API design decisions that age well are mostly about change, not naming. Design for callers you cannot contact: add fields rather than repurpose them, return errors a caller can act on, choose pagination before the collection grows, keep your database shape out of the response, and version rarely and deliberately.
Design for the caller you cannot contact
Early on, every consumer is known and a breaking change is a conversation. That stops being true quickly. Once callers include another region, a partner or a mobile version still in use, the interface has to change in ways that do not require coordination.
Practically: add rather than repurpose, make new fields optional, never change the meaning of an existing one, and treat removal as a scheduled process with notice rather than a release note.
Return errors a caller can act on
An error that says only that something failed forces every consumer to guess. A useful error distinguishes what the caller can fix from what they cannot, says whether retrying is sensible, and identifies the specific input at fault.
Include an identifier that also appears in your logs. It converts a vague report into a single lookup, and it is close to free to implement.
Decide pagination before you need it
Endpoints that return everything work until a collection grows, and by then callers depend on receiving the whole list. Retrofitting pagination is a breaking change dressed as an improvement.
Choose the approach at the start. Cursor-based paging is more robust than offsets when records are being inserted while a caller reads, which is the normal case.
Do not leak the database
An interface shaped exactly like your tables couples every consumer to your storage decisions. The first schema change then becomes a negotiation with every team that integrated.
Shape responses around what callers need. The translation costs a little and it buys the freedom to change what sits behind the interface without asking permission.
Version deliberately, and rarely
Versioning is a tool for the changes that genuinely cannot be made compatibly, not a routine step. Every live version is one you maintain, test and support.
Before adding one, check whether the change can be additive instead. Most can, and the ones that cannot are usually a sign that something upstream in the design deserves another look.
