🌐

Top 50 REST API Design Interview Questions & Answers (2026)

50 Questions 20 Beginner 20 Intermediate 10 Advanced

About REST API Design

Top 50 REST API Design interview questions covering HTTP methods, status codes, authentication, versioning, and API best practices. Companies hiring for REST API Design roles test this knowledge at every stage — from first-round screens that check the basics to final-round conversations about real-world trade-offs.

What to Expect in a REST API Design Interview

Expect a mix of conceptual and practical REST API Design questions: clear definitions and core-concept checks for junior roles, hands-on scenario questions for mid-level roles, and architecture or trade-off discussions for senior roles. Interviewers usually move from foundational topics toward the kind of problems you'd actually face on the job.

How to Use This Guide

Work through the REST API Design questions in order — Beginner, then Intermediate, then Advanced — so each concept builds on the last. Every question has its own page; bookmark the ones that trip you up and revisit them the day before your interview.

Curated by Tech Baithak Editorial Team  ·  Last updated: June 2026

Beginner 20 questions

Core concepts every REST API Design developer must know.

01

What is REST and what are its six architectural constraints?

REST (Representational State Transfer) is an architectural style for designing networked APIs, defined by Roy Fielding in his 2000 doctoral dissertation. Its six constraints are: Client-Server (client and server are decoupled and evolve independently), Stateless (each request contains all information needed; server stores no client session state), Cacheable (responses must define themselves as cacheable or non-cacheable), Uniform Interface (consistent resource identification, manipulation through representations, self-descriptive messages, HATEOAS), Layered System (client cannot tell if it is connected directly to the server or an intermediary like a load balancer or CDN), and Code on Demand (optional: server can send executable code like JavaScript to the client). An API that follows all constraints is called RESTful.

Open this question on its own page
02

What are the main HTTP methods used in REST APIs and what do they do?

REST APIs use HTTP methods to indicate the desired action on a resource. GET retrieves a resource or collection — it must be safe (no side effects) and idempotent. POST creates a new resource or triggers an action — it is neither safe nor idempotent. PUT replaces a resource entirely with the provided representation — idempotent but not safe. PATCH applies a partial update to a resource — not required to be idempotent but often is. DELETE removes a resource — idempotent (deleting an already-deleted resource returns 404 or 204). HEAD is identical to GET but returns only headers (no body) — useful for checking resource existence or metadata. OPTIONS returns the HTTP methods supported by the endpoint — used by browsers in CORS preflight requests.

Open this question on its own page
03

What is idempotency and which HTTP methods are idempotent?

Idempotency means that making the same request multiple times produces the same result as making it once. This is critical for reliable communication over unreliable networks — if a request times out, the client can safely retry an idempotent request without fear of duplicating side effects. GET, HEAD, PUT, DELETE, and OPTIONS are idempotent. POST and PATCH are not inherently idempotent — sending the same POST twice typically creates two resources. However, you can make POST effectively idempotent by requiring an idempotency key header (e.g., Idempotency-Key: UUID), where the server deduplicates requests with the same key. Stripe's payment API is a well-known example that uses this pattern.

Open this question on its own page
04

What are the most important HTTP status codes in REST APIs?

HTTP status codes communicate the outcome of a request. 200 OK: success for GET/PUT/PATCH. 201 Created: resource created (POST), with a Location header pointing to the new resource. 204 No Content: success with no response body (DELETE). 400 Bad Request: client sent invalid data (missing required field, wrong type). 401 Unauthorized: authentication is required or credentials are invalid. 403 Forbidden: authenticated but not authorized to perform the action. 404 Not Found: resource does not exist. 409 Conflict: state conflict (duplicate email on creation). 422 Unprocessable Entity: request format is valid but contains semantic errors (validation failures). 429 Too Many Requests: rate limit exceeded. 500 Internal Server Error: unexpected server failure. 503 Service Unavailable: server temporarily unavailable (maintenance or overload).

Open this question on its own page
05

What are REST resource naming conventions?

Good resource naming makes an API intuitive and self-documenting. Use nouns, not verbs — resources are things, not actions: /users not /getUsers. Use plural nouns for collections: /posts, /orders. Use hierarchical nesting for relationships: /users/{id}/posts. Use lowercase with hyphens (kebab-case) for multi-word names: /blog-posts, not /blogPosts or /blog_posts. Keep URLs short and meaningful: avoid deep nesting beyond two levels. For actions that do not map cleanly to CRUD (e.g., "publish a post"), use a noun-based sub-resource: POST /posts/{id}/publish. Avoid file extensions (.json) — use the Accept header for content negotiation instead.

Open this question on its own page
06

What is the difference between path parameters and query parameters?

Path parameters are part of the URL path and identify a specific resource: GET /users/42 — here 42 is the path parameter identifying a unique user. They are required and define the resource's identity. Query parameters come after the ? in the URL and provide additional input: GET /users?role=admin&sort=createdAt&limit=20. They are optional and used for filtering, sorting, pagination, and search. The rule of thumb: use path parameters for resource identity and query parameters for modifying how a resource collection is returned. Example: GET /products/{id} (path) vs GET /products?category=electronics&maxPrice=500 (query).

