Contracts over cleverness
A production API is a long-lived contract. Prefer explicit resource names, predictable error shapes, and pagination that clients can implement once.
Avoid leaking internal storage details into URLs. Clients should depend on meaning, not on how you store rows today.
Errors clients can act on
Return structured errors with a stable code, a human message, and optional field details. Clients should branch on codes, not on English sentences.
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after 30 seconds.",
"retryAfter": 30
}
}Version with intent
Not every change needs a new version. Additive fields are usually safe. Breaking response shapes or removing fields should force a version bump and a migration window.
Document deprecations with dates. Silence is how integrations rot.



