Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Api Design

ASecurity

REST API design patterns including resource naming, status codes, pagination, filtering, error responses, versioning, and rate limiting for production APIs. Also lazy-loads api-versioning.md / contract-testing.md / schema-evolution.md / deprecation-lifecycle.md content migrated from rules/common/ on 2026-06-02.

12 stars
0 votes
0 copies
0 views
Added 9/28/2026
developmenttypescriptpythongosqlnextjsnodetestingapifrontendbackend

Works with

cursorcliapi

Security Analysis

A100/100

Scanned 9/28/2026

Install to Claude Code

$npx -y skills add Nmor/the-claude-council --skill api-design --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Design?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Api Design
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nmor-api-design/badge)](https://www.skillsdirectory.com/skills/nmor-api-design)

More formats (shields.io, HTML) on the badges page.

Files
SKILL.md
---
name: api-design
description: REST API design patterns including resource naming, status codes, pagination, filtering, error responses, versioning, and rate limiting for production APIs. Also lazy-loads api-versioning.md / contract-testing.md / schema-evolution.md / deprecation-lifecycle.md content migrated from rules/common/ on 2026-06-02.
paths:
  - "**/routes/**"
  - "**/handlers/**"
  - "**/controllers/**"
  - "**/middleware/**"
  - "**/api/**"
  - "**/openapi*"
  - "**/swagger*"
  - "**/asyncapi*"
  - "**/*.openapi.yaml"
  - "**/*.openapi.yml"
  - "**/*.openapi.json"
  - "**/*.proto"
  - "**/*.graphql"
  - "**/schema.graphql"
  - "**/schema.json"
  - "**/migrations/**"
  - "**/v[0-9]/**"
  - "**/v[0-9][0-9]/**"
  - "**/endpoints/**"
  - "**/resolvers/**"
  - "**/contracts/**"
  - "**/pact/**"
---

# API Design Patterns

> **Size budget: 25 KB.** Check: wc -c. Gate: node ~/.claude/scripts/token-budget.mjs --check

Conventions and best practices for designing consistent, developer-friendly REST APIs.

## When to Activate

- Designing new API endpoints
- Reviewing existing API contracts
- Adding pagination, filtering, or sorting
- Implementing error handling for APIs
- Planning API versioning strategy
- Building public or partner-facing APIs

## Routing table

This skill is `paths:`-gated: when a glob above matches, this file is added to the
always-on context in full. It is therefore a ROUTER. The detail lives in
`references/`; read the row you need, not the whole set.

| Topic | Read |
| --- | --- |
| Resource design + HTTP methods / status codes — URL structure, naming rules, method semantics table, status-code reference, common mistakes | [`references/rest-conventions.md`](references/rest-conventions.md) |
| Response format + error envelope — success, collection, error bodies, envelope variants | [`references/response-format.md`](references/response-format.md) |
| Pagination, filtering, sorting, search — offset vs cursor (+ when to use which), filter/sort/search syntax, sparse fieldsets | [`references/pagination-filtering.md`](references/pagination-filtering.md) |
| Authentication, authorization, rate limiting — bearer/API key, ownership + role checks, `RateLimit-*` headers, tier table | [`references/auth-and-rate-limits.md`](references/auth-and-rate-limits.md) |
| Implementation examples — TypeScript (Next.js), Python (DRF), Go (net/http) handlers | [`references/implementation-examples.md`](references/implementation-examples.md) |
| Response-shape contracts (BE/FE drift) — the empty-not-broken bug class, the shared-type + pinned-test contract, endpoint-change workflow | [`references/response-shape-contracts.md`](references/response-shape-contracts.md) |
| Versioning — strategies, breaking vs additive, tolerant reader, parallel versions, `Sunset`/`Deprecation` headers, GraphQL + gRPC specifics, SDK versioning | [`references/api-versioning.md`](references/api-versioning.md) |
| Contract testing — CDC (Pact) vs schema-based (OpenAPI/GraphQL/Proto), deploy gating, per-stack examples | [`references/contract-testing.md`](references/contract-testing.md) |
| Schema evolution — compatibility modes, expand-contract, zero-downtime DDL, backfills, per-store specifics (PG/MySQL/Mongo/DynamoDB/Kafka) | [`references/schema-evolution.md`](references/schema-evolution.md) |
| Deprecation lifecycle — the four stages + calendar minimums, per-language `@deprecated` patterns, HTTP deprecation headers | [`references/deprecation-lifecycle.md`](references/deprecation-lifecycle.md) |
| API design standards (endpoint checklist + skill chain) — the migrated `rules-library/common/api-design.md` | [`references/api-design-standards.md`](references/api-design-standards.md) |

## API Design Checklist

Before shipping a new endpoint:

- [ ] Resource URL follows naming conventions (plural, kebab-case, no verbs)
- [ ] Correct HTTP method used (GET for reads, POST for creates, etc.)
- [ ] Appropriate status codes returned (not 200 for everything)
- [ ] Input validated with schema (Zod, Pydantic, Bean Validation)
- [ ] Error responses follow standard format with codes and messages
- [ ] Pagination implemented for list endpoints (cursor or offset)
- [ ] Authentication required (or explicitly marked as public)
- [ ] Authorization checked (user can only access their own resources)
- [ ] Rate limiting configured
- [ ] Response does not leak internal details (stack traces, SQL errors)
- [ ] Consistent naming with existing endpoints (camelCase vs snake_case)
- [ ] Documented (OpenAPI/Swagger spec updated)
- [ ] Response shape pinned by a shared type AND a contract test (see "Response-shape contracts"
  below)

## Purpose

Design REST API contracts that are consistent, predictable, and stable across versions. Covers
resource naming, status codes, pagination, filtering, error envelopes, authentication shape,
rate-limit semantics, and response-shape contracts between backend and frontend.

**Negative scope**: NOT GraphQL schema design (GraphQL evolves additively at field level, not URL
level). NOT internal RPC contracts (gRPC / Proto live under their own discipline). NOT message-bus
event schemas (Kafka / SNS contracts are the event payload, not a REST surface). NOT internal-only
DB-backed handlers with no external consumer.

## When NOT to use

- GraphQL services — schema-level evolution rules differ; use a GraphQL-specific guide
- gRPC / Proto3 services — `proto` files are the contract
- Webhook-only outbound interfaces — see `~/.claude/rules-library/common/api-versioning.md` for
  sunset semantics
- Pure event-driven systems (Kafka, SNS, EventBridge) where the contract is the event schema
- Throw-away admin scripts with a single internal caller

## Standards Cited

- **RFC 9110** (HTTP Semantics, Jun 2022) §15.5 (Client Error 4xx) + §15.6 (Server Error 5xx) —
  status code semantics
- **RFC 9110 §9.2.2** — Idempotent methods (PUT, DELETE, GET, HEAD, OPTIONS)
- **RFC 9457** (Problem Details for HTTP APIs, Jul 2023) — standardised error response shape
- **RFC 8594** — `Sunset` HTTP header for deprecation
- **RFC 8288** — Web Linking (`Link` header for pagination + relations)
- **RFC 6585 §4** — `429 Too Many Requests`
- **OWASP ASVS 4.0.3 §13.1** (Generic Web Service Security) + §13.2.5 (HTTP method allowlist)
- **OWASP API Security Top 10 (2023)** API1 (BOLA), API4 (Unrestricted Resource Consumption), API9
  (Improper Inventory Management)

## Anti-Patterns

| Pattern | Why bad | Correct alternative |
| --- | --- | --- |
| `200 OK` with `success: false` body | Loses HTTP semantics; generic middleware (CDN, load balancer, retry logic) can't branch | Map outcome to status — 4xx client, 5xx server per RFC 9110 §15 |
| Verb in URL (`/getUsers`, `/createOrder`) | REST URLs are nouns; the HTTP verb is the action | `GET /users`, `POST /orders` |
| Exposing DB primary keys (auto-incrementing IDs) | Enumeration leaks customer count + enables IDOR (OWASP API1) | UUIDs / ULIDs / opaque encoded IDs |
| Non-idempotent POST without `Idempotency-Key` | Double-charge / double-create on network retry | Accept `Idempotency-Key` header (Stripe pattern) — see `~/.claude/rules-library/common/idempotency.md` |
| `201 Created` without `Location` header | Client doesn't know the new resource URL | Always set `Location: /api/v1/<resource>/<id>` |
| Major version bump for additive changes (new optional field) | Forces unnecessary client migration; burns version slots | Additive = same major; only breaking = bump |
| Offset pagination on tables with concurrent writes | Items shift between pages → duplicates and gaps | Cursor pagination over indexed column |
| Server stack traces leaking through error body | Reveals framework, version, file paths to attackers | Strip at boundary; `error.code` + `error.message` only |

## Verification Checklist

- [ ] Status codes match RFC 9110 (404 missing, 409 conflict, 422 unprocessable, 429 rate-limit)
- [ ] Error envelope has stable `error.code` + `error.message` + optional `details[]`; no internal
  stack traces
- [ ] List endpoints paginated (cursor preferred); response includes `meta.next_cursor` or
  `meta.total`
- [ ] POST returns `201 Created` + `Location` header
- [ ] `Idempotency-Key` supported on mutating POSTs (per
  `~/.claude/rules-library/common/idempotency.md`)
- [ ] Versioning via URL path (`/api/v1/`) OR Accept header; deprecation signalled via `Sunset` +
  `Link: rel="successor-version"`
- [ ] Rate-limit headers (`RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`) on every
  endpoint
- [ ] Response shape pinned by shared type AND a contract test (per Response-shape contracts above)
- [ ] OWASP API Top 10 cross-check (BOLA on every object-level read, rate-limit on every public
  endpoint)

## Cross-References

- `~/.claude/rules-library/common/api-versioning.md` — major-vs-minor evolution rules + `Sunset`
  lifecycle
- `~/.claude/rules-library/common/idempotency.md` — `Idempotency-Key` contract
- `~/.claude/rules-library/common/error-handling-with-context.md` — error envelope shape
  (operation + ids)
- `~/.claude/rules-library/common/error-codes.md` — stable code catalogue
- `~/.claude/rules-library/common/rate-limiting.md` — RateLimit-* header standard
- `~/.claude/rules-library/common/contract-testing.md` — CDC (Pact) + OpenAPI / JSON Schema
  validation
- `~/.claude/skills/backend-patterns/SKILL.md` — handler / middleware patterns
- `~/.claude/agents/security-reviewer.md` — OWASP API Top 10 review

## Why this skill exists

REST APIs are the most-touched public contract any product ships. Every customer integration depends
on URL shape, status semantics, error structure, and pagination behaviour. The recurring failure
modes are mechanical and expensive:

- Status codes drift (`200 OK` becomes the universal envelope) → generic clients break, CDN-level
  retry logic mis-fires, error-rate alerting wrong
- Error shapes diverge per handler → frontend can't write one error handler → every screen ships its
  own
- Pagination breaks under writes → page 2 has rows from page 1 → users see duplicates, support
  tickets surge
- Version bumps land too eagerly (forced consumer work for additive change) or too late (breaking
  change inside a "minor")
- Primary keys leaked → IDOR exposure + customer enumeration on a public list endpoint

Each of these costs migration weeks across N consumers when the API has integrations. Cost of
correct design at write-time: one design review. Cost of redesign with integrators in flight:
quarters.

## Learning hooks

Per `~/.claude/rules/common/continuous-learning-mandate.md`:

**Signals to watch**:

- Verb-based endpoint (`/getUsers`, `/createOrder`) introduced (REST naming weakening)
- HTTP status code mismatched to outcome (validation failure as 400 not 422, create as 200 not 201)
- Error envelope differs between handlers (consistency drift — sister `error-codes.md` violation)
- Pagination missing on a list endpoint (`page`, `limit`, `total`, `next_cursor` absent)
- Versioning omitted on public API (sister `api-versioning.md` violation)
- Idempotency key not accepted on a POST mutation (sister `idempotency.md` violation)
- Rate-limit headers (`RateLimit-*`, `Retry-After`) absent on a public endpoint
- Response shape evolves without contract test (sister `contract-testing.md` violation)
- `as` cast hiding shape drift between BE + FE (sister S6571 + `no-discards.md` rule 8)

**Refinement candidates**:

- New endpoint-class row when a recurring shape emerges (e.g., webhook receivers, SSE streams, gRPC
  unary, GraphQL mutation)
- Tightening of the response-envelope contract when sister rules (`error-codes.md`,
  `error-handling-with-context.md`) evolve
- New cross-reference when a sister skill (security-review, observability-patterns) adds an
  endpoint-level gate
- New versioning template when a recurring breaking-change pattern emerges (e.g., field rename, enum
  addition)

<!-- ============================================================
     Migration appendix: 2026-06-02 lazy-rules-loading
     ============================================================ -->

## Migrated rules (2026-06-02)

The following rules were migrated from `~/.claude/rules/common/` into this skill as part of the
lazy-rules-loading plan. Phase H will delete the source files.

- `rules-library/common/api-design.md`
- `rules-library/common/api-versioning.md`
- `rules-library/common/contract-testing.md`
- `rules-library/common/schema-evolution.md`
- `rules-library/common/deprecation-lifecycle.md`

---

Attribution

NmorNmor
View sourceMore from Nmor →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284972 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

10311 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →