The API-Design Walk-through

A repeatable seven-step recipe for an API-design interview: requirements, endpoints, data, constraints, auth, evolution, latency.

Concept Foundational
12 min read
interview walkthrough method framework recipe

Summary#

An API-design interview is 45-60 minutes. The interviewer says “design the API for X.” The candidates who do well are not the ones with the deepest individual answers — they are the ones who walk through the same seven steps every time, in the same order, in roughly the same number of minutes per step. The interviewer can follow along, ask deep questions inside any step, and still know there is structure they can return to.

The seven steps:

  1. Requirements — functional, non-functional, in-scope, out-of-scope.
  2. Endpoints — verbs, paths, status codes; the operation surface.
  3. Data — request and response schemas; the wire shape.
  4. Constraints — rate limits, payload sizes, idempotency, partial success.
  5. Auth — authentication, authorization, scopes, tokens.
  6. Evolution — versioning, deprecation, backward compatibility.
  7. Latency — round-trip budget, caching, async, batching.

Five to eight minutes per step, with the harder ones (endpoints, data, evolution) taking the larger slices. The interviewer will deep-dive into one or two; the rest are crisp.

This is the same idea as the system-design walk-through (clarify → estimate → interface → high-level → data model → detailed → evaluate) but specialised for an API. It is the meta-script. Every step is one of the building-block and security writeups elsewhere in this workbook — the walk-through is the order to apply them in.

Why it matters#

Three reasons the walk-through is worth committing to memory:

  • It is what senior interviewers are actually looking for. They are not testing whether you know REST vs gRPC trivia. They are testing whether you can take an open-ended prompt, structure it under time pressure, and produce a contract another engineer could implement. Structure is the signal.
  • It maps to what real API design teams do at companies that ship public APIs well. Stripe, AWS, GitHub, Twilio, Slack — their internal API-design reviews step through almost exactly this list. The walk-through is interview shorthand for production discipline.
  • It frees up your CPU for the parts that matter. If you know what comes next, you don’t burn cycles deciding which question to ask. You ask the next question. The cycles go into the answer.

The walk-through is not a script you read out. It is the default order of operations. A strong candidate visibly skips a step (“we covered scopes in step 5, so I’ll skip ahead”) or re-orders one (“auth has implications for the data model, let me pull that forward”). Knowing the order makes the deviation legible.

How it works#

Step 1 — Requirements (5-7 minutes)#

The opening of every API-design round. Two columns of questions:

Functional

  • Who is the consumer? Browser? Mobile? Partner backend? Internal service?
  • What are the top three or four operations the API must support?
  • What are the read:write ratios?
  • What are the entities (orders, users, files, messages)? How do they relate?

Non-functional

  • Expected QPS at peak? Day one vs year one?
  • Latency target — p50, p99?
  • Availability target — three nines, four nines?
  • Geographic distribution? Multi-region?
  • Compliance — PII, payments, healthcare, regulated data?

Then call out what is out of scope. “I’ll focus on the public REST surface; I’ll leave the admin/internal endpoints for after. I’ll cover OAuth at the auth step but not OIDC. Logging and metrics are out of scope unless you want me to come back to them.” Naming scope is what stops a 60-minute round from drifting.

A useful artefact at the end of step 1 is a one-paragraph problem statement the interviewer agrees with. Something like:

“We’re designing a REST API for partners to create and manage shipments. ~100 partner integrators, ~50 RPS peak, p99 < 300ms, four nines on POST and three nines on bulk reads. PII (recipient name, address) in payloads — TLS everywhere, scoped access tokens. Out of scope: webhooks, the admin console, the partner dashboard.”

Get that on the whiteboard. Anchor everything that follows to it.

Step 2 — Endpoints (8-10 minutes)#

Now name the operations. Pick a style (Web API Architectural Styles — Overview) — REST, GraphQL, gRPC — with a one-sentence reason. Then list endpoints.

For REST, the discipline is resource-shaped names with HTTP verbs:

POST /v1/shipments Create shipment → 201 Created
GET /v1/shipments/{id} Read a shipment → 200 / 404
PATCH /v1/shipments/{id} Partial update → 200 / 409 / 412
DELETE /v1/shipments/{id} Cancel shipment → 204 / 409
GET /v1/shipments List + filter + paginate → 200
POST /v1/shipments/{id}:cancel Custom verb (when CRUD doesn't fit)

For each endpoint, name:

  • The HTTP verb and path.
  • The success status code (200, 201, 202, 204).
  • The non-trivial error codes (409 Conflict if the shipment is already cancelled, 429 Too Many Requests, 422 Unprocessable Entity).
  • Whether the operation is idempotent.

For RPC, the same exercise produces method names: CreateShipment, GetShipment, CancelShipment. The shape is different; the questions are the same.

Step 3 — Data (6-8 minutes)#

Sketch one or two of the largest request/response payloads. JSON or Protobuf depending on the style. Annotate field types, required vs optional, units, and any non-obvious encoding (timestamps in ISO-8601 UTC, money as integer minor units, IDs as opaque strings).

POST /v1/shipments — request
{
"recipient": {
"name": "Ada Lovelace",
"address_line1": "1 Analytical Engine St",
"city": "London", "country": "GB", "postcode": "W1A 1AA"
},
"parcels": [
{ "weight_grams": 1200, "dimensions_cm": [30, 20, 10] }
],
"service_level": "express",
"ship_at": "2026-06-01T08:00:00Z"
}
POST /v1/shipments — 201 Created
{
"id": "shp_a3f9c2",
"status": "label_generated",
"tracking_url": "https://track.example.com/shp_a3f9c2",
"label_url": "https://labels.example.com/shp_a3f9c2.pdf",
"created_at": "2026-05-30T08:14:23Z",
"_links": {
"self": "/v1/shipments/shp_a3f9c2",
"cancel": "/v1/shipments/shp_a3f9c2:cancel"
}
}

Also sketch the error envelope — every endpoint uses the same shape:

Error envelope (consistent across all endpoints)
{
"error": {
"code": "invalid_postcode",
"message": "Postcode 'W1A' is not a complete UK postcode",
"param": "recipient.postcode",
"request_id": "req_2k8a9f"
}
}

Mention OpenAPI / Protobuf as the formal schema artefact. You’re not writing the spec on the whiteboard; you’re naming that it exists.

Step 4 — Constraints (5-7 minutes)#

The contract is more than fields — it is also what the API refuses to do. The constraint checklist:

  • Rate limits. Per-API-key (1000/min default), per-IP (defense-in-depth), per-operation (writes lower than reads). Surfaced via X-RateLimit-* headers and 429 Too Many Requests with Retry-After. See Rate Limiting.
  • Payload sizes. Max request body (e.g. 10 MiB); max response body; max array length per request (e.g. 100 items in batch endpoints).
  • Idempotency. Every POST that creates a resource requires an Idempotency-Key header. The server stores the key + response for 24 hours; duplicate keys return the cached response. See The Role of Idempotency in API Design.
  • Partial success / batch semantics. A POST /v1/shipments:batch with 50 shipments — does it succeed all-or-nothing, or per-item? Either is fine; document which.
  • Timeouts. Server-side request timeout (e.g. 30s); long-running operations move to async (return 202 Accepted with a job ID).
  • Concurrency control. If-Match: "<ETag>" on PATCH for optimistic locking; 409 Conflict on mismatch.
  • Replay protection. Combined with idempotency for writes; combined with short token TTLs for reads.

Each of these is a one-line decision in the API-design round. The interviewer is checking that you remember they exist.

Step 5 — Auth (5-7 minutes)#

Authentication answers who. Authorization answers what they can do. Both are mandatory; many candidates name only one.

Default stack for a partner-facing API in 2026:

  • Authentication: OAuth 2.0 Authorization Code + PKCE for browser-shaped clients; Client Credentials for server-to-server. Access tokens short-lived (1 hour); refresh tokens with rotation on use. OAuth 2 — The Authorization Framework has the protocol detail.
  • Authorization: scope-based. Tokens carry scopes (shipments.read, shipments.write, shipments.cancel). The resource server enforces per-endpoint.
  • Transport: TLS 1.3 everywhere; HSTS; no fallback to plaintext. See Transport Layer Security (TLS).
  • Beyond scopes for fine-grained ABAC: tenant ID in the token, resource ownership check in the handler, audit log on every authorization decision.

Internal-service-to-internal-service: mTLS plus a SPIFFE identity or a static API key in a header. The OAuth ceremony is overkill for traffic inside a single trust boundary.

For an exam-style answer, sketch:

Browser ──→ /authorize (OAuth Auth Code + PKCE)
←── code
──→ /token (code + verifier)
←── access_token (scope=shipments.write, exp=3600s)
──→ POST /v1/shipments
Authorization: Bearer <access_token>
Idempotency-Key: <uuid>

And mention what is not in scope at this step (MFA, account recovery, password reset) — these are identity-provider concerns, not API-design concerns.

Step 6 — Evolution (5-7 minutes)#

Every API is going to change. The question is whether that change breaks existing callers.

Additive changes are always safe:

  • New endpoints.
  • New optional request fields (default to safe behaviour).
  • New response fields (clients ignore what they don’t recognise — Postel’s law).
  • New enum values if clients were told to handle unknown values.

Breaking changes require either a version bump or a long deprecation cycle:

  • Removing or renaming a field.
  • Changing a field’s type (stringinteger).
  • Tightening a constraint (max_length 100 → 50).
  • Changing default behaviour.
  • Removing or renaming an endpoint.

Pick a versioning strategy and name it (API Versioning):

  • URL versioning (/v1/, /v2/) — most public APIs (Stripe, GitHub before 2022, AWS). Easy to reason about, requires running both versions in parallel.
  • Header versioning (Accept: application/vnd.example.v2+json or X-API-Version: 2026-05-30) — Stripe uses date-based pinning per API key. Cleaner URLs, harder for caller to discover.
  • GraphQL deprecation@deprecated on schema fields, no version numbers, evolve forever.

Then name the deprecation policy: how long do you support v1 after v2 ships? (Stripe: indefinitely. GitHub: 12 months. Twilio: 24 months. Pick a number you can commit to.) And the deprecation surface: Deprecation and Sunset HTTP headers, developer-dashboard warnings, email to API-key holders, eventual 410 Gone.

Step 7 — Latency (5-7 minutes)#

The last step in a strong walk-through, because it ties everything before it back to a number.

State the budget from step 1: “p99 < 300ms client-perceived.” Then walk the call:

client LB gateway auth app DB
│ ───────► │ ~10ms (network)
│ │ ────► │ ~1ms
│ │ │ ─────► │ ~5ms (token verify)
│ │ │ ◄───── │ ~1ms
│ │ │ ────────► │ ~1ms
│ │ │ │ ──────► │ ~15ms (DB read)
│ │ │ │ ◄────── │ ~1ms
│ │ │ │ ──────► │ ~25ms (DB write)
│ │ │ │ ◄────── │ ~1ms
│ │ │ ◄──────── │ ~1ms
│ │ ◄──── │ ~1ms
│ ◄─────── │ ~10ms (network)
──────────────────────────────────────────────────────── total ~72ms p50

Then name where the budget might blow up:

  • Cold starts — token-verification cache miss, JIT warmup. Mitigation: cache token introspection, keep-alive on downstream.
  • Cascading retries — see Managing Retries and The Circuit Breaker Pattern; without per-call timeouts shorter than parent’s, retry storms amplify exponentially.
  • N+1 fetches — the GraphQL or REST shape where a list endpoint forces a per-item lookup. Mitigation: batch endpoints, response expansion (?expand=parcels), DataLoader pattern.
  • Long-running operations — return 202 Accepted with a job ID; poll or webhook for completion. Trying to keep a sync call under 30s for a 60s operation is a losing game.

If you have a minute left, name caching: Cache-Control headers on read-heavy endpoints; CDN in front of public reads; ETag-conditional GETs. See Caching at Different Layers.

The closing sentence of a strong walk-through: “That’s the seven-step pass. Where do you want to dig in?” Hands control back; signals you have more depth in any of the boxes.

Variants and trade-offs#

The walk-through compresses or expands depending on the prompt:

Public partner API design (Stripe-style). Every step gets full weight. Versioning and idempotency are load-bearing. Auth involves OAuth + scopes. Documentation and developer experience matter. The 60-minute round comfortably fills.

Internal RPC service design. Requirements lean operational (latency, fan-out). Endpoints are gRPC methods. Versioning is co-deploy + Protobuf field evolution. Auth is mTLS + service mesh. Idempotency still matters; rate limits less so. Less ceremony per step; deeper on tracing and SLOs.

Prompt shapeSteps that lean heavySteps that compress
Public REST APIRequirements, endpoints, evolution, authLatency (if no SLA pressure)
Internal microserviceConstraints, latency, evolutionAuth (mTLS, one line)
Real-time / streamingEndpoints (WS/SSE), constraints, latencyVersioning (one channel)
Mobile-shaped GraphQLData (schema), latency, evolutionEndpoints (one URL)
File / large-payload APIData, constraints, latencyMost others

The order itself is rarely violated. Even in compressed rounds, you cover them in the same sequence — skipping is fine, re-ordering is suspicious.

When this is asked in interviews#

The walk-through itself is rarely the question; it is the answer template to almost any open-ended API-design question. Typical prompts:

  • “Design the API for a URL shortener.” → seven steps.
  • “Design Stripe’s payments API.” → seven steps, with auth and idempotency dominant.
  • “Design Slack’s message API.” → seven steps, with WebSockets/SSE in step 2 and fan-out latency in step 7.
  • “Design YouTube’s upload API.” → seven steps, with chunked upload and async processing in steps 3 and 7.

What the interviewer is grading:

  • Do you clarify before solving? Step 1 — non-negotiable.
  • Do you name the style with reasons? Step 2 — beginning of step.
  • Are your endpoints at business altitude? POST /shipments (good), POST /db_inserts/shipment_row (bad).
  • Is your error model uniform? Step 3 — the envelope question.
  • Do constraints appear at all? Step 4 — most candidates skip; senior signal to include.
  • Do you distinguish authn from authz? Step 5 — the two-word vocabulary.
  • Can you ship v2 without breaking v1? Step 6 — the lifecycle question.
  • Can you defend a latency budget? Step 7 — the ties-it-all-together question.

The single sentence that closes a strong round: “I designed for the integrator, not for the implementation.” The walk-through is the discipline that lets you say it credibly.

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.