← Back to System Design Fundamentals

API Design Best Practices

System Design FundamentalsSeniorsystem-design

The Question

What are the best practices for API design?

What a Strong Answer Covers

  • Cursor vs offset tradeoff
  • RESTful naming.

Senior-Level Answer

Good API design is a contract between producers and consumers. A poorly designed API is expensive to change once clients depend on it. The following practices, applied consistently, produce APIs that are predictable, evolvable, and safe to build on.

**Resource-oriented URLs**: Use nouns, not verbs. `/orders` and `/orders/42` are correct; `/getOrder` is not. Nest resources only one level deep to avoid URL fragility—prefer `/orders/42/items` over `/users/1/orders/42/items`.

**Correct HTTP semantics**: Map CRUD to HTTP methods precisely (POST/GET/PUT/PATCH/DELETE). Return semantically correct status codes (201 for create, 204 for delete, 422 for validation errors, 409 for conflicts). Never return 200 with an error payload.

**Versioning**: Version from day one, before you have clients. URL versioning (`/v1/`) is the most visible and easiest to route at the gateway layer. Header versioning (`Accept: application/vnd.api.v2+json`) is cleaner but harder to test. Additive changes (new fields, new optional parameters) are non-breaking; removing or renaming fields is breaking.

**Pagination, filtering, sorting**: For collections, always paginate. Prefer cursor-based pagination over offset for large or frequently-updated datasets—offset pagination is inconsistent when items are inserted mid-page. Expose filtering via query parameters (`?status=active&sort=-created_at`).

**Authentication and authorization**: Use OAuth 2.0 / JWT for stateless auth. Never put credentials in URLs. Validate authorization at the resource level, not just the endpoint level—users should not be able to access other users' resources by ID manipulation (IDOR).

**Rate limiting**: Return `429 Too Many Requests` with `Retry-After` and `X-RateLimit-*` headers. Limit by API key or user identity, not just IP.

**Idempotency keys**: For non-idempotent POST operations that have significant side effects (payments, email sends), accept an `Idempotency-Key` header and deduplicate server-side.

**Error responses**: Return structured, consistent error bodies with a machine-readable code, a human-readable message, and optionally a documentation link. Never expose stack traces.

**Documentation**: Use OpenAPI (Swagger) to generate interactive docs and client SDKs. Treat the spec as the source of truth, not an afterthought.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Covers resource naming, HTTP method semantics, status codes, versioning, and pagination with trade-offs.

3/3 — Strong Answer

Covers all the above plus idempotency keys, IDOR prevention, cursor pagination trade-offs, structured error bodies, and rate limiting headers.

Common Mistakes

  • Versioning the API only after the first breaking change, when clients already exist.
  • Using offset pagination for large, frequently-updated datasets without mentioning cursor pagination.
  • Returning generic 400 or 500 without structured error bodies.
  • Not distinguishing authentication (401) from authorization (403) in error design.

Follow-Up Questions

  • Why is cursor-based pagination preferred over offset for large datasets? — Offset skips rows, which is inconsistent on insertions/deletions and expensive (full table scan to offset N). Cursors point to a stable position.
  • How would you handle a breaking change to a widely-used API endpoint? — Introduce /v2/ endpoint, deprecate /v1/ with sunset headers, communicate timeline, run both in parallel during migration window.
  • What is IDOR and how do you prevent it in an API? — Insecure Direct Object Reference—accessing another user's resource by guessing IDs. Prevent via ownership checks in the authorization layer, not just JWT validation.
  • How do you document an API so external developers can onboard in under an hour? — OpenAPI spec with examples for every endpoint, authentication guide, quickstart with curl examples, and changelog for versioned changes.

Related Questions

  • Redis Caching Patterns
  • Vertical vs Horizontal Scaling
  • API Versioning
  • SLOs vs SLAs
  • Availability — Five 9s

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout