Consistency & Conventions
The individual rules matter less than applying them everywhere. An API that is 90% consistent is more confusing than one that is consistently quirky, because the exceptions are where bugs and support tickets live.
Pick conventions once
Section titled “Pick conventions once”Decide these for the whole API and write them down:
- Casing of fields —
camelCaseorsnake_case, the same in every response. - Plurals — every collection plural (
/articles,/users), no mixing. - IDs — one format (UUID, ULID, or integer) and one field name (
id). - Timestamps — ISO 8601 UTC strings (
2026-06-24T10:00:00Z), with consistent field names likecreatedAt/updatedAt. - Money & enums — minor units (integers) for money; documented string enums, not magic numbers.
Collections vs singletons
Section titled “Collections vs singletons”Most resources are items in a collection (/articles/42). A few are singletons — there is exactly one per context, so there is no ID:
GET /me # the authenticated userGET /settings # the account's settingsPATCH /settings # update themSingletons skip the collection level on purpose; do not invent a fake ID for them.
A conventions checklist
Section titled “A conventions checklist”- Collections are plural; items are
/collection/{id}. - Lowercase, hyphenated paths; no verbs; no file extensions.
- One casing, one ID format, one timestamp format across every resource.
- Errors share one shape (covered in Status Codes & Errors).
- The same field means the same thing everywhere.
| Advantages (Consistency) | Trade-offs |
|---|---|
| Faster developer onboarding — endpoints become guessable | Requires agreeing on conventions upfront — costs time |
| Easier SDK generation and documentation | Some conventions don’t fit every resource |
| Consistent client code — no special cases | Changing a convention later is a breaking change |
| Fewer bugs from typos or inconsistent casing | The team has to enforce it — needs linting or review |
Common mistakes
Section titled “Common mistakes”Inconsistent response format Symptom:
- One endpoint returns
{ data: [...] }, another returns[...]directly - Error responses vary too: some endpoints send
{ error: "..." }, others{ message: "..." } - Define a standard response envelope and use it everywhere
Inconsistent date format Symptom:
createdAt: "2024-01-15"on one endpoint,created: "15/01/2024"on another- Clients have to parse a different format per call
- Use ISO 8601 (
2024-01-15T10:30:00Z) consistently across the whole API
💡 Real-world examples
Stripe API:
- Every resource carries
id,object,created,livemode— consistent metadata- The same error shape on every endpoint:
{ error: { type, code, message, param } }GitHub API:
X-RateLimit-*headers on every response, consistently- Pagination via the
Linkheader on every collection endpoint