| Dave Clissold | 7 min read

How to Plan an API Design and Get It Reviewed

How to plan an API design: the order to make the decisions in, which parts of it become permanent, and who should review the design before you ship it.

Plan an API design by naming its consumers and their real use cases first, then modelling the resources, the write behaviour and the error contract, and only then deciding how you will version it. Get the plan reviewed while it is still a draft. Once a client depends on the shape, the shape is a commitment.

This is for engineers designing a new HTTP or RPC interface that other teams will call.

How to plan an API design

Work in the order that decisions constrain each other: consumers first, shape second, failure behaviour third, versioning policy last. Doing it the other way round produces a tidy resource model that nobody can build against.

  1. Name the consumers and what each is trying to do. Not “the mobile app” but the three calls the mobile app makes on its home screen. An endpoint with no named caller is speculative work.
  2. Sketch real requests and responses before schemas. Write actual JSON for two or three use cases. An abstract resource model survives a meeting unchallenged; a concrete payload gets argued with, which is the point.
  3. Decide identity and collection semantics. What is a resource and what is a field on one, which identifier clients will store, and how collections filter, sort and paginate. Retrofitting cursor pagination onto an endpoint that returned an unbounded array breaks every caller.
  4. Work out write behaviour. Idempotency keys for retries, concurrency control for conflicting updates, and whether a partial failure leaves the caller able to tell what happened.
  5. Design the error contract. Status codes, a stable machine-readable error code, which errors are worth retrying, and what the client should do about each. Reviews that only walk the success path miss most of the integration cost.
  6. Fix the authorisation model, rate limits and quotas. Who may call this, at what volume, and what a rejected call looks like.
  7. Write the compatibility rules down. What your team counts as a breaking change, how new fields get added, how long a deprecated field survives, and whether you version by URL, by header or not at all.
  8. List the open questions, each with an owner and a date. A plan that admits what it has not decided attracts better comments than one that quietly guesses.

Steps one and two carry most of the value and are the two most often skipped, because both require talking to people outside the team that owns the service.

Which parts of the design become permanent

Anything a client can observe becomes something a client depends on, including behaviour you never documented and did not mean to promise: field ordering, the exact error string, the fact that a list happens to come back newest first. Hyrum’s law is the usual name for this, and it is why the review has to happen before the first integration.

Treat all of these as commitments from the moment a caller ships:

  • Field names, types and nullability
  • Enum values, and whether clients reject ones they do not recognise
  • Pagination shape and default page size
  • Error codes that clients branch on
  • Ordering, timing and retry behaviour that clients infer, documented or not

You are not only choosing an interface. You are choosing which of your current mistakes you will keep supporting for years. That is the argument for a week on the design and a day on the first implementation, and for recording the alternatives you rejected in an ADR while the reasoning is fresh.

Who should review an API design?

The teams that will call it, whoever owns the platform’s conventions, and security if the endpoint exposes data or actions that need authorisation. Everyone else can read it. A review with nine attendees produces consensus about naming and silence about failure modes.

ReviewerWhat only they will catchBring them in
Consuming teamsWhether the response matches what their screen or job needs, and how many calls a common task takesAt the request and response sketches
Platform or API ownerInconsistency with existing endpoints: naming, pagination, error format, authBefore the schema is written up
SecurityAuthorisation gaps, what list responses and error messages leak, missing rate limitsBefore the auth model is fixed
Service on-callTimeouts, retry storms, behaviour under load, which failures page a humanWith the error contract
Docs or developer experienceWhether the interface can be explained without a page of exceptionsOnce the design is stable but unshipped

Reviewing is not voting. One person owns the design and decides; the reviewers exist to raise what the owner cannot see from inside the service. Where the API crosses team boundaries or sets a precedent others will copy, the RFC process is the right vehicle, because it forces objections into writing before anyone gets attached.

When to send it for review

Send it when you have request and response examples plus a list of open questions, and before you have a finished OpenAPI file. The useful test: if a reviewer’s suggestion would irritate you because of how much work the change implies, you sent it too late.

Two passes are usually enough. A shape review on the sketches, asynchronous, three working days for comments. Then a contract review on the full spec whose only agenda item is what went unresolved in the first pass. Running that second pass as a short meeting rather than another comment thread helps when there is real disagreement and wastes everyone’s morning when there is not.

The hard part is getting consuming teams to answer before the spec exists rather than after it ships. Projan runs that round in Slack, asking each team which fields they will read and what they will do on a 409, then writing the replies up as a draft and pushing unresolved items to GitHub or Linear as tasks.

Frequently asked questions

What counts as a breaking change to an API? Anything that can make a working client stop working: removing or renaming a field, tightening validation, changing a status code, adding a required request parameter, or changing what an existing value means. Adding an optional response field is usually safe, though not for clients that reject unknown fields. Write your own list down, because teams disagree about the edges.

Do internal APIs need a design review? Yes, and usually a shorter one. The consumers are known and reachable, so it can be a half-hour conversation with the two teams that will call it rather than a public process. The cost of a bad internal API is lower per change and higher in total, because nobody budgets time to fix it.

Who decides when reviewers disagree? The person accountable for the service decides, once the disagreement has been written down rather than argued in a call. If two teams cannot agree on the contract, escalate to whoever owns both and record what was chosen and what was rejected. Unresolved design disagreements reappear as workarounds in client code.

How do you design an API with no consumers yet? Design the smallest thing your first known caller needs and ship it as unstable, with the instability stated in the docs. Speculative generality is how APIs acquire fields nobody reads and options nobody sets. If you genuinely cannot name a caller, the honest answer is that the design can wait.

API designs fail review for the same reason they fail in production: nobody asked the people who would call the thing what they needed until the shape was fixed. Sketch the payloads early, publish what you have not decided, and treat everything observable as a promise.

Frequently asked questions

What counts as a breaking change to an API?

Anything that can make a working client stop working: removing or renaming a field, tightening validation, changing a status code, adding a required request parameter, or changing what an existing value means. Adding an optional response field is usually safe, though not for clients that reject unknown fields. Write your own list down, because teams disagree about the edges.

Do internal APIs need a design review?

Yes, and usually a shorter one. The consumers are known and reachable, so it can be a half-hour conversation with the two teams that will call it rather than a public process. The cost of a bad internal API is lower per change and higher in total, because nobody budgets time to fix it.

Who decides when reviewers disagree?

The person accountable for the service decides, once the disagreement has been written down rather than argued in a call. If two teams cannot agree on the contract, escalate to whoever owns both and record what was chosen and what was rejected. Unresolved design disagreements reappear as workarounds in client code.

How do you design an API with no consumers yet?

Design the smallest thing your first known caller needs and ship it as unstable, with the instability stated in the docs. Speculative generality is how APIs acquire fields nobody reads and options nobody sets. If you genuinely cannot name a caller, the honest answer is that the design can wait.

Dave Clissold

Dave Clissold

Things are made better when we collaborate

linkedin.com/in/daveclissold
Share this article

Better thinking. Better plans.

Projan joins the conversation, asks what nobody thought of, and turns it into a plan your tools can action.

Start free trial

14-day free trial. No credit card required.