Architecture 7 min read

Designing APIs that stay maintainable after year three

Versioning, contracts, and ownership patterns that keep integrations from becoming a second product.

Technical deep dive

Most API pain does not come from the first release. It comes from the third year — when three clients depend on undocumented quirks, two teams “own” the same resource, and every change feels risky.

Start with clear resource boundaries

Model the business capabilities, not the current database tables. If a client must call four endpoints to complete one user journey, the boundary is wrong. Prefer a small number of stable resources with intentional expansion points.

  • Name resources after business nouns users recognise.
  • Keep write paths narrow; allow read models to be richer.
  • Document breaking vs additive changes before you ship.

Contracts beat folklore

Publish OpenAPI (or equivalent) as part of CI. Treat the contract as a product artifact: review it in PRs, generate clients where useful, and fail builds when responses diverge from the schema.

If the only source of truth is a senior engineer’s memory, you do not have an API strategy — you have a bus factor.

Version deliberately

Not every change needs a new major version. Additive fields, optional filters, and new endpoints are usually safe. Breaking renames and stricter validation should be versioned or gated behind feature flags with a deprecation window.

Operational ownership

Every public endpoint needs an owner, SLOs, and a path for support. Logs, correlation IDs, and rate limits are not “later” work — they are part of the first production release.

Good APIs feel boring to integrate. That boredom is the product of deliberate design.