Open this question on its own page
07

What are the most important HTTP request and response headers in REST APIs?

Key request headers: Content-Type declares the format of the request body (e.g., application/json). Accept declares the response format the client prefers. Authorization carries authentication credentials (e.g., Bearer {token}). Accept-Language specifies the preferred language for the response. Key response headers: Content-Type declares the response body format. Location provides the URL of a newly created resource (201 responses). X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset communicate rate limit status. ETag is a hash of the resource for cache validation. Cache-Control instructs caches how long to store the response. WWW-Authenticate indicates the authentication scheme required (on 401 responses).

Open this question on its own page
08

Why is JSON the standard response format for REST APIs?

JSON (JavaScript Object Notation) has become the de facto standard for REST API responses for several reasons. It is human-readable — easier to debug than XML or binary formats. It is lightweight with minimal syntax overhead compared to XML. It natively maps to data structures in virtually every programming language (objects, arrays, strings, numbers, booleans, null). JavaScript (the dominant web language) parses it natively with JSON.parse(). Most HTTP client libraries (axios, requests, fetch) handle JSON serialization/deserialization automatically. JSON also supports deeply nested structures that naturally represent domain objects. Always set Content-Type: application/json in responses and validate that the body is valid JSON before returning it.

Open this question on its own page
09

How do you map CRUD operations to HTTP methods?

CRUD operations map cleanly to HTTP methods and status codes in REST. Create: POST /resources with the new resource in the body — returns 201 Created with a Location header. Read (list): GET /resources returns a collection — returns 200 OK with an array in the body. Read (single): GET /resources/{id} returns one resource — returns 200 OK or 404 Not Found. Update (full replace): PUT /resources/{id} with the complete resource body — returns 200 OK or 204 No Content. Update (partial): PATCH /resources/{id} with only changed fields — returns 200 OK or 204 No Content. Delete: DELETE /resources/{id} — returns 204 No Content on success.

Open this question on its own page
10

What does stateless design mean in REST?

Stateless design means the server does not store any client session state between requests. Every request from the client must contain all the information needed to understand and process it — the server cannot rely on knowing what the client did in a previous request. Authentication tokens (JWT or API keys) are sent with every request in the Authorization header rather than stored in server-side sessions. This constraint has significant benefits: the server can scale horizontally easily (any server can handle any request since no session affinity is needed), fault tolerance improves (a server restart does not invalidate sessions), and load balancers can distribute requests freely. The tradeoff is larger request payloads since the client must repeatedly send credentials.

Open this question on its own page
11

What is an API endpoint?

An API endpoint is a specific URL where an API accepts requests and returns responses. It consists of the base URL plus a resource path: https://api.example.com/v1/users. Each endpoint represents a resource and, combined with an HTTP method, defines a specific operation. A well-designed API has a predictable set of endpoints following REST conventions — typically GET /resources (list), POST /resources (create), GET /resources/{id} (read), PUT /resources/{id} (update), and DELETE /resources/{id} (delete). Endpoints should be versioned (/v1/), documented, and stable — changes to existing endpoints require careful backwards-compatibility planning.

Open this question on its own page
12

What is the difference between HTTP and HTTPS?

HTTP (HyperText Transfer Protocol) transmits data in plain text, making it vulnerable to man-in-the-middle attacks where anyone on the network path can read or modify the data. HTTPS (HTTP Secure) wraps HTTP inside a TLS (Transport Layer Security) layer that encrypts all data in transit, authenticates the server's identity via a digital certificate, and ensures data integrity. All production REST APIs must use HTTPS. Sending API keys or JWT tokens over plain HTTP exposes them to interception. Modern browsers and HTTP clients warn against or block mixed-content HTTP requests. Certificate management is handled by services like Let's Encrypt (free) or commercial CAs, and cloud providers like AWS, Azure, and GCP include managed TLS termination.

Open this question on its own page
13

What is Basic Authentication in REST APIs?

Basic Authentication is the simplest HTTP authentication scheme. The client encodes the username and password as Base64(username:password) and sends it in the Authorization header: Authorization: Basic dXNlcjpwYXNzd29yZA==. It is simple to implement and supported natively by all HTTP clients. However, it has significant drawbacks: credentials are sent with every request (only safe over HTTPS), Base64 is not encryption (trivially reversible), and there is no built-in token expiry or revocation. Basic Auth is acceptable for internal or simple APIs, but for public APIs or user-facing applications, prefer API keys, OAuth 2.0, or JWT-based authentication. Always enforce HTTPS when using Basic Auth.

Open this question on its own page
14

What is the difference between RESTful and non-RESTful APIs?

