Why this matters
API First Design means you design and agree on the API contract before writing backend code. This reduces rework, speeds up parallel development, and improves consistency across services.
- Real tasks you will do: define endpoints and schemas, write an API spec, review changes, generate mocks, and implement against the agreed contract.
- Benefits: fewer breaking changes, faster front-end and integration work, easier documentation and testing.
Concept explained simply
Think of the API contract like architectural drawings for a house. Everyone (clients, backend, QA, partners) agrees on the blueprint first. Then builders implement exactly what the blueprint says.
- Contract-first: describe requests, responses, errors, security, and versioning in a spec before coding.
- Mock-first: use the spec to mock endpoints, letting clients start integration early.
- Generate-then-implement: generate docs, tests, and stubs from the spec to keep code and docs aligned.
Mental model: the blueprint loop
- Model domain resources (nouns) and actions (verbs).
- Draft the spec (paths, payloads, status codes, errors).
- Review with stakeholders; iterate until clear and consistent.
- Mock endpoints and validate flows.
- Generate docs/clients/servers as needed.
- Implement and test against the contract.
Core building blocks
- Resources and actions: use clear nouns (e.g., tickets) and HTTP verbs (GET, POST, PATCH, DELETE).
- Data models: define schemas (types, required fields, enums, formats like uuid, date-time).
- Status codes: map success and failure paths (201 for create, 200 for fetch, 202 for async, 400/401/403/404/409/422/429/500 as needed).
- Error model: consistent structure (e.g., type, title, detail, code, field).
- Pagination: cursor-based or page/limit; include next/prev indicators.
- Filtering/sorting: predictable query params; validate and document.
- Idempotency: safe retries for POST/PUT with an idempotency key header.
- Security: describe auth (e.g., bearer tokens), scopes/roles, and error responses.
- Versioning: prefer additive changes; use v1, v2; deprecate with warnings and timelines.
- Lifecycle: propose, review, approve, implement, release, deprecate, sunset.
Worked examples
Example 1: Create a support ticket (contract-first)
Goal: POST /v1/tickets creates a ticket and returns it. Use idempotency to avoid duplicates.
POST /v1/tickets
Headers:
Authorization: Bearer <token>
Idempotency-Key: uuid-v4
Request (application/json):
{
"subject": "Login issue",
"description": "Cannot reset password",
"priority": "high", // enum: low|medium|high
"customerId": "c_123"
}
Responses:
201 Created (application/json):
{
"id": "t_101",
"subject": "Login issue",
"priority": "high",
"status": "open", // enum: open|in_progress|resolved
"createdAt": "2024-06-01T10:00:00Z"
}
401 Unauthorized, 409 Conflict (duplicate key), 422 Validation error
Error (application/problem+json):
{
"type": "https://example.com/problems/validation",
"title": "Invalid request",
"detail": "priority must be one of: low, medium, high",
"code": "VALIDATION_ERROR",
"field": "priority"
}
Example 2: List tickets with cursor pagination
GET /v1/tickets?limit=25&cursor=eyJpZCI6InRfMTAxIn0=
200 OK (application/json):
{
"items": [ { "id": "t_101", ... }, { "id": "t_100", ... } ],
"nextCursor": "eyJpZCI6InRfMDk1In0=",
"hasMore": true
}
Errors: 400 for invalid cursor, 401 for auth issue
Example 3: Webhook contract for ticket status updates
Event: ticket.status.changed
Delivery: POST to subscriber URL with HMAC signature header
Payload (application/json):
{
"eventId": "evt_789",
"type": "ticket.status.changed",
"occurredAt": "2024-06-02T12:00:00Z",
"data": { "ticketId": "t_101", "oldStatus": "open", "newStatus": "in_progress" }
}
Retry: exponential backoff, max 24h. Respond with 2xx to acknowledge.
How to run API-first in a team
- Start with a short problem statement and user flows.
- Draft the spec. Keep endpoints small and composable.
- Run a quick review with frontend, QA, and partners. Resolve naming, fields, and error cases.
- Mock the API and validate with real UI or scripts.
- Set a style guide: naming, pagination, errors, timestamps, booleans, enums.
- Adopt a change log and a deprecation policy with timelines.
Exercises
These mirror the exercises below. Do them contract-first, then peek at solutions only after your attempt.
- ex1: Design POST /v1/tickets (create) with idempotency and a clear error model.
- ex2: Design GET /v1/tickets with cursor pagination, filtering by status, and sorting by createdAt.
- ex3: Design a webhook event contract for ticket.created.
Checklist before you move on
- Endpoints named with clear nouns and verbs.
- All request/response bodies have explicit schemas.
- Errors follow a consistent structure with codes.
- Pagination documented and predictable.
- Security described (auth type, scopes if any).
- Idempotency defined for non-safe operations.
- Versioning noted and non-breaking changes preferred.
Common mistakes and self-check
- Mixing implementation concerns into the contract (leaky DB field names). Use business terms instead.
- Inconsistent casing and naming. Pick one style and stick to it (e.g., snake_case for fields, kebab-case or camelCase—document it).
- Ambiguous errors. Provide code, title, and actionable detail.
- Unbounded responses. Always offer pagination or limits.
- Breaking changes without a plan. Mark deprecated fields and provide timelines.
Self-check prompts
- Can a client implement against your spec without guessing?
- Are error scenarios covered with examples?
- Is the happy path and at least one failure path shown for each endpoint?
- Would adding a new optional field break existing clients? If yes, redesign.
Practical projects
- Issue Tracker API: tickets, comments, labels. Include pagination, filtering, idempotent create, and webhooks.
- Payments-like API: charges, refunds, disputes. Emphasize idempotency and error codes.
- Catalog + Orders: list/search products, create orders, order state machine. Include async processing with 202 + polling or webhooks.
Acceptance criteria template
- OpenAPI or equivalent contract is complete and linted.
- At least 3 worked examples present in the spec as examples.
- Mock server responds per contract; clients can integrate without backend changes.
- Change log and deprecation notes included.
Learning path
- Before: HTTP basics, JSON, authentication fundamentals.
- This subskill: API First Design — contracts, reviews, mocking, consistency.
- Next: API security deep dive, testing strategies, performance and rate limiting, versioning and deprecation workflows.
Who this is for
- API Engineers and Backend Developers who want predictable, maintainable APIs.
- Frontend/Integrations Engineers who need stable contracts for parallel work.
- Tech Leads aiming to standardize API practices across teams.
Prerequisites
- Comfort with HTTP methods, status codes, and JSON.
- Basic understanding of authentication (e.g., bearer tokens).
- Familiarity with a schema language (e.g., OpenAPI or JSON Schema) is helpful.
Next steps
- Adopt a style guide and linter for your specs.
- Introduce mock servers into your CI or local dev workflow.
- Pilot API-first on a small feature, gather feedback, and iterate.
Mini challenge
Design a minimal contract for PATCH /v1/tickets/{id} to update only priority and status. Include validation rules, errors, and an example request/response. Keep it backward compatible and idempotent.
Quick Test
Take the quick test below to check your understanding. Available to everyone; log in to save your progress.