API Interview Prep Guide
Complete Beginner Edition — The most commonly asked API questions in system design and backend interviews
Each question includes a clear answer, key points to mention, and what not to say. Whether you're preparing for your first backend role or brushing up before a system design round, this guide covers what interviewers actually test.
Contents
An API (Application Programming Interface) is a contract that allows two systems to communicate. It defines what requests can be made, how to make them, and what responses to expect. In web development, this typically means a server exposing endpoints over HTTP that clients can call to read or manipulate data.
Key points to mention
- It's a contract between client and server
- Abstracts internal implementation — clients don't need to know how data is stored
- Enables reusability (e.g. Stripe, Google Maps, Twilio)
"It's just a URL you call to get data" — too vague and shows surface-level understanding.
REST (Representational State Transfer) is an architectural style for designing APIs. A RESTful API follows these constraints:
/users/42), not actions (/getUser)
Key points to mention
- Statelessness is the most important constraint — enables horizontal scaling
- Use nouns in URLs, not verbs:
/ordersnot/createOrder - HTTP methods express the action, not the URL
Calling the operation multiple times produces the same result as calling it once. Critical for safe retries over unreliable networks.
GET and DELETE are idempotent. POST is not — calling it twice creates two resources. Interviewers love this distinction.
"You're not logged in" = 401. "You're logged in but can't do this" = 403. Interviewers ask this constantly.
Versioning prevents breaking existing clients when you make changes. Three common strategies:
Most common. Visible and simple.
GET /v1/users GET /v2/users
Cleaner URLs, harder to test in browser.
GET /users API-Version: 2
Easy but can clutter query strings.
GET /users?version=2
Never remove or change existing fields in a version — only add. When breaking changes are needed, create a new version. Support old versions for a deprecation period (usually 6–12 months).
GET /posts?page=3&limit=20
- Easy to implement
- Can jump to any page
- Breaks when items inserted/deleted mid-pagination
Best for: admin panels, reports, page jumps
GET /posts?cursor=eyJpZ&limit=20
- Stable even when data changes
- Cursor = opaque base64 token
- Can't jump to arbitrary pages
Best for: real-time feeds, large datasets, infinite scroll
Always return structured, consistent error responses — not just an HTTP status code:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "field": "email", "issue": "Invalid email format" }
],
"request_id": "req_abc123"
}
}
Key principles
- Use correct HTTP status codes — never return 200 with an error body
- Include a machine-readable
codefor programmatic handling - Include a human-readable
message - Include a
request_idfor traceability in logs - For validation errors, list all failing fields — not just the first one
- Simple random string in a header:
X-API-Key: sk_live_abc123 - Good for server-to-server and developer APIs
- No user context, no expiry by default
Use for: developer-facing APIs, service-to-service
- Three parts:
header.payload.signature - Stateless — server verifies signature without a DB lookup
- Sent as:
Authorization: Bearer eyJhbG... - Contains claims: user_id, role, expiry
- Can't be invalidated before expiry without a blocklist
Use for: user authentication in your own system
- For third-party access: "Login with Google", "Connect Spotify"
- Issues access tokens + refresh tokens
- User grants your app permission to access their data on another service
Use for: when your app needs access to a user's data on another platform
"Proving who you are"
Validating the JWT token or API key. "I am Alice."
"Determining what you can do"
Checking if that user/role has permission for this action. "Alice can read but not delete."
Rate limiting protects your API from abuse and ensures fair usage. The algorithm you choose depends on your tolerance for burst traffic.
Bucket holds N tokens, refills at fixed rate. Allows bursting up to bucket size. Most commonly used — Stripe and AWS use this.
Count requests per minute. Simple but has an edge case: 1000 req at 0:59 + 1000 req at 1:01 = 2000 requests in 2 seconds.
Rolling time window — fixes the fixed-window edge case. More accurate, slightly more memory required.
Implementation details
- Store counters in Redis with TTL
- Key by
user_idor IP address - Return
429 Too Many Requestswhen exceeded
Return these response headers so clients can self-throttle:
X-RateLimit-Remaining: 723
X-RateLimit-Reset: 1735689600
Retry-After: 30
An operation is idempotent if calling it multiple times has the same effect as calling it once.
Networks fail. Clients retry. Without idempotency, retries can cause duplicate payments, duplicate orders, and duplicate emails sent to customers.
Idempotency keys (used by Stripe) — client generates a unique key per operation:
POST /payments Idempotency-Key: a8098c1a-f86e-11da-bd1a-00112444be1e { "amount": 100, "currency": "USD" }
Server stores the key and response. If the same key arrives again, returns the stored response instead of processing again. Client can safely retry after a network failure.
A pattern that prevents cascading failures when a downstream service is slow or down.
Normal operation. Requests flow through. Failures are counted.
Service is failing. Requests fail immediately without calling downstream.
After a timeout, one test request is allowed. Success → CLOSED. Failure → OPEN.
Without a circuit breaker, a slow downstream service causes all your threads to block waiting for it — eventually exhausting your thread pool and crashing your service too. The circuit breaker cuts the damage fast.
Cross-Origin Resource Sharing. A browser security policy that blocks requests from a different domain unless the server explicitly allows it via headers like Access-Control-Allow-Origin.
REST has multiple endpoints with fixed data shapes. GraphQL has one endpoint; the client specifies exactly what data it needs. GraphQL avoids over-fetching and under-fetching but adds query complexity.
A single entry point for all API requests. Handles cross-cutting concerns: authentication, rate limiting, routing, SSL termination, logging. Examples: AWS API Gateway, Kong, NGINX.
The reverse of an API call. Instead of polling for updates, the server pushes events to your URL when something happens. Used by Stripe (payment events), GitHub (push events), etc.
A high-performance RPC framework using Protocol Buffers instead of JSON. Faster and more efficient than REST. Primarily used for internal microservice communication.
Think out loud. Interviewers want to hear your reasoning process, not just the final answer.
Ask clarifying questions. "Is this a public API or internal? What's the expected scale?" Shows senior thinking.
Start simple, then optimize. Design the basic version first, then layer on caching, rate limiting, pagination, etc.
Use the right vocabulary. Idempotency, stateless, pagination, circuit breaker — drop these naturally to signal depth.
Draw it out. For system design, a quick diagram of client → API gateway → service → DB goes a long way.
Know trade-offs. For every choice, be ready to say what you're giving up. "Cursor pagination is more stable but you can't jump to page 50."
