API Spec Template
Use this structure to make API contracts testable, reviewable, and stable for client/server teams. The notes below help you avoid hidden breaking changes.
# API Spec Template (OpenAPI mindset) ## Endpoint - Method: GET/POST/PUT/DELETE - Path: /v1/... - Owner: ... ## Request - Headers: - Query: - Body schema: - field: type / required / default / constraints - Example request: ## Response - Success (2xx): - schema: - example: - Error (4xx/5xx): - code: string - message: string - traceId: string - example: ## Compatibility - Backward compatibility notes: - Deprecation strategy: ## Test Checklist - [ ] happy path - [ ] validation errors - [ ] auth/permission - [ ] timeout/retry/idempotency
Template usage path
- Copy the contract sections before endpoint implementation starts.
- Fill request, response, error, compatibility, idempotency, and release checks.
- Attach one success example and at least two non-happy-path examples.
- Mirror stable schema details into OpenAPI once behavior is reviewed.
What a review-ready API spec looks like
A template becomes useful only after it carries a real decision, owner, and evidence. Use the blank template above for structure, then aim for this level of specificity before implementation starts.
Endpoint: POST /refunds Consumer: support console Compatibility: additive response field Review evidence: - old client ignores refund_status - duplicate idempotency key returns same refund_id - contract test covers ORDER_NOT_REFUNDABLE
If the copied template still has empty owner, evidence, or rollback fields, keep it in review.
What this template protects
- Consumer breakage from undocumented schema changes.
- Inconsistent error shapes across endpoints.
- Retry bugs on write endpoints without idempotency rules.
- Release surprises caused by unclear compatibility policy.
How to fill key sections
The Request section should specify field type, required flag, constraints, and defaults. The Response section should include the exact success schema and standardized error envelope. The Compatibility section clarifies what can change in place versus what needs versioning. The Test Checklist should cover success, validation, auth, conflict, timeout, and retry paths.
Documenting these upfront is usually faster than reverse-engineering contract intent after bugs appear.
Common contract anti-patterns
- Renaming/removing response fields in the same API version.
- Returning different error formats by endpoint owner preference.
- Relying on undocumented default sort order in list APIs.
- Treating retries as infrastructure-only concerns.
Release gate checklist
- Contract tests run in CI and include non-happy paths.
- Breaking changes are versioned and announced.
- Monitoring can detect response code/schema anomalies.
- Rollback preserves previous consumer behavior.
Related guides: API contract checklist and Given/When/Then template.
Weak vs strong API contract
Weak contract
POST /payments creates a payment and returns an error if something fails. This leaves retry behavior, duplicate requests, pending payment states, and stable error codes undefined.
Strong contract
POST /payments requires Idempotency-Key. Duplicate keys within 24 hours return the original result. Processing payments return 202 with status: "processing". Card declines return stable code PAYMENT_DECLINED.
The strong version gives frontend, backend, QA, support, and generated clients the same behavior to build against.
How to use this template in review
- Product review: confirm the endpoint maps to a real user or partner workflow, not just an internal implementation idea.
- Engineering review: check schema shape, idempotency, authorization, pagination, rate limits, and compatibility rules.
- QA review: turn each response and error into a test case before implementation starts.
- Operations review: verify logs, metrics, trace IDs, and rollback behavior are visible enough to debug production failures.
Using the spec with AI coding tools
Paste the API spec into your coding assistant with explicit constraints: do not add undocumented fields, do not invent error codes, do not change response names, and include tests for each checklist item. A well-written API spec is a boundary for generation, not just background context.
Ask the assistant to produce a diff summary that maps every implemented behavior back to the spec. If it cannot point to a section, that behavior should be removed or the spec should be updated before merge.
API template FAQ
Is OpenAPI enough by itself?
OpenAPI is excellent for schema and client generation, but many decisions live outside schema: idempotency, rollout timing, deprecation, partial failure, support workflows, and monitoring. Keep those decisions in the spec and mirror the stable parts into OpenAPI.
How specific should error codes be?
Specific enough for clients to choose behavior. A support-only diagnostic code can be detailed, but the public error contract should remain stable, documented, and small enough for client teams to handle deliberately.
What to attach before handoff
Before a client team implements against the contract, attach one successful request, one validation failure, one authorization failure, and one retry or duplicate request example. These examples should use the exact headers, status codes, and response fields expected in production. If the endpoint is partner-facing, include rate-limit behavior and deprecation notice expectations as well.
The handoff is ready when a consumer can write contract tests from the spec without asking which fields are stable, which errors are recoverable, or whether a retry is safe.
Real-world example: payment refund endpoint
## Endpoint POST /v1/payments/:paymentId/refund ## Request | Field | Type | Required | Constraints | |-------------|--------|----------|------------------------| | amount | number | yes | > 0, ≤ original amount | | reason | string | yes | max 500 chars | | idempotencyKey | string | yes | UUID v4, unique per refund | ## Response - Success (200): - refundId: string (UUID) - status: "pending" | "completed" - amount: number - createdAt: ISO 8601 - Error (409 — duplicate idempotency key): - code: "REFUND_ALREADY_PROCESSED" - message: "A refund with this idempotency key already exists" - traceId: string - existingRefundId: string - Error (422 — exceeds original): - code: "REFUND_EXCEEDS_PAYMENT" - message: "Refund amount exceeds original payment" - traceId: string ## Compatibility - This is v1; field additions are non-breaking - Removing `reason` field would require v2 ## Test Checklist - [x] happy path: full and partial refund - [x] validation: amount > original, missing fields - [x] idempotency: duplicate key returns 409 with original refund - [x] auth: only payment owner or admin can refund - [x] timeout: refund request times out → status check via GET
Review ownership before implementation
Before implementation starts, assign one owner for the API contract and at least one reviewer from a consuming team. The contract owner checks naming, versioning, compatibility, and rollout timing; the consumer reviewer checks whether the examples are enough to build against without private clarification.
For partner-facing or AI-agent-facing APIs, also record the rate-limit policy, retry window, permission boundary, and support escalation path. These details often sit outside OpenAPI, but they decide whether integration failures are recoverable.
Editorial note
This template covers API specification for spec-first engineering teams. The refund endpoint example is an illustrative scenario.
- Author: Daniel Marsh
- Editorial policy: How we review and update content
- Corrections: Contact the editor
Tip: pair this with contract tests in CI and keep examples synchronized with real API fixtures. Last updated: May 6, 2026.
Fill a form, get Markdown — ready for your repo.