# API Contract Design

Turns the interactions an interface must support into a contract a consumer can build against — and adds no field that nobody described.

## Deliverable

One Markdown document, `api-contract.md`, in the structure set out under **Output** below. It takes the interfaces named in section 4 of `architecture-specification.md` and is the input to implementation and to the tests written against it.

## Required inputs

- **The interactions the interface must support** — what a consumer needs to do, stated as tasks. A list of endpoints taken from an existing system describes what was built, not what is needed.
- **The consumers** — who or what will call the interface, and what each one is permitted to see and to change.

If either is absent, stop and report it. A contract written without its consumers is a schema, and a schema is agreed with nobody.

## Optional inputs

- The data model the interface exposes, and the constraints already enforced on it
- The authentication and authorisation scheme in use across the surrounding systems
- Existing contracts in the same system, and the conventions they follow
- The expected call patterns: which operations are called together, which are called repeatedly
- The error taxonomy the consumers already handle
- Transport, encoding or protocol constraints stated by the requester

Where a convention was not supplied, the contract states the choice it made and records it as a decision to confirm, never as a house style it assumed. Where a limit or a bound was not supplied, the rule is written and the value is left `unknown`.

## Execution

**1 — List the interactions, not the endpoints.** One line per thing a consumer needs to do, in the consumer's words, with the consumer named against it. Endpoints are derived from this list. A list derived from endpoints reproduces whatever exists, including its mistakes.

**2 — Name the resources and their operations.** Group the interactions into the things the interface exposes, then the operations on each. An operation that belongs to no resource means a resource is missing: name the missing one rather than attaching the operation to the nearest resource that will hold it.

**3 — Specify requests and responses field by field.** For every field: name, type, required or optional, what it means, and what constrains it. A field the requester did not describe is not added. A field that looks necessary but was not described is raised as a question, because the answer changes who owns the data.

**4 — Write the error catalogue.** Every error a consumer can receive: the condition that raises it, whether the consumer may retry, and what the consumer is expected to do. An operation whose error conditions cannot be listed is not yet understood; record it as such rather than shipping a single generic failure.

**5 — Set authentication and authorisation per operation.** For each operation: what the caller must prove, what right is required, and what happens when the right is absent. An operation with no stated rule is recorded `authorisation unknown — required before implementation`. It is never defaulted to open, and never defaulted to closed.

**6 — Define the behaviour rules.** Idempotency per operation: safe to repeat, or what the caller must supply to make repetition safe. Pagination: how a page is requested, what bounds it, and what happens when the underlying set changes mid-traversal. Ordering, concurrency and rate limits are written only where the requester stated them.

**7 — Set versioning and deprecation.** What counts as a breaking change in this contract, how a breaking change is signalled, how a consumer learns that a version is ending, and how long a version is supported. Where the support period was not supplied, write `unknown` and name who must set it.

## Output

`api-contract.md`, in this order:

- **1. Input and date** — which interactions and which consumers this contract serves, who supplied them, and when
- **2. Consumers** — per consumer: what it calls the interface for, and what it is permitted to see and to change
- **3. Resources and operations** — per resource: what it represents, its operations, and the interaction each operation serves
- **4. Request and response schemas** — per operation: every field with its name, type, optionality, meaning and constraint
- **5. Error catalogue** — per error: the condition that raises it, whether it is retryable, and what the consumer must do
- **6. Authentication and authorisation** — per operation: what must be proven, what right is required, and what happens without it
- **7. Behaviour rules** — idempotency, pagination, ordering, concurrency, and rate limits where they were stated
- **8. Versioning and deprecation** — what counts as a breaking change, how it is signalled, and how a version ends
- **9. Open questions** — the question, what it blocks, who can answer it

## Validation

The contract is ready when all of these hold:

- Every interaction in the input reaches exactly one operation in section 3
- Every field in section 4 carries a type and states whether it is required
- Every error in section 5 names the condition that raises it and whether a retry is permitted
- Every operation in section 6 states a rule or carries the marker `authorisation unknown`
- No limit, bound or support period appears that the requester did not supply
- Section 9 is either non-empty or states explicitly that nothing is outstanding

Fail the run if a field appears that no input described, or if an operation is published with neither an authorisation rule nor the `unknown` marker.

## Failure handling

- **No interactions supplied** — stop. Report that there is nothing to contract, and that an interface designed from a data model alone serves the store rather than the caller.
- **No consumers named** — produce sections 1 and 3 to 9, mark section 2 `UNKNOWN CONSUMERS`, and state that section 6 cannot be settled until someone names who calls this.
- **Only an existing implementation is available** — describe what the implementation does, mark the whole document `AS-BUILT`, and list in section 9 every behaviour that appears deliberate but is unconfirmed. An as-built description is not an agreed contract.
- **Consumers want contradictory behaviour** — record both positions, name both consumers, and raise the conflict in section 9 as blocking. Do not satisfy both by making the difference an optional field.
- **Partial material** — specify the operations the material supports, mark the rest `INCOMPLETE — pending <question>`, and deliver.
