Skip to content

API contracts written before code

Between services, the API contract is what the brief becomes. The story says Uri sees a clean reconciliation report on the morning after the billing cycle. The contract is what that means in machine-checkable terms.

text
POST  /v1/billing/cycles/:cycle_id/charges

Request body
  { subscription_id, idempotency_key, amount, currency }

Success
  201 Created · { charge_attempt_id, status: "succeeded", cardcom_reference }

Known failures
  409 · idempotency_key already used — returns original attempt
  422 · { failure_category: "stale_plan_ref" | "card_expired" | ... }
  503 · cardcom rate-limited — retry safe with same key

Guarantees
  Idempotent on idempotency_key. No charge silently dropped —
  every request resolves to a charge_attempt row.

The Guarantees section is the most important part — it is where the brief's intent enters the contract. No charge is silently dropped. That sentence is the technical translation of "Uri does not have to manually reconcile." If the contract does not enforce it, no amount of code will satisfy the brief.

The contract is written before the code. It belongs in the same review that decides the story is ready. Writing it after — letting it emerge from whatever the code happens to return — is one of the most common substitution failures in technical work.

Next — The ADR →

200apps · How We Work · NWIRE