Skip to content

API Contract Design

Verb, path, request, response, errors, guarantees. The contract is what the trio agrees on before code. Drift between contract and implementation is the most common source of adr-drift bugs.

Owners: Tech Lead, Developer Phase it lives in: What We Build (Volume III) The corpus principle this enacts: The artefacts the chain produces survive the conversation.

Where it lives in the chain

How to do this

A contract names six things:

  1. Verb + pathPOST /exams/:id/grade. Resource-oriented, domain-named.
  2. Request shape — typed schema. Required vs optional. Field semantics, not just types.
  3. Response shape — same. Including pagination, partial-success, empty-collection shapes.
  4. Error responses — typed and named. GradingDeadlinePassed, ExamAlreadyGraded — not 400 Bad Request.
  5. Guarantees — idempotency, ordering, at-least-once vs exactly-once, retry safety.
  6. SLA — p50 / p95 latency, availability target. The promise to downstream callers.

What good practice looks like

The contract is written in OpenAPI (REST), GraphQL SDL (GraphQL), or Avro/protobuf (events) — and lives in source control, not in a Notion page. A contract that lives in Notion is a contract nobody runs in CI. The trio reads the contract together at the amigos session; the developer implements against it; the consumer's CI runs against the same file. When the contract changes, the PR changes the file — and every consumer's CI catches the drift before any code ships.

The discipline: the contract is the spec, not the code. If the code returns something the contract didn't promise, the code is wrong. If the code returns something the contract promised but a consumer doesn't expect, the consumer is wrong. Without the contract as third party, every disagreement is litigation.

200apps · How We Work · NWIRE