HTTP API design rules
Rules for HTTP APIs covering resource naming, status codes, problem+json errors, cursor pagination, idempotency keys and versioning. Load when designing or changing HTTP endpoints.
When you design or change an HTTP API in this project, apply these rules. Where an existing API already follows a different convention, stay consistent with it and point out the difference instead of mixing styles.
Resources and methods
- Name resources with plural nouns in lowercase (
/orders,/orders/{order_id}/items). Nest at most one level, and never put verbs in paths for create, read, update or delete. - Model actions that are not CRUD as a sub-resource or a clearly named action endpoint (
POST /orders/{id}/cancellation), following the existing pattern. GETis safe and has no body.PUTreplaces and is idempotent.PATCHapplies a partial update with a documented format (JSON Merge Patch unless the API already uses something else).DELETEis idempotent.- Use one field casing across the whole API, matching what exists.
Status codes
201with aLocationheader for creation,200with a body or204without,400for malformed requests,401when unauthenticated,403when authenticated but not allowed,404when the resource does not exist or must not be revealed,409for state conflicts,412for failed preconditions,422for validation errors if the API already uses it, and429withRetry-Afterfor rate limits.- Never return
200with an error body, or a5xxfor a client mistake.
Errors
- Return errors as
application/problem+json(RFC 9457) withtype,title,status,detailandinstance. Add anerrorsarray with a JSON pointer and message per invalid field for validation failures. - Make
typea stable identifier clients can branch on. Never expose stack traces, SQL or internal hostnames.
Collections
- Paginate every collection that can grow. Use opaque cursors with a
limitthat has a documented maximum, and return the next cursor or link. Use offset pagination only for small, stable sets. - Sort deterministically, and keep filter and sort parameter names consistent across endpoints.
Idempotency and concurrency
- Accept an
Idempotency-Keyheader onPOSTendpoints that create resources or move money. Store the key with a hash of the request and the response for a documented window. Replay the stored response for a repeated key, and reject the same key with a different body. - Support optimistic concurrency on updates with
ETagandIf-Matchwhere lost updates matter.
Data formats
- Timestamps are RFC 3339 strings in UTC. Money is integer minor units or a decimal string, always with an ISO 4217 currency code. Identifiers are strings.
- Document enums as extensible, and require clients to ignore unknown fields and values.
Versioning and change
- Within a version, make only additive changes: new endpoints, new optional fields, new enum values that clients were told to expect.
- Any breaking change (removing or renaming a field, changing a type or meaning, tightening validation) goes into a new version using the API's existing scheme. Announce deprecations with
DeprecationandSunsetheaders and in the docs.
Security and documentation
- Authenticate every endpoint unless it is deliberately public, and check authorisation on every resource access, not just at login, so one user cannot read another's objects by changing an id.
- Never put secrets or personal data in URLs.
- Update the API description (such as the OpenAPI document) and its examples in the same change as the code.
details
- kind
- Rule: standing instructions for everything the assistant does
- domain
- Software engineering
- category
- Conventions
- made for
- Backend engineer, Full-stack engineer, Software architect, Software engineer
- risk
- read-only
- version
- v1.0.0 · experimental
- reviewed
- 2026-10-02
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md, ChatGPT, claude.ai
use in
npx @hermes-hq/hodios install api-design-rules --target claude-codenpx skills add hermes-hq/hodios-dist --skill api-design-rules -a claude-codeRules are always-on instructions, so they are not in the plugins: add the skill, or paste the text into CLAUDE.md.
pairs well with
All of ConventionsSQL style rules
Standing rules for SQL an assistant writes, covering formatting, naming, explicit column lists, parameterised queries, NULL handling, data types and safe migrations.
sql-style-rulesC# style rules
Standing rules for C# an assistant writes, covering nullable reference types, async all the way with cancellation tokens, records and pattern matching, dependency injection and xUnit tests.
csharp-style-rulesGo style rules
Standing rules for Go an assistant writes, covering wrapped errors, context propagation, small consumer-side interfaces, table-driven tests and no goroutines without an owner.
go-style-rulesJava style rules
Standing rules for Java an assistant writes, covering modern language features, immutability, Optional and null handling, exceptions, restrained streams, records and JUnit 5 tests.
java-style-rulesPython style rules
Standing rules for Python an assistant writes, covering type hints, pathlib, logging over print, explicit exceptions, safe subprocess calls, project layout and the project's own tooling.
python-style-rulesReact component rules
Standing rules for React code an assistant writes, covering function components, the rules of hooks, colocated state, stable list keys, accessible markup and no effect-driven derived state.
react-component-rules