System Design API Design for Interviews: Contracts, Idempotency, and Pagination
Why API Design Is an Architecture Decision, Not a Syntax Exercise
In system design interviews, API design is not a list of HTTP verbs.
π― System Scenario & Requirements
System Goal
In system design interviews, API design is not a list of HTTP verbs.
Actors & Components
- Edge Traffic Ingress
- Stateless Microservices
- Datastore Infrastructure
- API Gateway
- Domain Service
- Redis Cache
- Transactional DB
Functional Requirements
- TLDR: In system design interviews, API design is not a list of HTTP verbs.
- It is a contract strategy: clear resource boundaries, stable request and response shapes, pagination, idempotency, error semantics, and versioning decisions that survive scale and failures.
- TLDR : Good API design reduces ambiguity for clients and prevents operational incidents when traffic grows.
Constraints & Assumptions
- Pattern 1: Resource-first endpoint design Instead of action-heavy endpoints like /createOrder , design around resources: - POST /orders - GET /orders/{order id} - GET /orders?customer id=...
- This keeps semantics predictable and easier to evolve.
- The best interview answer names at least one failure mode and one mitigation tied to API contract design.
β‘ Execution Stages & Decision Trace
Stage 1 β The API Contract Checklist You Should Apply in Every Interview
You can use a reusable checklist to keep API design systematic.
Define the resource model and identifiers.
Deep Dive
Scenario context
In system design interviews, API design is not a list of HTTP verbs. It is a contract strategy: clear resource boundaries, stable request and response shapes, pagination, idempotency, error semantics, and versioning decisions that survive scale and failures.
TLDR: Good API design reduces ambiguity for clients and prevents operational incidents when traffic grows.
In 2015, Stripe renamed the amount field toβ¦
This walkthrough focuses on Why API Design Is an Architecture Decision, Not a Syntax Exercise.
Before making a design choice, clarify:
- In 2015, Stripe renamed the amount field to amount cents in their charge response object β a clarification that made semantic sense internally.
- They had an active changelog and sent developer notifications.
- It still silently broke integrations for hundreds of third-party apps and payment platforms that parsed the response without strict field validation.
Concepts in play: system-design-hld-architectures, caching, git-internals-and-versioning, api-gateway
Stage 1 β The API Contract Checklist You Should Apply in Every Interview
- You can use a reusable checklist to keep API design systematic.
- Define the resource model and identifiers.
- Define the core operations per resource.
- Define request and response fields with explicit constraints.
Observable outcome: Define request and response fields with explicit constraints.
Stage 2 β Deep Dive: Translating Product Behavior Into Stable API Contracts
- API contracts are where product semantics become system boundaries.
- The Internals: Validation, Idempotency Store, and Backward Compatibility At runtime, robust API services usually implement these internal mechanisms: - Request validation layer for schema and semantic rules.
- Idempotency key store for safe retried writes.
- Serialization logic with explicit field defaults.
Observable outcome: - Serialization logic with explicit field defaults.
Stage 3 β API Lifecycle Flow From Client Request to Stable Response
- This flowchart captures the API contract philosophy: consistent validation, safe retries, and predictable responses.
- π REST API Request Lifecycle This sequence diagram traces the full lifecycle of a single REST API request from the client through the gateway and into the order service, highlighting the idempotency key check and the dβ¦
- The flow shows that the API gateway handles cross-cutting concerns (auth, rate limiting) while the service layer owns business validation and deduplication.
- Take away: every hop in this chain is an opportunity for failure, which is why idempotency at the service boundary prevents duplicate side effects from network retries.
flowchart TD
A[Client request] --> B[Schema and semantic validation]
B --> C{Idempotency key present?}
C -->|Yes| D[Check idempotency store]
D --> E{Seen before?}
E -->|Yes| F[Return previous response]
E -->|No| G[Execute business transaction]
C -->|No| G
G --> H[Persist result and emit event]
H --> I[Return structured response]
sequenceDiagram
participant C as Client
participant G as API Gateway
participant S as Order Service
participant DB as Database
C->>G: POST /v1/orders
G->>G: Auth and rate limit
G->>S: Forward request
S->>S: Validate schema
S->>DB: Check idempotency key
DB-->>S: Key not found
S->>DB: Write order record
DB-->>S: Commit OK
S-->>G: 201 Created
G-->>C: 201 + order_id
Observable outcome: Take away: every hop in this chain is an opportunity for failure, which is why idempotency at the service boundary prevents duplicate side effects from network retries.
Stage 4 β Real-World Applications: Payments, Feeds, and Internal Microservices
- Payments API: idempotency is non-negotiable because duplicate charges are business-critical incidents.
- Timeline/feed API: pagination and filtering matter most, because reads dominate and data size grows continuously.
- Internal microservice APIs: strict schemas, backward compatibility, and explicit error contracts reduce coordination cost between teams.
- Different domains stress different contract dimensions, but the checklist remains stable.
Observable outcome: Different domains stress different contract dimensions, but the checklist remains stable.
Stage 5 β Practical Example: Design a Create-and-List Orders API
- Suppose your interview prompt includes order creation and order history.
- You can propose: - POST /v1/orders with idempotency key.
- GET /v1/orders/{order id} for direct lookup.
- GET /v1/orders?customer id=...&cursor=...&limit=...
Observable outcome: - GET /v1/orders?customer id=...&cursor=...&limit=...
Stage 6 β Self-Documenting API Contracts: Design Approach
- A production REST API benefits from machine-readable contract documentation that stays in sync with the implementation.
- The key principle is that the contract specification should be derived from the code rather than maintained as a separate manual artifact β ensuring that the documented API always matches what the service actually does.
- In practice, this means annotating each endpoint with its intended summary, description, request parameters, and expected response codes at the point of definition.
- A create-order endpoint would declare that it accepts an idempotency key header, requires a valid request body, and returns 201 on success, 409 on duplicate key conflict, 429 on rate limit, and 422 on malformed input.
Observable outcome: A create-order endpoint would declare that it accepts an idempotency key header, requires a valid request body, and returns 201 on success, 409 on duplicate key conflict, 429 on rate limit, and 422 on malformed input.
End-to-end outcome
After working through the stages, you should be able to explain:
- API design is about long-lived contracts, not endpoint naming alone.
- Idempotency and pagination should be first-class concerns in write and list APIs.
Alternatives considered
Decision Guide: REST, RPC, and Contract Complexity
If you need protocol-level trade-offs, pair this post with System Design Protocols: REST, RPC, and TCP/UDP.
Failure and degraded modes
Pattern 1: Resource-first endpoint design
- Detection: Instead of action-heavy endpoints like /createOrder , design around resources: - POST /orders - GET /orders/{order id} - GET /orders?customer id=...
- User or operator impact: Instead of action-heavy endpoints like /createOrder , design around resources: - POST /orders - GET /orders/{order id} - GET /orders?customer id=...
Pattern 2: Idempotent writes for retry safety
- Detection: Client retries are inevitable during network failures.
- User or operator impact: Client retries are inevitable during network failures.
Pattern 3: Cursor-based pagination
- Detection: Offset pagination ( page=1000 ) becomes slow and unstable at scale.
- User or operator impact: Offset pagination ( page=1000 ) becomes slow and unstable at scale.
Pattern 4: Structured errors
- Detection: Avoid free-form strings as your main failure contract.
- User or operator impact: Avoid free-form strings as your main failure contract.
Trade-offs & Failure Modes: How API Contracts Break at Scale
- Detection: The best interview answer names at least one failure mode and one mitigation tied to API contract design.
- User or operator impact: The best interview answer names at least one failure mode and one mitigation tied to API contract design.
