Skip to content

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 /userProfiles or /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_count only 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_case for 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/json by default.
  • Support Accept header negotiation where multiple formats are available.

Rate Limiting and Throttling

  • Enforce rate limits per client or API key.
  • Return 429 Too Many Requests with a Retry-After header (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-store on responses containing sensitive data.
  • Include X-Content-Type-Options: nosniff and X-Request-Id on 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.