A RESTful API adheres to REST's six architectural constraints — stateless, client-server, cacheable, uniform interface, layered system — and uses standard HTTP methods and status codes correctly. Resources are identified by URLs, operations are performed via HTTP verbs, and responses use standard media types (JSON, XML). A non-RESTful API (sometimes called RPC-style or REST-ish) may use HTTP as a transport but violates REST principles. Common violations include: using verbs in URLs (/getUser), using POST for all operations, returning 200 for errors, storing state on the server, or ignoring HTTP semantics. XML-RPC and SOAP are technically non-RESTful. GraphQL and gRPC are explicitly not REST — they are different paradigms. Most real-world APIs are pragmatic and not perfectly RESTful.

Open this question on its own page
15

What is API documentation and what is Swagger/OpenAPI?

API documentation describes how to use an API — its endpoints, request/response formats, authentication, error codes, and examples. It is essential for developer adoption and reduces integration time. OpenAPI Specification (OAS), formerly known as Swagger, is the industry-standard format for defining REST APIs in a machine-readable YAML or JSON file. An OpenAPI document defines all endpoints, parameters, request bodies, response schemas, security schemes, and examples. Tools built on OpenAPI include: Swagger UI (interactive browser-based API explorer), Postman (import OpenAPI to generate a collection), code generators (client SDKs in any language), and mock servers. Maintaining an OpenAPI spec alongside code ensures documentation stays accurate and enables automated testing and contract validation.

Open this question on its own page
16

What is the Accept-Language header and how is it used?

The Accept-Language request header indicates the client's preferred human language for the response. Example: Accept-Language: en-US,en;q=0.9,fr;q=0.8 — the client prefers American English, then any English, then French. The server uses this to return localized content: translated messages, locale-specific date formats, and currency symbols. APIs that support internationalization parse this header and return content in the preferred language. The q factor (quality value, 0.0–1.0) indicates preference priority. If the server does not support the requested language, it falls back to a default (usually English). This header enables the same API endpoint to serve content in multiple languages without requiring separate endpoints per locale.

Open this question on its own page
17

What is a base URL and how should it be structured?

The base URL is the common prefix shared by all endpoints in an API. A well-structured base URL looks like: https://api.example.com/v1. Best practices include using a dedicated subdomain (api.example.com instead of example.com/api) to allow independent scaling and routing. Include the API version in the base URL (/v1) so clients can target a specific version. Use HTTPS always — never expose APIs on plain HTTP in production. The base URL should be stable and not change — all versioning is handled through the version segment. For SDKs, configure the base URL as an environment variable so clients can point to dev/staging/production without code changes.

Open this question on its own page
18

What is the difference between a collection resource and a singleton resource?

