CareerGuide 33 of 36
Career guide · Guide 33 of 36
Top 30 REST API Interview Questions and Answers
30 REST API interview questions with clear answers: HTTP methods and status codes, auth and OAuth, pagination, rate limits, retries, webhooks and API ingestion.
On this page
- Question list
- REST API basics
- 1. What is a REST API?
- 2. What are the main HTTP methods?
- 3. What do the main HTTP status codes mean?
- 4. What is the difference between PUT and PATCH?
- 5. What is the difference between POST and PUT?
- 6. What does stateless mean in REST?
- 7. What are path parameters and query parameters?
- 8. What are resources and endpoints?
- 9. Which HTTP methods are safe and which are idempotent?
- 10. Why do most REST APIs use JSON?
- Security, paging and reliability
- 11. How do you authenticate to a REST API?
- 12. How does OAuth 2.0 work?
- 13. What is a JWT?
- 14. What is pagination, and which kinds are there?
- 15. What is rate limiting, and how do you handle a 429?
- 16. How do you retry failed API calls safely?
- 17. What is an idempotency key?
- 18. What is the difference between webhooks and polling?
- 19. How do you secure a webhook?
- 20. How do you version a REST API?
- 21. How does caching work in REST APIs?
- 22. What is CORS?
- 23. REST vs GraphQL vs gRPC: when would you use each?
- 24. What is the difference between REST and SOAP?
- APIs in data engineering
- 25. How do you load data from a REST API into a data warehouse?
- 26. How do you load only new or changed records from an API?
- 27. What do you do when an API changes its response format?
- 28. How do you test code that calls an API?
- 29. How would you design a REST API for orders?
- 30. How should an API handle a long-running job?
These 30 REST API interview questions start with the basics every developer is asked: methods, status codes, PUT vs PATCH. They then cover what data engineers and forward deployed engineers are asked when an API is the data source: authentication, pagination, rate limits, retries, webhooks and loading API data into a warehouse. Each answer is short and plain, with a small example where it helps.
Question list
Show all 30 questions
- What is a REST API?
- What are the main HTTP methods?
- What do the main HTTP status codes mean?
- What is the difference between PUT and PATCH?
- What is the difference between POST and PUT?
- What does stateless mean in REST?
- What are path parameters and query parameters?
- What are resources and endpoints?
- Which HTTP methods are safe and which are idempotent?
- Why do most REST APIs use JSON?
- How do you authenticate to a REST API?
- How does OAuth 2.0 work?
- What is a JWT?
- What is pagination, and which kinds are there?
- What is rate limiting, and how do you handle a 429?
- How do you retry failed API calls safely?
- What is an idempotency key?
- What is the difference between webhooks and polling?
- How do you secure a webhook?
- How do you version a REST API?
- How does caching work in REST APIs?
- What is CORS?
- REST vs GraphQL vs gRPC: when would you use each?
- What is the difference between REST and SOAP?
- How do you load data from a REST API into a data warehouse?
- How do you load only new or changed records from an API?
- What do you do when an API changes its response format?
- How do you test code that calls an API?
- How would you design a REST API for orders?
- How should an API handle a long-running job?
REST API basics
1. What is a REST API?
A REST API lets programs read and change data over HTTP using a small set of rules. Data is organised as resources (orders, customers), each with its own URL such as /orders/42. You act on a resource with standard HTTP methods: GET to read, POST to create, PUT or PATCH to update, DELETE to remove. Each request carries everything the server needs, and the server replies with a status code and usually JSON.
REST stands for Representational State Transfer, a style described by Roy Fielding in 2000. In practice, “REST API” usually means “an HTTP API with resource URLs, standard methods and JSON”, even when it does not follow every rule of the original style.
2. What are the main HTTP methods?
| Method | Use | Example |
|---|---|---|
GET |
Read a resource or a list | GET /orders/42 |
POST |
Create a resource, or run an action | POST /orders |
PUT |
Replace a resource with the body you send | PUT /orders/42 |
PATCH |
Change some fields of a resource | PATCH /orders/42 |
DELETE |
Remove a resource | DELETE /orders/42 |
Two more appear in interviews: HEAD (like GET but headers only, useful to check if something changed) and OPTIONS (asks which methods are allowed, used by browsers for CORS checks).
3. What do the main HTTP status codes mean?
The first digit gives the group: 2xx success, 3xx redirect or “not modified”, 4xx the client made a mistake, 5xx the server failed.
- 200 OK: success with a body. 201 Created: a new resource was made. 204 No Content: success, nothing to return.
- 304 Not Modified: your cached copy is still current.
- 400 Bad Request: the request is malformed. 401 Unauthorized: not signed in or bad credentials. 403 Forbidden: signed in but not allowed. 404 Not Found. 409 Conflict: clashes with the current state. 422 Unprocessable Content: well-formed but invalid data. 429 Too Many Requests: rate limited.
- 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout.
The practical rule: retry 429 and most 5xx; do not retry other 4xx, because the same request will fail again.
4. What is the difference between PUT and PATCH?
PUT replaces the whole resource with what you send. PATCH changes only the fields you send.
If an order is {"status": "placed", "note": "gift"}:
PUT /orders/42with{"status": "shipped"}leaves an order with only a status; the note is gone.PATCH /orders/42with{"status": "shipped"}changes the status and keeps the note.
PUT is idempotent: sending it twice gives the same result. PATCH is not guaranteed to be, because a patch can say “add 1 to the count”. Use PATCH for partial updates from forms and apps, PUT when the client owns the full state.
5. What is the difference between POST and PUT?
POST sends data to a collection and the server decides the new resource’s URL: POST /orders returns 201 Created with Location: /orders/43. Sending it twice usually creates two orders, so POST is not idempotent.
PUT writes to a URL the client already knows: PUT /orders/43 creates or replaces that exact resource. Sending it twice leaves the same result, so PUT is idempotent.
This matters for retries. A retried PUT is safe; a retried POST can create duplicates unless the API supports idempotency keys (see question 17).
6. What does stateless mean in REST?
Stateless means the server keeps no memory of earlier requests from the client. Every request carries everything needed to handle it: the resource URL, the credentials (for example a token in the Authorization header) and the data.
The benefit is scale and reliability: any server behind a load balancer can answer any request, and a server can restart without losing a “session”. The cost is that some information, such as the token, is sent on every call. The data itself (orders in a database) is of course stored; stateless only refers to the conversation between client and server.
7. What are path parameters and query parameters?
- Path parameters identify a resource and are part of the URL path: in
/customers/7/orders/42,7and42say which customer and order. - Query parameters come after
?and change how a result is returned: filters, sorting, paging. For example,/orders?status=shipped&sort=-created_at&limit=100.
A good rule: if leaving it out changes which thing you mean, it belongs in the path; if it only narrows or shapes a list, it belongs in the query. Data you create or update goes in the request body, not the URL, and secrets never go in the URL because URLs end up in logs.
8. What are resources and endpoints?
A resource is a thing the API exposes: a customer, an order, an invoice. An endpoint is a URL plus method that acts on it, such as GET /orders/{id}.
Good resource design uses nouns, not verbs, and plural collections:
GET /orderslists orders,POST /orderscreates one.GET /orders/42reads one,PATCH /orders/42updates it.- Related data nests one level:
GET /customers/7/orders.
Avoid URLs like /getOrders or /createOrder: the method already says what happens. Actions that do not fit, such as “cancel”, are often modelled as a state change (PATCH with status: cancelled) or a sub-resource (POST /orders/42/cancellation).
9. Which HTTP methods are safe and which are idempotent?
- Safe means the request only reads and does not change anything:
GET,HEAD,OPTIONS. - Idempotent means sending the same request several times has the same effect as sending it once: all the safe methods, plus
PUTandDELETE. - Not idempotent:
POST, andPATCHunless the API makes it so.
DELETE /orders/42 twice still leaves order 42 deleted, even if the second call returns 404, so it counts as idempotent. These properties tell you which calls a client, a proxy or a pipeline can retry automatically after a timeout without causing duplicates.
Learn more: Idempotency in data pipelines
10. Why do most REST APIs use JSON?
JSON is text, easy for people to read, built into every programming language and browser, and maps directly onto objects and lists. That makes it the default body format. The client says what it sends with Content-Type: application/json and what it wants back with Accept: application/json.
Its limits matter for data work. JSON has no date type, so dates arrive as strings and you need an agreed format such as ISO 8601. Numbers can lose precision in some languages, so money is often sent as a string or in cents. Large responses are also slower to parse than binary formats. REST does not require JSON; XML and CSV endpoints still exist.
Security, paging and reliability
11. How do you authenticate to a REST API?
The common methods, from simplest:
- API key: a secret string sent in a header such as
X-API-KeyorAuthorization. Simple, common for server-to-server access. - Basic auth: a username and password, base64-encoded in the
Authorizationheader. Only safe over HTTPS. - Bearer token:
Authorization: Bearer <token>, usually a short-lived access token from OAuth 2.0 (question 12), often a JWT (question 13). - Mutual TLS: both sides present certificates; used in banking and internal systems.
Whatever the method: always use HTTPS, keep secrets in a secrets manager or environment variable, never in code or URLs, and rotate them. Remember 401 means “who are you?” and 403 means “you are not allowed”.
12. How does OAuth 2.0 work?
OAuth 2.0 lets an application get a limited, expiring access token instead of handling a user’s password. The token is then sent as Authorization: Bearer <token>.
The two flows you are most likely to discuss:
- Client credentials (server to server): your pipeline sends its client ID and secret to the provider’s token endpoint and receives an access token. No user is involved. This is what most data ingestion jobs use.
- Authorization code (on behalf of a user): the user signs in at the provider, approves the requested scopes, and your app exchanges a one-time code for tokens. Public apps add PKCE to protect that exchange.
Access tokens expire, often within an hour; a refresh token gets a new one without asking the user again.
13. What is a JWT?
A JWT (JSON Web Token) is a compact token in three base64url parts separated by dots: header.payload.signature. The payload holds claims such as the user ID (sub), expiry (exp) and permissions. The signature, made with a secret or private key, lets the server check that nobody changed the token, without a database lookup.
Two points interviewers check:
- A JWT is signed, not encrypted by default. Anyone can read the payload, so never put secrets in it.
- It cannot easily be revoked before it expires, so access tokens are kept short-lived and paired with refresh tokens.
Always verify the signature, the expected algorithm, the issuer, the audience and the expiry.
14. What is pagination, and which kinds are there?
APIs return large lists in pages so responses stay small and fast. Three kinds:
- Offset:
?offset=200&limit=100. Simple, but slow on big tables, and rows shift if data changes while you page. - Page number:
?page=3&per_page=100. The same idea and the same problems. - Cursor (keyset): the response includes a
next_cursor, and you pass it back to get the next page. Fast and stable while data changes; the usual choice for large or busy datasets.
The client loop is the same for all of them: keep asking until the API says there is no next page.
# A fake API that returns pages of orders with a cursor, like many real APIs do.
ORDERS = [{"id": i, "updated_at": f"2026-11-0{1 + i // 4}"} for i in range(1, 11)]
def fake_get(cursor=None, limit=4):
start = int(cursor or 0)
page = ORDERS[start:start + limit]
nxt = str(start + limit) if start + limit < len(ORDERS) else None
return {"data": page, "next_cursor": nxt}
def fetch_all(get):
"""Follow next_cursor until the API says there is no next page."""
cursor, pages = None, 0
while True:
body = get(cursor=cursor)
pages += 1
yield from body["data"]
cursor = body["next_cursor"]
if not cursor:
break
print(f"pages fetched: {pages}")
rows = list(fetch_all(fake_get))
print(f"rows: {len(rows)}, first id {rows[0]['id']}, last id {rows[-1]['id']}")
pages fetched: 3
rows: 10, first id 1, last id 10
Learn more: Working with APIs in Python: pagination, retries and rate limits
15. What is rate limiting, and how do you handle a 429?
Rate limiting caps how many requests a client may send in a time window, such as 100 per minute, to protect the API. Going over returns 429 Too Many Requests, often with a Retry-After header saying how many seconds to wait. Many APIs also send headers such as X-RateLimit-Remaining so you can slow down before hitting the limit.
How to handle it as a client:
- On 429, wait for
Retry-Afterif it is present, otherwise back off exponentially (question 16). - Throttle yourself: stay under the documented limit, especially with parallel workers sharing one key.
- Request less: larger page sizes, filters such as
updated_since, and bulk endpoints if they exist.
16. How do you retry failed API calls safely?
Retry only what can succeed next time: timeouts, connection errors, 429 and 5xx. Do not retry 400, 401, 403 or 404. Wait longer after each failure (exponential backoff), add randomness (jitter) so many clients do not retry at the same moment, cap the wait and the number of attempts, and respect Retry-After. Only retry non-idempotent calls such as POST when the API supports idempotency keys.
import random
RETRYABLE = {429, 500, 502, 503, 504}
def backoff_delays(statuses, base=1.0, cap=30.0, retry_after=None, seed=7):
"""Seconds to wait before each retry: exponential, capped, with full jitter; Retry-After wins if sent."""
rng = random.Random(seed)
delays = []
for attempt, status in enumerate(statuses):
if status not in RETRYABLE:
break # 400, 401, 404: retrying will not help
if retry_after and status == 429:
delays.append(float(retry_after))
else:
delays.append(round(rng.uniform(0, min(cap, base * 2 ** attempt)), 2))
return delays
print("503s: ", backoff_delays([503, 503, 503, 503]))
print("429 + hint:", backoff_delays([429], retry_after=12))
print("404: ", backoff_delays([404, 503]))
503s: [0.32, 0.3, 2.6, 0.58]
429 + hint: [12.0]
404: []
The upper limit doubles each time (1, 2, 4, 8 seconds), and jitter picks a random wait below it.
Learn more: Pipeline reliability and retries
17. What is an idempotency key?
An idempotency key is a unique ID the client sends with a request that is not naturally idempotent, usually a POST, often in a header such as Idempotency-Key. The server stores the key with the result. If the same key arrives again, for example because the client timed out and retried, the server returns the stored result instead of acting twice.
It solves the classic problem: “the payment request timed out; did it go through?” Without a key, retrying might charge the customer twice. With a key, retrying is always safe. Payment providers use this widely. Keys are generated per operation (a UUID), reused only for retries of that same operation, and kept by the server for a limited time.
18. What is the difference between webhooks and polling?
- Polling: your system asks the API on a schedule, “anything new since 10:00?”. Simple and under your control, but wasteful when little changes, and data is only as fresh as the interval.
- Webhooks: the provider sends an HTTP POST to your URL when something happens (“order.paid”). Near real time and efficient, but you must run a public endpoint and handle failures.
In production, the reliable pattern is often both: webhooks for speed, plus a periodic catch-up poll for anything missed. Webhook handlers should reply quickly with 2xx, put the event on a queue, and process it separately, because providers retry slow or failed deliveries and the same event can arrive more than once.
19. How do you secure a webhook?
Your webhook URL is public, so anyone could post fake events to it. The standard protections:
- Verify the signature. The provider signs each request body with a shared secret (usually HMAC-SHA256) and sends the signature in a header. Recompute it over the raw body and compare with a constant-time comparison.
- Check the timestamp included in the signed data and reject old requests, which stops replay attacks.
- Deduplicate on the event ID, because retries deliver the same event again.
- Use HTTPS only, and keep the secret in a secrets manager.
As extra safety, treat the event as a hint: fetch the latest state of the resource from the API before acting on it.
20. How do you version a REST API?
Versioning lets you change an API without breaking existing clients. Common approaches:
- In the URL:
/v1/orders,/v2/orders. The most visible and easiest to route and cache. - In a header:
Accept: application/vnd.example.v2+jsonor a custom version header. Keeps URLs clean, harder to test in a browser. - Date-based versions sent in a header, which some large APIs use for frequent small changes.
More important than the method: avoid breaking changes in the first place. Adding a field or an endpoint is safe; removing or renaming a field, or changing its type, is breaking. When a version must retire, announce it, give a deprecation period, and send a deprecation header so clients notice.
21. How does caching work in REST APIs?
HTTP has caching built in, mainly for GET:
Cache-Controltells clients and proxies how long a response may be reused, for examplemax-age=300, orno-storefor private data.ETagis a version tag for a resource. The client sends it back inIf-None-Match; if nothing changed, the server replies 304 Not Modified with no body, saving bandwidth.Last-ModifiedandIf-Modified-Sincedo the same with a timestamp.
For ingestion jobs, conditional requests are useful: polling a large resource that rarely changes costs almost nothing when the answer is 304. Writes (POST, PUT, PATCH, DELETE) should make cached copies of that resource stale.
22. What is CORS?
CORS (Cross-Origin Resource Sharing) is a browser rule. By default, JavaScript on app.example.com cannot read responses from api.other.com. The API can allow it by sending headers such as Access-Control-Allow-Origin: https://app.example.com. For some requests the browser first sends an OPTIONS preflight to ask which methods and headers are allowed.
Two points that often confuse people:
- CORS is enforced only by browsers. A Python script, curl or a server-side job is not affected by it at all.
- CORS is not authentication. It controls which websites’ scripts may read responses, not who may call the API, so the API still needs proper auth.
23. REST vs GraphQL vs gRPC: when would you use each?
| REST | GraphQL | gRPC | |
|---|---|---|---|
| Shape | Many resource URLs | One endpoint, the client writes a query | Remote procedure calls defined in Protocol Buffers |
| Format | Usually JSON | JSON | Binary (protobuf) over HTTP/2 |
| Strength | Simple, cacheable, universal | Client gets exactly the fields it needs in one call | Fast, strongly typed, streaming |
| Typical use | Public and partner APIs | Front ends with varied data needs | Internal service-to-service calls |
Pick REST for broad, simple, cache-friendly APIs; GraphQL when many clients need different slices of related data and over-fetching hurts; gRPC for high-volume internal traffic between services you control.
24. What is the difference between REST and SOAP?
SOAP is an older protocol: every message is an XML envelope, the operations are described in a WSDL file, and it comes with standards for security and transactions (WS-Security and others). REST is an architectural style: resources at URLs, standard HTTP methods and usually JSON.
REST is lighter, easier to use from any language or browser, and dominant for modern APIs. SOAP is still found in banking, insurance, telecoms and older enterprise systems (some ERP and government services). As a data engineer or forward deployed engineer you may still need to call a SOAP service: libraries such as zeep in Python generate a client from the WSDL.
APIs in data engineering
25. How do you load data from a REST API into a data warehouse?
A reliable pattern:
- Extract with a client that handles authentication, pagination, rate limits, timeouts and retries.
- Land raw responses unchanged in object storage or a raw table, with the load time and request parameters. This lets you reprocess without calling the API again.
- Load incrementally, not the full history every run (question 26).
- Transform in the warehouse: flatten nested JSON, cast types, deduplicate on the record ID, then MERGE into the target so reruns are safe.
- Orchestrate and monitor: schedule in a tool such as Airflow, alert on failures, and check row counts and freshness.
Managed connectors can replace steps 1–3 for common SaaS sources; custom code is for the rest.
Learn more: API integration: connecting to a customer’s systems
26. How do you load only new or changed records from an API?
Use a watermark: remember the highest updated_at (or a cursor the API gives you) from the last successful run, and next time ask only for records changed since then, for example ?updated_since=2026-11-02T10:00:00Z.
The details that make it correct:
- Store the watermark only after the load commits, so a failed run is simply repeated.
- Overlap a little (re-read the last few minutes) to catch records written late or with clock differences, and deduplicate on the record ID with MERGE.
- Deletes often do not appear in “changed since” results; look for a deleted-records endpoint, a status field, or run a periodic full comparison.
- Backfills use the same code with an explicit date range.
Learn more: Incremental loading, watermarks and backfills
27. What do you do when an API changes its response format?
Plan for it, because it will happen:
- Land raw JSON first, so a new or changed field never loses data; only the parsing step needs fixing.
- Validate responses against the fields you depend on (for example with a schema check or Pydantic) and fail loudly, or quarantine the bad records, when a required field is missing or changes type.
- Ignore unknown new fields in parsing until you decide to use them; adding a field should not break the pipeline.
- Pin the API version if the provider offers versions, and watch their changelog and deprecation notices.
- Alert on sudden changes in row counts or null rates, which often signal a silent format change.
28. How do you test code that calls an API?
Test at three levels:
- Unit tests with a fake. Replace the HTTP call with a stub (for example
unittest.mock, or libraries such asresponsesforrequests) that returns saved example responses. Test the paths that matter: several pages, an empty page, 429 then success, 500 three times, a malformed record. - Recorded responses. Capture real responses once and replay them, so tests are realistic but run offline and fast.
- A small live check against a sandbox account, run on a schedule rather than on every commit, to catch real changes in the API.
Keep the client code separate from the transformation logic, so most of the pipeline can be tested without any HTTP at all.
Learn more: Testing data pipelines and CI/CD
29. How would you design a REST API for orders?
Start from the resources and the users’ tasks, then apply consistent rules:
- Endpoints:
GET /orders(filter with?status=and?created_after=, cursor pagination),POST /orders(accepts an idempotency key),GET /orders/{id},PATCH /orders/{id}for status changes, andGET /customers/{id}/orders. - Responses: JSON with stable IDs, ISO 8601 timestamps, money as a string or minor units with a currency code, and one consistent error format (
code,message,details). - Status codes: 201 with a
Locationheader on create, 404 for unknown IDs, 409 for invalid state changes such as cancelling a shipped order, 422 for invalid fields. - Operations: authentication and scopes, rate limits, versioning, an
updated_sincefilter for consumers who sync data, and webhooks for events such asorder.shipped.
30. How should an API handle a long-running job?
Do not keep the HTTP request open for minutes: connections time out and retries start duplicates. Use the asynchronous request pattern instead:
- The client sends
POST /exports. The server queues the work and replies 202 Accepted with a job ID and a status URL, such asLocation: /exports/123. - The client checks
GET /exports/123, which reportsqueued,running,succeededorfailed, possibly with progress. TheRetry-Afterheader can suggest how often to check. - When it succeeds, the status includes a link to the result, such as a file to download.
A webhook when the job finishes saves the client from polling. Data platforms use this pattern for exports, report generation and bulk loads.

