guidance layer
API Conventions
Follow these conventions when designing, implementing, or reviewing REST APIs. Consistency across endpoints reduces integration friction and simplifies documentation.
URL Structure and Naming
- Use lowercase, hyphen-separated path segments:
/user-profiles, not/userProfilesor/user_profiles. - Use plural nouns for resource collections:
/orders,/products,/users. - Use resource identifiers as path segments:
/users/{userId}/orders/{orderId}. - Limit nesting to two levels; deeper relationships should use query parameters or links.
- Use query parameters for filtering, sorting, and pagination:
?status=active&sort=-created_at&page=2. - Avoid verbs in URLs; let HTTP methods convey the action.
HTTP Methods
GET— Retrieve a resource or collection. Must be safe and idempotent. Never mutate state.POST— Create a new resource or trigger a non-idempotent action. Return 201 with Location header for creates.PUT— Replace an entire resource. Must be idempotent. Return 200 or 204.PATCH— Partially update a resource. Use JSON Merge Patch or JSON Patch content types. Return 200.DELETE— Remove a resource. Must be idempotent. Return 204 on success, 404 if already absent.OPTIONS— Return allowed methods and CORS headers. Used for preflight requests.
Status Codes
Use the most specific applicable status code:
| Range | Use for |
|---|---|
| 200 | Successful retrieval or update |
| 201 | Resource created (include Location header) |
| 204 | Success with no response body |
| 400 | Malformed request (syntax or validation errors) |
| 401 | Missing or invalid authentication credentials |
| 403 | Authenticated but insufficient permissions |
| 404 | Resource not found |
| 409 | Conflict (e.g., duplicate key, version mismatch) |
| 422 | Semantically invalid request (valid syntax but business rule violation) |
| 429 | Rate limit exceeded (include Retry-After header) |
| 500 | Unexpected server error (never expose internals) |
Error Response Format
Return a consistent JSON error body for all 4xx and 5xx responses:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Human-readable summary of the problem",
"details": [
{
"field": "email",
"issue": "Must be a valid email address"
}
],
"request_id": "req_abc123"
}
}
code— Machine-readable error identifier (UPPER_SNAKE_CASE).message— Brief, user-safe description. Never include stack traces or internal paths.details— Optional array of field-level errors for validation failures.request_id— Correlation identifier for debugging (matches server-side logs).
Pagination
- Use cursor-based pagination for large or frequently-changing collections.
- Support limit/offset as a simpler alternative for smaller, stable datasets.
- Return pagination metadata in the response body:
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6MTAwfQ",
"has_more": true,
"total_count": 2340
}
}
- Include
total_countonly when it can be computed efficiently.
Versioning
- Use URL prefix versioning for major breaking changes:
/v1/users,/v2/users. - Increment the version number only on backward-incompatible changes.
- Support the previous major version for at least 6 months after a new version ships.
- Treat additive changes (new optional fields, new endpoints) as backward-compatible.
- Document deprecation timelines in the Sunset response header and changelog.
Request and Response Conventions
- Use
snake_casefor JSON field names throughout request and response bodies. - Represent timestamps in ISO 8601 format with UTC timezone:
2025-06-15T10:30:00Z. - Use envelope format for collections:
{ "data": [...], "pagination": {...} }. - Return the full created or updated resource in response to POST, PUT, and PATCH.
- Accept and return
Content-Type: application/jsonby default. - Support
Acceptheader negotiation where multiple formats are available.
Rate Limiting and Throttling
- Enforce rate limits per client or API key.
- Return
429 Too Many Requestswith aRetry-Afterheader (seconds until next allowed request). - Include rate limit headers on every response:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset.
CORS and Security Headers
- Configure CORS to allow only trusted origins; avoid wildcard
*in production. - Return appropriate CORS headers:
Access-Control-Allow-Origin,Access-Control-Allow-Methods,Access-Control-Allow-Headers. - Set
Cache-Control: no-storeon responses containing sensitive data. - Include
X-Content-Type-Options: nosniffandX-Request-Idon all responses.
Documentation and Discoverability
- Provide an OpenAPI 3.x specification for every public API.
- Include request/response examples for each endpoint.
- Document authentication requirements, rate limits, and error codes.
- Use consistent terminology across endpoint descriptions.