Well-designed APIs: contracts before code
Designing an API means writing a contract between teams, products and companies. Code can be rewritten; a contract, once published and integrated, changes at a cost and requires negotiation. That's why it's worth investing time in the format before investing time in the implementation.
Start from the consumer, not from the database
An API that mirrors tables forces every client to rebuild the business rule on its own. An API that exposes meaningful domain operations reduces coupling and prevents the same logic from being reimplemented in five different places.
A simple exercise helps: write the call and response example you'd like to read in the documentation first. If the example is confusing, the design isn't ready yet.
- Stable, predictable names, consistent in language across the whole surface.
- Errors with a code, a readable message and a correlation identifier.
- Pagination, sorting and filters defined from the first version.
Errors and idempotency are part of the product
Networks fail, clients retry, timeouts happen. Write operations need an idempotency key so a retry doesn't produce two charges or two orders. That detail prevents most integration incidents.
Error responses deserve the same care as success responses: predictable, documented and free of leaked internal information.
Versioning means planning for change
Adding a field is safe; removing one or changing its meaning is not. When a breaking change is unavoidable, publish a new version, keep the previous one for an announced period, and offer a migration path. A written deprecation policy is worth more than any verbal promise.
Living documentation and explicit limits
A specification generated from the code, executable examples and a test environment drastically reduce integration cost. Usage limits, quotas and authentication rules should be on the first page, not in a footnote.
In short
A good API is one someone can integrate without opening a support ticket: clear contract, predictable errors, idempotency and a published versioning policy.
Use cases
Integration with a client's ERP
Stable contract, per-partner key and safe reprocessing of duplicate events.
Webhook for external systems
Verified signature, retries with progressive backoff and logging of every attempt.
Mobile app
Lean responses, tolerant versioning and compatibility with older versions still installed.
Common mistakes
- Exposing the database model directly in the response.
- Returning success with an error message inside the body.
- Breaking a contract with no warning and no new version.
- Documenting only the happy path.
Best practices
- Contract defined and reviewed before implementation.
- Idempotency key on every relevant write operation.
- Clear usage limits and authentication rules per consumer.
- Contract tests run in the pipeline.
Recommended books
Building Microservices — Sam Newman
Covers integration, contracts and service boundaries with a practical focus.
Domain-Driven Design — Eric Evans
Grounds how to expose domain operations instead of internal structures.
Release It! — Michael Nygard
Shows resilience patterns essential for real-world integration.
Go deeper
Frequently asked questions
- REST or GraphQL?
- It depends on consumption. REST tends to be simpler to operate and cache; GraphQL helps when very different clients need different slices of the same data.
- When should I create version 2?
- When a change breaks existing clients. Adding an optional field usually doesn't require a new version.
- What is idempotency?
- The guarantee that repeating the same call produces the same effect, avoiding duplication in case of a network failure.
- How do I document without it becoming endless manual work?
- By generating the specification from the code and validating examples in the pipeline, so the documentation doesn't drift from reality.
References
- Roy Fielding — the dissertation that originated the REST style
- OpenAPI Specification
- Sam Newman — contracts and coupling between services
Original content by the i9 Conecty team. Classic concepts are explained in our own words and credited to their authors.