Skip to content
Skill · Claude CodeSKILL.mdCoding

API Design First

Write and review the endpoint contract — resources, errors, pagination, versioning — before any handler code exists.

Use when: Use when adding or changing API endpoints, so the contract is designed and reviewed before implementation locks in accidental decisions.

@libraryNewcomer
0 upvotes0 forks0 comments

The skill file

Claude Code · SKILL.md
SKILL.md3680 chars
# API Design First Implementation details leak into contracts when the contract is written last. Design the interface as an artifact (OpenAPI spec, tRPC router signatures, or a markdown contract doc), get it reviewed, then implement against it. ## Step 1 — Write the contract document For every endpoint, specify before writing handler code: - Method + path, request shape, response shape with field types and nullability, status codes, auth requirement, and rate-limit class. - At least one concrete example request/response pair per endpoint. Examples expose bad designs faster than schemas do. - Walk a consumer scenario end to end ("client creates X, lists X, updates X") using only the contract. If the walkthrough needs information the API doesn't return, the design is incomplete. ## Naming and shape rules - Resources are plural nouns: `/invoices`, `/invoices/{id}/line-items`. Verbs only for true actions that aren't CRUD: `/invoices/{id}/send`. - Pick one casing for JSON fields (camelCase or snake_case) and never mix. Match the codebase's existing choice. - No booleans that will grow a third state — use an enum (`status: "draft" | "sent" | "void"` instead of `isSent`). - Timestamps are ISO 8601 UTC strings, money is integer minor units plus a currency code, IDs are opaque strings (never expose auto-increment integers in new APIs). - Don't return different shapes from the same endpoint based on input. Variants belong in a discriminated union with an explicit `type` field. ## Errors - Define the error envelope once and use it everywhere: `{ "error": { "code": "invoice_already_sent", "message": "...", "details": {...} } }`. Machine-readable `code` is the contract; `message` is for humans and may change. - Map deliberately: 400 malformed input, 401 unauthenticated, 403 unauthorized, 404 missing (also for resources the caller can't know exist), 409 state conflict, 422 semantically invalid, 429 throttled. Reserve 500 for actual bugs — never return 500 for predictable conditions. - Validation errors list *all* failures in `details`, not just the first. Clients hate fix-one-resubmit loops. - Write the error cases into the contract with the same rigor as success cases. Every 4xx an endpoint can return is part of its signature. ## Pagination, filtering, ordering - Every collection endpoint paginates from day one — retrofitting breaks clients. Default and max page sizes are stated in the contract. - Prefer cursor pagination (`?cursor=...&limit=50`, response carries `nextCursor: string | null`) for anything that grows; offset pagination drifts under concurrent writes. - Filters are explicit query params with documented semantics. Reject unknown params with a 400 rather than ignoring them — silent ignoring hides client typos forever. ## Versioning and evolution - Additive changes (new optional field, new endpoint) need no version bump. Breaking changes (removing/renaming a field, changing a type, tightening validation) need a new version or a deprecation cycle — never a silent change. - State the deprecation policy in the contract: how breakage is announced, the sunset window, and how callers detect it (e.g. a `Deprecation` header). - Plan for unknown fields: clients must ignore fields they don't recognize; document this so future additions stay non-breaking. ## Before implementing - [ ] Contract reviewed by at least one consumer of the API (or by walking their use case yourself). - [ ] Every endpoint has examples, error cases, auth requirement, and pagination defined. - [ ] Names checked against existing endpoints for consistency. - [ ] Implementation tests assert against the contract's examples, so drift fails CI.

Install

drop into your repo

Save this to your project or home directory so Claude Code can load it.

path~/.claude/skills/api-design-first/SKILL.md
Discussion

What people are saying

Forks

0 forks of this skill
Loading forks…