API Contract
Agent Prompt Snippet
Ensure the project has an API contract specifying endpoint schemas, request/response formats, authentication, versioning strategy, and error codes.Purpose
An API contract is the formal agreement between an API producer (the service that implements it) and its consumers (the clients that call it). It specifies what requests are valid, what responses will be returned, what errors mean, how authentication works, and how the API evolves over time without breaking clients. It is the single source of truth for everyone who needs to build against or maintain the API.
Without a contract, every consumer must reverse-engineer the API from the implementation or from ad hoc experimentation. This leads to fragile integrations that break when the implementation changes, misunderstandings about error semantics, and arguments about who broke what. A published contract shifts the relationship from “figure it out from the code” to “build against the spec; the spec is the product.”
An API contract is not the same as generated API documentation. Documentation explains how to use an API; a contract specifies what the API guarantees. The contract comes first—ideally before the implementation exists (contract-first design)—and the documentation is generated from it. OpenAPI 3.x, GraphQL SDL, AsyncAPI, and gRPC protobuf are all viable contract formats.
For teams building both the producer and consumer, a contract enforces discipline: it catches breaking changes before they reach production and makes it possible to work on producer and consumer simultaneously without constant coordination.
Who needs this document
| Persona | Why they need it | How they use it |
|---|---|---|
| Sam (Indie Dev) | Prevents breaking third-party integrations unintentionally; single reference for frontend/backend alignment | Writes OpenAPI spec before implementing endpoints; generates client SDK from spec |
| Claude Code (AI Agent) | Needs authoritative endpoint schemas to generate correct integration code | Reads contract before writing any code that calls or implements the API; validates generated code against schema |
| Priya (Eng Lead) | Manages API lifecycle across multiple teams; governs breaking vs. non-breaking change policy | Reviews contract in PRs; rejects implementation changes that violate the contract without a version bump |
| DevOps (CI Operator) | Validates deployed API against contract in CI; catches schema drift before production | Runs contract compliance tests in CI pipeline using tools like Dredd or Schemathesis |
What separates a good version from a bad one
Criterion 1: Every field is typed, required/optional status is explicit
✓ Strong: “
user_id(string, UUID v4, required): Unique identifier for the user. Immutable after creation.display_name(string, 1–64 chars, optional): User-visible name. Defaults to email prefix if omitted.created_at(string, ISO 8601 UTC, required): Creation timestamp. Always present in responses, never accepted in requests.”
✗ Weak: “
user_id: user ID.display_name: display name.created_at: timestamp.” (No types, no constraints, no required/optional distinction, no read-vs-write semantics.)
Criterion 2: Error responses are enumerated with actionable semantics
✓ Strong: “
422 Unprocessable Entity: Request body is syntactically valid JSON but fails validation. Body:{"error": "validation_error", "field": "email", "message": "Invalid email format"}. Thefieldproperty identifies which input field failed. Clients must display field-specific error to users.”
✗ Weak: “Errors return HTTP error codes.” (No error schema, no enumeration of which errors are possible, no guidance on how clients should handle them.)
Criterion 3: Versioning strategy is explicit
✓ Strong: “This API uses URI path versioning:
/v1/,/v2/. A breaking change (field removal, type change, authentication change) requires a new major version. Minor additions (new optional fields, new endpoints) are non-breaking and do not bump the version. v1 will receive security patches for 18 months after v2 GA.”
✗ Weak: “API versioning will be handled as needed.” (No policy means every consumer carries risk of silent breakage on every deployment.)
Criterion 4: Authentication and authorization are specified per endpoint
✓ Strong: “All
/v1/admin/*endpoints requireAuthorization: Bearer <token>with theadminscope.GET /v1/public/statusrequires no authentication.POST /v1/webhooksrequires HMAC-SHA256 signature verification using theX-Webhook-Signatureheader.”
✗ Weak: “API requires authentication.” (Which endpoints? Which scheme? Which scopes? Unanswered questions become security bugs.)
Common mistakes
Contract-last development. Writing the contract after implementing the API produces a description of the implementation, not a guarantee. The contract’s value is that it can be reviewed and agreed upon before a line of implementation code is written. Without contract-first discipline, breaking changes get discovered in production.
Marking everything as required. When developers are unsure whether a field will always be present, they often mark it required “to be safe.” This creates brittle consumers that break when optional fields are occasionally absent. Document actual nullability in production—if it can be absent, mark it optional.
Omitting rate limits from the contract. Rate limits are part of the API’s observable behavior. Consumers who don’t know about rate limits cannot implement backoff correctly. Include rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) and the status code for limit violations (429) in the contract.
Not specifying idempotency. Which endpoints are idempotent? Which support Idempotency-Key headers? Consumers building retry logic need this information. Omitting it leads to duplicate mutations during retries.
How to use this document
When to create it
Write the contract at the beginning of API design, before implementation. For new endpoints on an existing API, write the contract change in the same PR as the feature request, before the implementation PR. The contract review is the design review.
Who owns it
The team or engineer responsible for the API service owns the contract. External teams building consumers are stakeholders who must approve breaking changes. The contract is stored in the service repository and versioned alongside the code.
How AI agents should reference it
get_standard_docs(type="web_app", features=[])
→ api_contract in documents[]
→ agent reads the contract before writing any code that calls an API endpoint
→ agent validates generated request payloads against the schema
→ agent flags if a suggested implementation change would violate the contract
→ agent checks versioning policy before proposing field removals or type changes
The prompt_snippet — “Ensure the project has an API contract specifying endpoint schemas, request/response formats, authentication, versioning strategy, and error codes” — tells the agent to verify all five dimensions are covered.
How it connects to other documents
The API Contract is constrained by the API Design Guide (house style for naming, versioning, error formats) and feeds the Rate Limit & Error Specification (per-endpoint rate limit policy) and Authentication Design (auth scheme details). The SLA definition’s latency and uptime targets apply to the endpoints enumerated in the contract. The Technical Design Document’s implementation choices must stay within the contract’s guarantees.
Recommended Reading
- The Design of Web APIs by Arnaud Lauret — Practical guide to API design with strong coverage of contract-first thinking.
- RESTful Web API Patterns and Practices Cookbook by Mike Amundsen — Patterns for versioning, error handling, and evolving APIs safely.
- OpenAPI Specification (spec.openapis.org) — The industry-standard format for REST API contracts; understanding the spec is prerequisite for writing high-quality contracts.