A collection resource represents a group of resources of the same type and is addressed by a plural noun URL: /users. A GET request returns a list; POST creates a new item in the collection. A singleton resource represents a single, unique resource — either a specific item (/users/42) or a conceptually single entity (/account/settings for the currently authenticated user's settings). For singletons that are contextually unique, avoid requiring an ID: GET /me returns the current user's profile without needing to know the ID. The collection/singleton distinction maps cleanly to database table (collection) vs row (singleton) concepts and helps clients intuitively understand the API structure.

Open this question on its own page
19

What is content negotiation in REST APIs?

Content negotiation is the mechanism by which a client and server agree on the format of the response. The client sends an Accept header listing preferred media types: Accept: application/json, application/xml;q=0.9. The server selects the best matching format it supports and sets Content-Type in the response accordingly. If the server cannot satisfy the Accept header, it returns 406 Not Acceptable. Most modern APIs return only JSON and can ignore the Accept header, but supporting content negotiation is important for enterprise APIs serving multiple client types. Similarly, the client declares its request body format with Content-Type: application/json and the server responds with 415 Unsupported Media Type if it cannot process that format.

Open this question on its own page
20

What is a RESTful API's uniform interface constraint?

The uniform interface constraint is the central distinguishing feature of REST. It has four sub-constraints. Resource identification: resources are identified by stable URIs (e.g., /users/42) — the URI identifies the concept, not a specific representation. Manipulation through representations: clients interact with resources by sending representations (JSON bodies) — the server's internal implementation is hidden. Self-descriptive messages: each request/response includes enough metadata (Content-Type, Authorization, status code) to describe how to process it. HATEOAS: responses include links to related actions the client can take next. The uniform interface simplifies the overall system architecture by decoupling client from server and enabling each to evolve independently.

Open this question on its own page
Intermediate 20 questions

Practical knowledge for developers with hands-on experience.

01

What is HATEOAS and how is it implemented?

HATEOAS (Hypermedia as the Engine of Application State) is the highest level of REST maturity. It means API responses include hyperlinks that tell the client what actions are available next, removing the need for clients to have hardcoded knowledge of URL structures. Example: a response to GET /orders/42 might include links like { "self": "/orders/42", "cancel": "/orders/42/cancel", "payment": "/orders/42/payment" } — the client follows these links rather than constructing URLs. The HAL (Hypertext Application Language) and JSON:API formats standardize how links are embedded. While HATEOAS is the theoretically correct REST approach, it adds complexity and is rarely implemented fully in practice — most APIs are pragmatic and treat HATEOAS as optional.

Open this question on its own page
02

What are the main API versioning strategies in REST and what are their tradeoffs?

Three main versioning approaches exist. URL path versioning (/v1/users) is the most common and explicit — version is visible in the URL, easy to route and test, but "pollutes" the URL structure and requires clients to update base URLs. Header versioning (API-Version: 2 or Accept: application/vnd.myapi.v2+json) keeps URLs clean and is semantically correct (the URL identifies the resource, not the version), but it is harder to test in a browser and less visible. Query parameter versioning (/users?version=2) is easy to add but is non-standard and can interfere with caching. URL path versioning is recommended for most public APIs due to visibility and simplicity. Never change a published version — create a new one and run old and new in parallel until clients migrate.

Open this question on its own page
03

What are the pagination strategies in REST APIs?

Three main pagination strategies are used in REST. Page/offset pagination: GET /posts?page=3&limit=20 — simple to implement and understand but unstable with live data (inserting an item shifts all subsequent pages). Offset/limit pagination: GET /posts?offset=40&limit=20 — similar to page/limit but more flexible. Cursor-based (keyset) pagination: GET /posts?after=cursor123&limit=20 — the cursor is typically an encoded last-seen ID or timestamp. It is stable (insertions/deletions do not affect other pages) and performs better on large datasets (no OFFSET in SQL). The response should include pagination metadata: { "data": [...], "meta": { "total": 500, "next": "/posts?after=xyz", "hasMore": true } }. Cursor-based is preferred for large, frequently-changing datasets like social media feeds.

Open this question on its own page
04

What is rate limiting and how is it communicated in REST APIs?

Rate limiting restricts how many requests a client can make in a time window, protecting the API from abuse and ensuring fair usage. Common algorithms include token bucket (smooth burst tolerance), sliding window (accurate, no boundary spikes), and fixed window (simple but allows burst at window boundaries). Rate limit status is communicated via standard headers: X-RateLimit-Limit: 1000 (total allowed), X-RateLimit-Remaining: 42 (left in current window), X-RateLimit-Reset: 1609459200 (Unix timestamp when the window resets). When the limit is exceeded, return 429 Too Many Requests with a Retry-After header indicating seconds to wait. Apply different limits by tier (free vs paid), by endpoint (write operations cost more), and by IP for unauthenticated requests.

Open this question on its own page
05

How does HTTP caching work in REST APIs with ETag and Cache-Control?

HTTP caching reduces server load and latency. Cache-Control headers set caching policy: Cache-Control: public, max-age=3600 allows any cache to store the response for one hour. ETag is a hash of the response body (e.g., ETag: "abc123"). On subsequent requests, the client sends If-None-Match: "abc123"; if the resource has not changed, the server returns 304 Not Modified (no body), saving bandwidth. Last-Modified is a timestamp alternative to ETag, used with If-Modified-Since. For user-specific data, use Cache-Control: private to prevent shared caches from storing it. Cache-Control: no-store prevents all caching (for sensitive data). Proper caching can dramatically reduce API load — up to 90% of traffic can be served from cache for read-heavy APIs.

Open this question on its own page
06

What are the OAuth 2.0 grant types and when do you use each?

OAuth 2.0 has four main grant types. Authorization Code: the user authorizes via a browser redirect, the server returns an authorization code, which the backend exchanges for tokens. Safest — tokens never exposed to the browser. Authorization Code + PKCE (Proof Key for Code Exchange): same as above but for public clients (SPAs, mobile apps) that cannot keep a client secret — PKCE prevents code interception attacks. Now recommended for all clients. Client Credentials: machine-to-machine authentication where there is no user — the client authenticates directly with client_id and client_secret to get an access token. Used for backend services and cron jobs. Implicit (deprecated): returned tokens directly to the browser — now replaced by Authorization Code + PKCE. Avoid implicit flow in new implementations.

Open this question on its own page
07

What is JWT and how is it validated in REST APIs?

A JWT (JSON Web Token) consists of three Base64URL-encoded parts separated by dots: header.payload.signature. The header specifies the algorithm (e.g., HS256, RS256). The payload contains claims: standard ones (sub for subject/user ID, exp for expiry, iat for issued-at) and custom ones (role, permissions). The signature is computed with a secret (HS256) or private key (RS256), allowing verification without a database lookup. Validation steps: verify the signature, check exp has not passed, check iss (issuer) and aud (audience) if set. JWTs are stateless — revocation requires short expiry times plus a refresh token mechanism or a token blacklist. Never store sensitive data in the payload — it is only encoded, not encrypted.

Open this question on its own page
08

What is the difference between API keys and OAuth 2.0?

API keys are static tokens issued to an application, sent in headers (X-API-Key: abc123) or query params. They are simple to implement and ideal for server-to-server communication, but they cannot represent a specific user's permissions, do not expire automatically, and are dangerous if leaked (no built-in revocation). OAuth 2.0 is a full authorization framework that issues short-lived access tokens and refresh tokens. It supports delegated authorization (a user granting an app access to their data without sharing their password), scopes for fine-grained permissions, token expiry and revocation, and multiple client types. Use API keys for simple internal integrations or when a user context is not needed. Use OAuth 2.0 for user-delegated access, third-party integrations, and any scenario requiring fine-grained authorization.

Open this question on its own page
09

What is CORS and how does a preflight request work?

CORS (Cross-Origin Resource Sharing) is a browser security mechanism that restricts which origins (domain+port+protocol) can make requests to an API from JavaScript. When a browser script on https://app.com calls https://api.example.com, it is a cross-origin request. For "non-simple" requests (non-GET/POST, custom headers, or JSON body), the browser first sends an OPTIONS preflight request asking the server if the actual request is allowed. The server responds with CORS headers: Access-Control-Allow-Origin: https://app.com, Access-Control-Allow-Methods: GET, POST, PUT, Access-Control-Allow-Headers: Authorization, Content-Type. If the preflight succeeds, the browser sends the actual request. Access-Control-Allow-Credentials: true is required if the request includes cookies. Avoid Access-Control-Allow-Origin: * with credentials.

Open this question on its own page
10

What is the RFC 7807 Problem Details format for REST API errors?

RFC 7807 Problem Details defines a standardized JSON format for HTTP API error responses, avoiding inconsistent error structures across APIs. The media type is application/problem+json. A Problem Details response looks like: { "type": "https://example.com/errors/validation-error", "title": "Validation Failed", "status": 422, "detail": "The 'email' field must be a valid email address.", "instance": "/api/users" }. Fields: type (URI identifying the problem type, links to documentation), title (human-readable summary), status (HTTP status code), detail (human-readable explanation of the specific occurrence), instance (URI of the specific request). Additional fields can be added for machine-readable error details (field-level validation errors, error codes). Standardizing error formats dramatically reduces client-side error handling complexity.

Open this question on its own page
11

What is the difference between PUT and PATCH?

PUT replaces a resource entirely with the provided representation. If you send PUT /users/42 with { "name": "Alice" }, all fields not included in the body are set to null/default. PUT requires the client to send the complete resource — you must first GET the resource, modify it, then PUT the full updated version. PATCH applies a partial update — only the fields included in the body are changed. PATCH /users/42 with { "name": "Alice" } changes only the name; all other fields remain unchanged. PATCH is more bandwidth-efficient for large resources where only a small field changes. JSON Patch (RFC 6902) formalizes PATCH operations: [{ "op": "replace", "path": "/name", "value": "Alice" }]. In practice, PATCH is more commonly used for partial updates in modern APIs.

Open this question on its own page
12

How do you handle long-running async operations in REST APIs?

Long-running operations (video processing, report generation, batch imports) should not block the HTTP connection. The accepted pattern is the 202 Accepted response: the API immediately returns 202 with a job ID and a link to poll status: { "jobId": "abc123", "statusUrl": "/jobs/abc123" }. The client polls GET /jobs/abc123, which returns the job status (pending, processing, completed, failed). On completion, the response includes a link to the result: { "status": "completed", "resultUrl": "/reports/xyz" }. The alternative to polling is webhooks — the client registers a callback URL and the server POSTs to it when the job finishes. Webhooks are more efficient than polling but require the client to expose a public HTTPS endpoint. A third option is Server-Sent Events (SSE) for streaming progress updates.

Open this question on its own page
13

What are the best practices for filtering, sorting, and searching in REST APIs?

Use query parameters for all three. For filtering: GET /products?category=electronics&minPrice=100&maxPrice=500&inStock=true. Use consistent parameter naming — avoid ambiguous operators. Complex filters can use a filter language: filter=price:gt:100,status:eq:active. For sorting: GET /products?sort=price&order=asc or support multi-field sort: sort=-createdAt,name (prefix - for descending). For searching: GET /products?search=wireless+headphones for full-text search. Separate search from filtering — search is fuzzy and ranked, filtering is exact. Always validate and sanitize filter parameters to prevent injection. Document all supported filter fields and sort fields in the OpenAPI spec. For complex queries, consider a dedicated search endpoint or GraphQL.

Open this question on its own page
14

What is an API gateway and what responsibilities does it handle?

An API gateway is a server that acts as the single entry point for all client requests, routing them to appropriate backend services. It handles cross-cutting concerns so individual services do not have to: Authentication and authorization (validate JWTs or API keys before requests reach services), rate limiting (enforce per-client limits centrally), request routing (route /v1/users to the Users service, /v1/orders to the Orders service), SSL termination (handle HTTPS, forward as HTTP internally), load balancing (distribute traffic across service instances), request/response transformation (adapt legacy APIs to REST conventions), logging and tracing (add correlation IDs, emit metrics), and caching (cache common responses). Popular API gateways include AWS API Gateway, Kong, Nginx, and Apigee.

Open this question on its own page
15

How do webhooks work and what are the delivery guarantees?

Webhooks are reverse APIs — instead of the client polling for updates, the server pushes HTTP POST requests to a client-registered callback URL when events occur. Example: GitHub sends a webhook POST to your CI server when a commit is pushed. The client registers the webhook URL via the API: POST /webhooks { "url": "https://client.com/hooks", "events": ["order.created", "payment.completed"] }. Delivery challenges: the client endpoint may be down — use an at-least-once delivery strategy with exponential backoff retries (immediate, then 5m, 30m, 2h, 24h). Include a webhook signature header (HMAC-SHA256 of the payload using a shared secret) so clients can verify authenticity. Clients should respond quickly with 200 OK and process asynchronously — a timeout on the response triggers a retry. Stripe, GitHub, and Twilio all follow this pattern.

Open this question on its own page
16

What is an idempotency key for POST requests?

An idempotency key makes non-idempotent POST requests safe to retry. The client generates a unique key (UUID) and sends it as a header: Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000. The server stores the key and its associated response. If the same key arrives again (due to a network retry), the server returns the stored response instead of processing the request again. This prevents duplicate payments, double-sends, or duplicate resource creation when requests time out and the client cannot tell if the server processed the request. The stored response is typically retained for 24 hours. Stripe's payment API uses idempotency keys extensively — creating a charge is idempotent if you use the same key, preventing customers from being charged twice due to network timeouts.

Open this question on its own page
17

What is the OpenAPI 3.0 specification structure?

An OpenAPI 3.0 document is a YAML or JSON file with these top-level sections. openapi: "3.0.3" declares the spec version. info contains the API title, version, description, contact, and license. servers lists the base URLs (dev, staging, production). paths is the core section — each path key (/users/{id}) has operation objects (get, post, put, delete) with parameters, request bodies, responses, security requirements, and tags. components holds reusable definitions: schemas (data models), responses (common response objects), parameters (reusable params), securitySchemes (Bearer JWT, API key, OAuth2 flows). security sets global security requirements. tags groups operations for documentation organization. Tools like Swagger UI render this into interactive documentation automatically.

Open this question on its own page
18

What are the best practices for designing API SDKs?

A well-designed API SDK dramatically improves developer experience. Key principles: Idiomatic code — follow language conventions of the target (e.g., snake_case in Python, camelCase in JavaScript, fluent builder patterns in Java). Authentication abstraction — accept API keys or OAuth tokens in the constructor, not per request. Automatic retry with exponential backoff for 429 and 5xx errors. Sensible defaults with full configurability (timeouts, base URL, logging). Strongly-typed request/response models — auto-generated from the OpenAPI spec ensures the SDK stays in sync with the API. Comprehensive error types that wrap HTTP errors into domain-specific exceptions. Pagination helpers that handle cursor traversal transparently. Versioned releases with a changelog. SDK generation tools like Speakeasy or OpenAPI Generator produce multi-language SDKs directly from the OpenAPI spec.

Open this question on its own page
19

How do you design REST APIs for bulk operations?

Bulk operations allow clients to create, update, or delete multiple resources in a single request, reducing round trips. Common approaches: Batch create: POST /users/batch with an array of user objects in the body — return 207 Multi-Status with per-item success/failure. Bulk update: PATCH /orders with { "ids": [1,2,3], "status": "shipped" } — update a field on multiple resources. Bulk delete: DELETE /users with { "ids": [1,2,3] } in the body (non-standard but pragmatic). Return a 207 Multi-Status response that details the outcome per item: success, partial failure, or total failure. Set a reasonable limit on batch size (e.g., 100 items per request) to prevent resource exhaustion. Process items transactionally (all or nothing) or individually (return per-item errors) based on business requirements.

Open this question on its own page
20

What is sparse fieldsets and response compression in REST API performance?

Sparse fieldsets let clients request only the fields they need, similar to GraphQL's field selection: GET /users?fields=id,name,email. This reduces payload size, database column fetching, and JSON serialization time. The JSON:API specification formalizes this with the fields[type] parameter. Response compression reduces bandwidth by compressing response bodies. The client sends Accept-Encoding: gzip, br and the server compresses the response body, returning Content-Encoding: gzip. Gzip provides ~70-90% size reduction for JSON. Brotli (br) achieves better compression ratios. Enable compression at the web server or API gateway level (Nginx, AWS CloudFront) so application code is not burdened. Together, sparse fieldsets and compression are especially impactful for mobile clients on metered connections where data transfer directly affects user cost.

Open this question on its own page
Advanced 10 questions

Deep expertise questions for senior and lead roles.

01

What is the Richardson Maturity Model and what are its four levels?

The Richardson Maturity Model (RMM), introduced by Leonard Richardson, describes the degree to which an API adheres to REST principles in four levels. Level 0 (The Swamp of POX): HTTP is used as a tunnel for RPC — all calls go to a single endpoint via POST with an XML or JSON body specifying the action. SOAP APIs are at Level 0. Level 1 (Resources): individual resources have their own URLs (/users/42) but only one HTTP method (usually POST) is used for all operations. Level 2 (HTTP Verbs): correct HTTP methods (GET, POST, PUT, DELETE) are used along with meaningful status codes. Most well-designed REST APIs today are at Level 2. Level 3 (Hypermedia Controls / HATEOAS): responses include hyperlinks to related actions, making the API self-descriptive. The client navigates the API by following links rather than constructing URLs. Level 3 is the true REST as defined by Fielding and is rarely implemented fully in practice, but Level 2 is widely accepted as "RESTful".

Open this question on its own page
02

How do you decide between REST, GraphQL, and gRPC for a new API?

The choice depends on use case, team, and performance requirements. REST is best for: public APIs where discoverability and caching matter, simple CRUD resources, teams familiar with HTTP semantics, and clients that benefit from CDN caching. REST's uniform interface is universally understood. GraphQL is best for: complex data graphs with many related entities, mobile clients that need to minimize over-fetching, multiple different clients (web, mobile, TV) with different data needs, and developer portals where schema introspection aids exploration. Its flexibility comes with increased complexity (N+1 problem, authorization complexity, no HTTP caching). gRPC is best for: internal microservice-to-microservice communication where performance is critical, strongly-typed contracts with generated client/server code, streaming large datasets, and polyglot environments. gRPC uses Protocol Buffers (binary, ~10x faster than JSON), HTTP/2 multiplexing, and bi-directional streaming, but is not natively supported by browsers without a proxy layer. In practice, many systems combine all three: gRPC internally, GraphQL for the BFF (Backend for Frontend), and REST for the public API.

Open this question on its own page
03

What is consumer-driven contract testing with Pact?

Consumer-driven contract testing is a testing approach where the API consumer (client) defines the contract — the expected requests and responses — and the provider (server) verifies that it meets those expectations. Pact is the most popular framework for this. The consumer writes a Pact test that defines the interactions: "when I send GET /users/1, I expect a response with status 200 and body { id: 1, name: String }". Pact generates a contract file (the "pact"). The provider then runs a verification step that plays back all consumer pacts against the real API and confirms it satisfies each one. This catches breaking changes before deployment — the provider CI fails if any consumer contract is broken. Pact Broker stores and versions pacts, enabling teams to track compatibility across versions. Unlike end-to-end tests, contract tests are fast (no running full stack), isolated, and pinpoint exactly which consumer is affected by a change.

Open this question on its own page
04

What are backward compatibility strategies and Postel's Law in REST API evolution?

Postel's Law (the Robustness Principle): "Be conservative in what you send, be liberal in what you accept." For APIs: ignore unknown request fields gracefully (do not reject requests with extra fields), but always return well-formed, conservative responses. Key backward-compatible (non-breaking) changes: adding new optional fields to responses (clients ignore unknown fields), adding new optional request parameters with sensible defaults, adding new endpoints, and loosening validation. Breaking changes: removing fields, renaming fields, changing field types, making optional fields required, or changing URL structure. Strategies to avoid breaking changes: use additive-only changes for the life of a version, use deprecation headers (Deprecation: true, Sunset: Sat, 01 Jan 2027 00:00:00 GMT) to warn clients before removal, and use expansion patterns — add new fields alongside old ones (amount and amountInCents) during transition. Monitor field-level usage analytics to know when it is safe to remove deprecated fields.

Open this question on its own page
05

What is event-driven REST and when do you use webhooks vs SSE vs WebSockets?

Three push mechanisms serve different needs. Webhooks: the server POSTs to a client-registered URL when events occur. Best for: event notifications where the client does not need to be actively connected, server-to-server integrations (Stripe, GitHub, Shopify). Drawbacks: clients must expose a public endpoint, and delivery failures need retry logic. Server-Sent Events (SSE): the server streams newline-delimited JSON events over a long-lived HTTP connection (Content-Type: text/event-stream). Best for: one-way server-to-browser push (live feeds, progress bars, notifications). SSE works over standard HTTP/1.1, is automatically reconnecting, and is natively supported by browsers via EventSource. Drawback: HTTP/1.1 limits to 6 connections per domain. WebSockets: full-duplex bidirectional communication over a persistent TCP connection. Best for: real-time collaborative applications (live chat, multiplayer games, collaborative editing) where both client and server need to send messages. Drawback: more complex infrastructure (requires WebSocket-aware load balancers and sticky sessions or pub/sub backend).

Open this question on its own page
06

How do you optimize REST API performance — N+1 avoidance, sparse fieldsets, and response compression?

REST API performance optimization operates at multiple layers. N+1 query avoidance: use eager loading (SQL JOINs or ORM includes) when a list endpoint triggers per-item queries. For GET /posts that includes author data, load all posts then all authors in two queries instead of N+1. Sparse fieldsets (?fields=id,name): select only requested columns in SQL, skip serialization of omitted fields, reducing CPU and bandwidth. Response compression (gzip/brotli): enable at the reverse proxy layer — JSON compresses 70-90%. HTTP caching: set ETag and Cache-Control headers; responses served from CDN cache cost near-zero compute. Connection pooling: reuse database connections rather than creating new ones per request. Async processing: move expensive writes to background queues (Redis Queue, SQS), returning 202 immediately. Pagination: never return unbounded lists — enforce maximum page sizes. Database indexes: ensure all filter/sort columns are indexed. Response time budgeting: set p99 latency targets (e.g., 200ms) and measure per-endpoint with APM tools like Datadog or New Relic.

Open this question on its own page
07

What does an API governance and design review process look like at scale?

API governance ensures consistency, stability, and quality across all APIs in an organization. The process starts with an API design guide — a document codifying naming conventions, versioning policies, error formats, pagination patterns, authentication standards, and deprecation lifecycle. New APIs go through an API design review (sometimes called an API council) before implementation: the schema is reviewed for consistency with existing APIs, naming correctness, security implications, and forward compatibility. Linting tools like Spectral automate style enforcement by running rules against the OpenAPI spec in CI — failing pipelines if conventions are violated. A schema registry (e.g., Stoplight, SwaggerHub) stores all API specifications with version history. Breaking change detection runs in CI using tools like openapi-diff or Optic. Usage analytics from the API gateway track which endpoints, fields, and versions clients use, informing deprecation decisions. The goal is a consistent developer experience across all APIs in the organization regardless of which team built them.

Open this question on its own page
08

What is the REST API deprecation lifecycle management?

A structured deprecation lifecycle prevents breaking clients while allowing APIs to evolve. The process: 1. Mark deprecated: add the Deprecation: true header and Sunset: {date} header to responses, and document with a deprecation notice in the OpenAPI spec (the deprecated: true field on operation or parameter). 2. Communicate: notify API consumers via email, developer portal announcements, and changelog. Provide migration documentation with the new endpoint or field. 3. Monitor usage: use API gateway analytics to track deprecated endpoint/field usage by client. Do not remove until usage drops to zero. 4. Set sunset date: give clients a reasonable migration window — minimum 6-12 months for major API changes, longer for large enterprise clients. 5. Enforce sunset: on the sunset date, return 410 Gone instead of processing the request. The Link header can point to the replacement: Link: <https://api.example.com/v2/users>; rel="successor-version". Automated tooling should alert clients whose usage drops to zero of an upcoming sunset to validate the migration is complete.

Open this question on its own page
09

What are the security hardening measures for REST APIs — injection, mass assignment, BOLA/IDOR?

REST APIs face several critical security vulnerabilities. Injection: always use parameterized queries or ORMs — never concatenate user input into SQL, NoSQL queries, or shell commands. Validate and sanitize all inputs. Use an allowlist of accepted values rather than a denylist. Mass assignment (insecure direct object assignment): never bind request bodies directly to database models without filtering allowed fields. Explicitly whitelist which fields a client can set — prevent clients from setting isAdmin: true or balance: 1000000 in a user update. BOLA (Broken Object Level Authorization), also called IDOR (Insecure Direct Object Reference): verify that the authenticated user is authorized to access the specific resource they are requesting. GET /invoices/42 must check that invoice 42 belongs to the current user, not just that the user is authenticated. BOLA is the #1 API vulnerability in the OWASP API Security Top 10. Additional hardening: enforce HTTPS everywhere, validate Content-Type to prevent MIME confusion, implement rate limiting per user and per IP, use security headers (Strict-Transport-Security, X-Content-Type-Options), rotate API keys regularly, and log all access with correlation IDs for audit trails.

Open this question on its own page
10

How do you design a REST API specifically for mobile-first clients considering bandwidth and offline-first use cases?

Mobile clients have unique constraints that shape API design. Minimize payload size: implement sparse fieldsets (?fields=id,name), use gzip/brotli compression (mandatory for mobile), and return only necessary nested data. Consider a BFF (Backend for Frontend) layer that aggregates multiple service calls into one mobile-optimized response, reducing round trips. Reduce round trips: design composite endpoints that return all data a screen needs in one call (GET /home-feed returns posts, stories, and user info together). Support conditional requests (ETags) so the client can check for changes without re-downloading unchanged data. For offline-first: design APIs around a sync model — each resource has an updatedAt timestamp, and clients send GET /posts?updatedSince=2024-01-01T00:00:00Z to fetch only changes. Use conflict resolution strategies (last-write-wins, version vectors, or server authority) for data modified offline. Support delta sync — a dedicated /sync endpoint returns only changed/deleted items since the last sync token. Idempotency keys on POST requests let mobile clients safely retry mutations when offline actions are replayed on reconnection. Optimize for slow networks by supporting request priority hints and limiting default page sizes to 20-50 items.

Open this question on its own page
Back to All Topics 50 questions total