Everything must be made as simple as possible, but no simpler.
How often have we heard the phrase, KISS - Keep It Simple, Stupid? It’s something to keep in mind, and if you don’t think that applies to you then it applies doubly to you.
Keeping things simple does not necessarily imply keeping things trivial - a little design will go along way to building a service that appears far simpler than its usefulness would imply, which should be our goal. In the real world we get points for outcomes, not for complexity, even if it doesn’t feel that way at the time.
One habit to work on is using the discipline to create a properly stateless system. By that I mean stateless business logic; state is highly useful on the front-end and basically a requirement of your storage layer.
If you have a nice clean stateless API will be able to get awful lot of mileage out of it if, however you let a little bit of state creep in, you may have made whatever problem you were trying to solve slightly easier at that time at the cost of locking yourself into an approach that is likely not the best moving forward. By having your willingness to keep things clean and simple, and sticking to that discipline, the API would you do today will feed the products of tomorrow without needing a lot of redesign.
As an aside, your API should absolutely have a product owner to advocate for it. If you don’t have one designated, figure out who’s most passionate about keeping it clean and give them the extra work officially!
Keeping stateless discipline allows you to make clean services that support your operation, but then expects custom server-side code to be implemented whenever your API consumer needs change to make it easy on them. To be clear, this approach works really well when you're client account is now numbered in the billions-like Facebook. However it's be used way too often I people's simultaneous client account numbers and the tenants, sacrificing for future flexibility for a trivial temporary performance boost. Remember the old saying: premature optimization is the root of all evil.
When you're just beginning to build product, you should keep in mind a realization and in admittance of just how much you don't know is there a mobile app in your future? Probably. How about your front-end, is your website look and feel going to change? Almost certainly. With a decent set of reasonably scoped APIs, we can handle those future changes without needing any expensive refactoring and that is huge. If certain future layouts do who've to be poorly handled with generic APIs, we can always add optimization later, but these should be in addition to instead of in place off your generic simple systems. And as previously mentioned, no matter how tempting it is, your application service should continue to reject state at all times.
If you'd rather have some real numbers for consideration, a single Heroku dyno can often handle 20 or more simultaneous API calls. That may seem low, but if your database and services are reasonably straightforward, this can easily translate into well over 1000 calls per minute. When you consider that adding an additional dyno costs approximately $25 per month, and every backend service can easily cost several thousand dollars in development and testing time, the benefits of keeping things generic and scalable should not be underestimated.