An AI assistant is planned. Until it is genuinely useful we would rather point you at the page that actually answers your question.
An API is the contract between systems. It defines what can be asked for, what comes back, what happens when something goes wrong, and what guarantees hold under load. The code behind it is usually straightforward; the contract is what takes judgement.
The two dominant styles are REST, which models resources over HTTP verbs, and GraphQL, where clients specify exactly the shape of data they need. Both work well. The choice is driven by how many different clients you have and how varied their data needs are.
A poorly designed API becomes permanent. Once external teams have integrated, changing it means coordinated releases with people who have their own priorities. Design decisions that took an afternoon end up constraining the product for years.
Well-designed APIs also become a distribution channel. If integrating with you is straightforward, partners build on top of you, and their engineering effort becomes a barrier to them leaving. Difficult APIs get replaced at the first opportunity.
Our approach
We design the contract before implementing it. An OpenAPI or GraphQL schema written first can be reviewed, criticised and agreed while changes are still free. Consumers can also start building against a mock immediately, rather than waiting for the backend to be finished.
We version from the first release, even when there is only one consumer. Retrofitting versioning onto a live API means either breaking clients or maintaining an unversioned legacy path indefinitely. Starting with it costs almost nothing.
We treat errors as part of the interface. Consistent error shapes, meaningful status codes and actionable messages are what separate an API that is pleasant to integrate from one that requires reverse engineering. This is specified, not left to whatever the framework happens to return.
Capabilities
Resource modelling, consistent conventions and an OpenAPI specification that stays in step with the implementation.
Schema design, resolver efficiency and query cost limits so a single request cannot exhaust the database.
OAuth, API keys and JWT with scopes and permissions enforced server-side on every request.
Per-client limits with headers that tell consumers where they stand rather than failing opaquely.
Outbound events with signing, retries and replay, so consumers can trust delivery.
Generated reference plus written guides, because a schema dump alone is not documentation.
Stack
Process
Resources, operations and error shapes specified and reviewed before implementation begins.
A mock server so consumers can start integrating and raise problems while changes are still cheap.
Building against the agreed specification, with contract tests keeping the two aligned.
Rate limits, authentication, input validation and load testing against realistic traffic.
Reference material, integration guides and runnable examples in the languages consumers actually use.
Versioned release with latency, error rate and per-consumer usage visible from day one.
Use cases
One backend serving web, mobile and partner integrations without each needing bespoke endpoints.
Exposing functionality to external developers, where documentation and stability are the product.
Putting stable interfaces around parts of a large system so they can be changed independently.
A coherent interface over several internal systems, so consumers deal with one contract rather than five.
Choosing an approach
Both are good choices. The decision depends on how many clients you have and how much their data requirements differ.
| Style | Choose when | Trade-off |
|---|---|---|
| REST | Few clients with predictable needs; caching and simplicity matter | Clients often over-fetch, or need several requests to assemble a view |
| GraphQL | Many clients with varied data needs, especially mobile on slow networks | Query cost control and caching are meaningfully harder |
| Both | A public REST API for partners, GraphQL internally for your own apps | Two surfaces to maintain and keep consistent |
Outcomes
FAQ
Related