design-checklist
Run through this before declaring an API contract done. It is ordered the way you should *design*: resources first, cross-cutting rules last. Every box is a place real APIs go wrong in production.
$ npx -y skills add vanara-agents/skills --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Run through this before declaring an API contract done. It is ordered the way you should *design*: resources first, cross-cutting rules last. Every box is a place real APIs go wrong in production.
Agent definition
design-checklist.mdAPI Design Checklist
Run through this before declaring an API contract done. It is ordered the way you should *design*: resources first, cross-cutting rules last. Every box is a place real APIs go wrong in production.
1. Resource modeling
- [ ] Collections are **plural nouns** (`/orders`, `/users`) — never verbs (`/getOrders` is wrong; the
verb is `GET`).
- [ ] Nesting shows ownership and is **at most one level deep** (`/users/{id}/orders`). Deeper than that,
link by ID instead.
- [ ] Non-CRUD actions are modeled as sub-resources or controller endpoints
(`POST /orders/{id}/refunds`), not RPC verbs (`POST /refundOrder`).
- [ ] Identifiers are **stable and opaque**. Prefer UUID/ULID over auto-increment where enumeration is a
risk (`ord_01H...` not `/orders/41`).
- [ ] Field naming is **consistent casing** across the whole API (pick `camelCase` or `snake_case` once).
2. HTTP methods & status codes
| Method | Use | Safe | Idempotent | |---|---|---|---| | GET | read | yes | yes | | POST | create / non-idempotent action | no | no | | PUT | full replace | no | yes | | PATCH | partial update | no | no | | DELETE | remove | no | yes |
- [ ] `GET` **never mutates** state. Caches and proxies rely on this.
- [ ] Each endpoint lists the **accurate** status codes for success *and* failure.
- [ ] `201 Created` returns a `Location` header for the new resource.
- [ ] `204 No Content` for successful deletes with no body.
- [ ] Never `200 OK` with `{"success": false}` — use real 4xx/5xx codes.
- [ ] `401` (not authenticated) vs `403` (authenticated, not allowed) are used correctly; `404`-vs-`403`
is a deliberate choice to avoid leaking existence.
- [ ] `409` (conflict) vs `422` (semantically invalid) vs `400` (malformed) are distinguished.
3. Response envelope & errors
- [ ] **One envelope shape** everywhere: `data`, `meta` (for lists), `error`.
- [ ] On error, `data: null` and a populated `error` with a machine-readable `code`, a human `message`,
and optional field-level `details`.
- [ ] The **same** error shape is returned for every failure across every endpoint.
- [ ] Errors include a `requestId`/correlation id for support.
4. Pagination, filtering, sorting
- [ ] **Every** collection endpoint paginates. No exceptions — an unbounded list is a latent outage.
- [ ] `limit` is **capped server-side** (e.g. max 100) so a client can't request a million rows.
- [ ] Cursor (keyset) pagination for large/growing/real-time data; offset only for small datasets or
genuine page-number UX.
- [ ] Filtering and sorting use consistent query-param conventions (`?status=open&sort=-createdAt`).
- [ ] A unique tiebreaker (e.g. `id`) is part of any sort to avoid dropped/repeated rows at boundaries.
5. Auth, rate limiting, idempotency, concurrency
- [ ] Auth requirement is documented **per endpoint** (and which scopes/roles).
- [ ] Authorization is enforced server-side per action (guard against IDOR — check ownership, not just
authentication).
- [ ] Rate limits are documented; throttled responses use `429` + `Retry-After`.
- [ ] `POST`s that create resources accept an `Idempotency-Key` header so retries don't double-create.
- [ ] Updates support optimistic concurrency (`ETag` + `If-Match`) where lost-update is a real risk.
- [ ] All input is validated at the boundary; invalid input fails fast with `400`/`422` and field details.
6. Evolvability
- [ ] An explicit versioning strategy is chosen and documented (see `versioning-and-evolution.md`).
- [ ] The change you are making is classified **additive (safe)** or **breaking (needs a version)**.
- [ ] New optional fields default sensibly so old clients keep working.
Read more
API Design Checklist
Run through this before declaring an API contract done. It is ordered the way you should *design*: resources first, cross-cutting rules last. Every box is a place real APIs go wrong in production.
1. Resource modeling
- [ ] Collections are **plural nouns** (`/orders`, `/users`) — never verbs (`/getOrders` is wrong; the
verb is `GET`).
- [ ] Nesting shows ownership and is **at most one level deep** (`/users/{id}/orders`). Deeper than that,
link by ID instead.
- [ ] Non-CRUD actions are modeled as sub-resources or controller endpoints
(`POST /orders/{id}/refunds`), not RPC verbs (`POST /refundOrder`).
- [ ] Identifiers are **stable and opaque**. Prefer UUID/ULID over auto-increment where enumeration is a
risk (`ord_01H...` not `/orders/41`).
- [ ] Field naming is **consistent casing** across the whole API (pick `camelCase` or `snake_case` once).
2. HTTP methods & status codes
| Method | Use | Safe | Idempotent | |---|---|---|---| | GET | read | yes | yes | | POST | create / non-idempotent action | no | no | | PUT | full replace | no | yes | | PATCH | partial update | no | no | | DELETE | remove | no | yes |
- [ ] `GET` **never mutates** state. Caches and proxies rely on this.
- [ ] Each endpoint lists the **accurate** status codes for success *and* failure.
- [ ] `201 Created` returns a `Location` header for the new resource.
- [ ] `204 No Content` for successful deletes with no body.
- [ ] Never `200 OK` with `{"success": false}` — use real 4xx/5xx codes.
- [ ] `401` (not authenticated) vs `403` (authenticated, not allowed) are used correctly; `404`-vs-`403`
is a deliberate choice to avoid leaking existence.
- [ ] `409` (conflict) vs `422` (semantically invalid) vs `400` (malformed) are distinguished.
3. Response envelope & errors
- [ ] **One envelope shape** everywhere: `data`, `meta` (for lists), `error`.
- [ ] On error, `data: null` and a populated `error` with a machine-readable `code`, a human `message`,
and optional field-level `details`.
- [ ] The **same** error shape is returned for every failure across every endpoint.
- [ ] Errors include a `requestId`/correlation id for support.
4. Pagination, filtering, sorting
- [ ] **Every** collection endpoint paginates. No exceptions — an unbounded list is a latent outage.
- [ ] `limit` is **capped server-side** (e.g. max 100) so a client can't request a million rows.
- [ ] Cursor (keyset) pagination for large/growing/real-time data; offset only for small datasets or
genuine page-number UX.
- [ ] Filtering and sorting use consistent query-param conventions (`?status=open&sort=-createdAt`).
- [ ] A unique tiebreaker (e.g. `id`) is part of any sort to avoid dropped/repeated rows at boundaries.
5. Auth, rate limiting, idempotency, concurrency
- [ ] Auth requirement is documented **per endpoint** (and which scopes/roles).
- [ ] Authorization is enforced server-side per action (guard against IDOR — check ownership, not just
authentication).
- [ ] Rate limits are documented; throttled responses use `429` + `Retry-After`.
- [ ] `POST`s that create resources accept an `Idempotency-Key` header so retries don't double-create.
- [ ] Updates support optimistic concurrency (`ETag` + `If-Match`) where lost-update is a real risk.
- [ ] All input is validated at the boundary; invalid input fails fast with `400`/`422` and field details.
6. Evolvability
- [ ] An explicit versioning strategy is chosen and documented (see `versioning-and-evolution.md`).
- [ ] The change you are making is classified **additive (safe)** or **breaking (needs a version)**.
- [ ] New optional fields default sensibly so old clients keep working.
🐒 Free agents, skills & packs for Claude Code One subscription. An army of Claude Code agents. 30 production-grade agents, skills, and packs for Claude Code — free, Apache-2.0, install with one command.
Repo: vanara-agents/skills
Other agents on vanara-agents-skills.
- AGENT
Use when designing a new HTTP/GraphQL API or changing an existing one — modeling resources, defining endpoint contracts, choosing status codes, pagination, filtering, error envelopes, versioning, and idempotency. Produces a reviewable API contract plus an OpenAPI snippet, not
Open agent - review-notes
This shows how the api-designer agent reviews a flawed draft. Findings are severity-ranked so the implementer fixes the contract-breakers first. Severity legend: **CRITICAL** (breaks clients / data risk), **HIGH** (real bug or inconsistency), **MEDIUM** (maintainability),
Open agent - contract-and-openapi
The contract is the deliverable. Express it as an **OpenAPI 3.1** document so it is human-readable *and* machine-checkable. This reference covers how to structure that document and what `scripts/lint-openapi.mjs` enforces.
Open agent - versioning-and-evolution
APIs are forever once published: a consumer you've never met may depend on any field you expose. Design so you can **add without breaking**, and version explicitly when you must break.
Open agent - pr-comment-template
Copy-paste templates for leaving review comments. Keep each comment to one finding: an anchor, the problem, and the fix.
Open agent - sample-review-output
A complete review of a hypothetical PR, in the standard format. Use this as the model for tone, structure, and the anchor → problem → fix pattern.
Open agent

