API Contract Design Checklist: What to Verify Before You Ship
A pre-ship checklist for REST API contract design covering naming, error shapes, versioning, pagination, security headers, and documentation completeness.
An API contract is a promise. Once clients depend on it, every field name, status code, and error shape becomes a migration cost to change. The best time to catch design problems is before the first consumer exists — which means before you ship.
This checklist is organized by the categories that most commonly generate breaking changes, client confusion, or production incidents after the fact.
API Contract Design Checklist
Work through each section before marking an API as ready for consumers.
Resource and Endpoint Naming
- All resource names are plural nouns (
/users,/orders,/invoices) - No verbs in URL paths — actions are expressed through HTTP methods
- Nested resources reflect genuine ownership, not just relation (
/users/42/addressesis fine;/users/42/global-settingsshould probably be its own root resource) - No trailing slashes (or consistent trailing slashes if your framework requires them)
- All URL segments are lowercase and use hyphens, not underscores or camelCase
- Field names in request and response bodies follow a single consistent convention — snake_case or camelCase, documented and applied uniformly
HTTP Methods and Semantics
GETrequests have no side effects and are safe to retryPUTandDELETEare idempotent — calling them twice produces the same state as calling them oncePOSTis used only for non-idempotent creation;PUTorPATCHfor updatesPATCHis used for partial updates where appropriate, with clear documentation of which fields are patchable- For operations where idempotency is critical (payments, order submission), an
Idempotency-Keyheader is accepted and honored
HTTP Status Codes
- Success cases return
200,201, or204correctly —201includes aLocationheader pointing to the created resource - Client errors return
4xx, not200with an error body - Validation failures return
400or422, not500 - Authentication failures return
401; authorization failures return403 - Rate limit responses return
429with aRetry-Afterheader - All error responses have the same shape — consistent
code,message, and optionalfieldkeys
Error Response Shape
- Every error response includes a machine-readable
codestring, not just a human-readablemessage - Validation errors identify which field or parameter caused the failure
- Error codes are documented alongside their HTTP status mappings
- Error messages are actionable — they tell the caller what to do, not just what went wrong
Versioning
- The API includes a version in the URL path (
/v1/) or a documented version header - The version is present from the first public release, even if it is the only version today
- A deprecation policy is documented: how much notice consumers will receive before a breaking change
Request and Response Contracts
- All response fields are documented with their type, nullability, and allowed values
- Optional fields in requests are explicitly labeled as optional with documented defaults
- No response field is ever
nullsometimes and absent other times — pick one and be consistent - Dates and timestamps are ISO 8601 in UTC everywhere — no Unix epoch integers, no ambiguous date strings
- Monetary values are integers (cents/pence) or strings with explicit decimal precision — never floats
- Boolean fields do not use numeric proxies (
0/1) in JSON responses
Pagination
- Every collection endpoint has pagination — no endpoint returns unbounded results
- Default page size and maximum page size are documented
- Pagination metadata is returned in the response body, not only in
Linkheaders - Behavior at the last page is defined —
has_more: falseor an absentnext_cursor
Authentication and Security Headers
- All endpoints that require authentication return
401when credentials are missing, not404or403 - The authentication scheme is documented — Bearer token, API key header, OAuth scopes
- Rate limiting is applied and the limits are documented
Content-Type: application/jsonis required on request bodies and enforced — a missing content type returns a clear error- CORS policy is intentional, not left at the framework default
OpenAPI Specification
- Every endpoint has a
summaryanddescriptionin the spec - Every request parameter and response field has a description
- Request and response examples are included for the happy path and at least one error case
- The spec is generated from or validated against the actual implementation — they should not drift
Backward Compatibility Verification
- Adding new optional fields to responses is the only change made since the last version
- No existing field has been renamed, removed, or had its type changed without cutting a new version
- Removing an endpoint is preceded by a deprecation period with a
DeprecationandSunsetheader on that endpoint
How to Use This List
Run through it at two points: once during design review, before any implementation begins, and once before opening the API to its first consumer. Design-time catches are free. Post-ship catches cost you migrations.
If you are working through this list and finding that your current API fails several of these checks, the pragmatic move is to cut a new version with the corrections rather than silently fix the live version and hope no clients depended on the broken behavior.
For teams that want an expert pair of eyes on an API design before it ships, or need a backend built with these contracts enforced from day one, Clixo can help.