Give Way, Not Guesswork: Signposting Your API Like a British Junction
Photo: Godot13, CC BY-SA 4.0, via Wikimedia Commons
There's a stretch of road near me where two A-roads meet and the whole thing is handled by a roundabout so plain it's almost apologetic. No flyover, no lane gymnastics, just a circle with clear paint and a couple of signs you can read at 40mph. You approach it once and you never think about it again. That's the highest compliment you can pay a junction.
Now think about the last API you integrated against. Was it that roundabout, or was it the Magic Roundabout in Swindon — five mini-circles stacked on top of each other, technically legal, quietly terrifying, and entirely dependent on everyone else knowing the local custom?
Most API design advice dresses this up in acronyms. It doesn't need to. The questions are the same ones a highways engineer asks: can you see the exit before you commit to it, is the lane you're in the lane you need, and does anyone have to guess?
The approach lane is your documentation
Before a driver reaches a roundabout, they've already been told what's coming. Advance warning signs, a speed limit that steps down, road markings that start narrowing the choices. Nothing is sprung on them at the give-way line.
Your API's equivalent is the first ten minutes of a new integrator's experience. Can they find the base URL without hunting? Is there a sandbox where a GET returns something plausible rather than a 401? Does the quickstart produce a working request, or does it produce a working request once you've filed a support ticket to find out which header is mandatory?
If someone has to ask a human how to make their first call, the signage is facing the wrong way. Fix that before you touch anything else.
Name the lanes, not the tarmac
Endpoint naming is where teams quietly encode their internal org chart. You end up with /getCustomerInvoices_v2, /cust-inv, and /billing/legacy/lookup all doing roughly the same thing because three squads shipped at different times.
A roundabout works because every approach uses the same visual language. Do the same:
- Resources are nouns, plural, and hierarchical.
/customers/{id}/invoicestells you where you are and what you'll get./fetchInvoicesForCustomertells you the author once had a SOAP background. - Don't smuggle verbs into paths. The HTTP method is the verb. If your endpoint needs
action=approvein the query string, that's a design smell, not a feature. - Pick one casing and one separator for the whole surface. Mixed camelCase and snake_case in query parameters is the API equivalent of lane markings that change colour halfway around.
- Reserve abbreviations for things everyone already says out loud.
idis fine.custis not.
None of this is glamorous. It's paint on tarmac, and it's the reason the junction works.
Every exit should be visible before it's taken
Here's where most APIs lose people. The happy path is documented to death; the failure modes are folklore.
A driver approaching a roundabout can see, in advance, that the third exit is the one they want. An integrator hitting your API at 2am should be able to see, from the response alone, what went wrong and what to do next. That means:
- Use status codes honestly. A
200wrapping{"success": false}is a junction with the exit sign pointing at a hedge. - Return a structured error body with a stable machine-readable code, a human sentence, a link to the relevant doc page, and a request identifier you can actually grep for in logs.
- Say whether retrying helps. A
429with aRetry-Afterheader is a sign that says wait here, it'll clear. A bare503is a shrug. - Validate loudly and specifically.
"invalid request"costs someone an hour."field 'postcode' failed format check; expected a UK postcode"costs them thirty seconds.
Write the error states before you write the happy path. They're the exits people actually need.
No sudden merges: versioning with warning
Roundabout signage works because it arrives early. Nothing on a British junction tells you to turn left at the exact moment you need to turn left.
Versioning should behave the same way. Put the version in the path so it's unmissable, publish a changelog that a human wrote, and treat deprecation as a process rather than an event. That means deprecation headers on responses, a sunset date published months ahead, a named contact, and — crucially — a migration guide that isn't just a diff of the OpenAPI spec.
If your plan for a breaking change is to announce it in a Slack channel that half your integrators aren't in, you haven't signposted anything. You've just moved the roundabout overnight.
Consistency is the whole trick
Swindon's Magic Roundabout is only navigable because every mini-circle follows the same convention. Break that and it becomes a car park.
Pick your conventions once and apply them everywhere: pagination style, filtering syntax, sort parameters, timestamps in ISO 8601 with UTC offsets, money in minor units with an explicit currency, and a single pagination envelope shape across every collection. Document them in one place and link to that page from every endpoint. Consistency isn't a nice-to-have you get to once the roadmap clears — it's the load-bearing structure.
A checklist for before you ship
Print it, argue about it, then run it:
- Can a new integrator make a successful call in under five minutes using only the docs?
- Does every endpoint use the same naming, casing and pagination conventions?
- Does every error response carry a stable code, a useful message and a docs link?
- Are retry semantics documented per status code, with
Retry-Afterwhere relevant? - Is the API version visible in the path, and is deprecation a documented process with dates?
- Is there a sandbox, and does it return realistic data?
- Are idempotency expectations stated for anything that creates or moves money?
- Do the examples in the docs actually run, or were they hand-written once in 2021?
Knowing when to leave it be
Not every internal API needs this treatment. If two services in the same repo are talking over a private network and the same three people own both sides, a quick POST /do-thing is fine and the ceremony would be waste. The roundabout metaphor earns its keep at boundaries — public APIs, partner integrations, anything a team you've never met will call at an hour you'd rather be asleep.
At those boundaries, the goal is modest and worth stating plainly: nobody should have to circle your API twice to work out where they're going. Get the paint right and the junction disappears. Nobody thanks you for it. That's the point.