Guide · Interview prep
API Design Interview: How the Round Runs and How You Are Scored
21 min readUpdated By Saket Bhatnagar
Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.
In short
- An API design interview asks you to design one API's contract in a single interview slot. The contract is the promise of which requests the API accepts and what it sends back.
- A good flow: agree the use cases, name the resources (nouns like appointments), list the endpoints (a method plus a path), then settle status codes, paging, errors and retries.
- As of 24 October 2026 there is no public, shared rubric, and companies differ. Practise against what the round tests: use cases, resources, HTTP meaning, safe retries, stable paging, errors and trade-offs.
- The classic trap is the create call. POST is not idempotent, meaning a repeat can act twice, so a retried booking can create two bookings. An Idempotency-Key header, still an IETF draft, fixes that when the server stores and checks it.
- Beginners can stop after the worked endpoint table and then read the practice rubric. Engineers get a FastAPI 0.162.0 demo we ran: a retry replayed, a reused key rejected with 422, and offset pages repeating a row while cursor pages do not.
What goes wrong when you treat an API design round like a system design round?
You run out of time before you have written a single endpoint. In an API design interview the interviewer mostly wants the contract, not the boxes behind it.
Picture a common setup. A candidate is asked to design the API for a clinic's appointment booking app. They spend 25 minutes drawing load balancers, caches and database shards. The setup is made up, but this guide is built to help you avoid exactly that trap.
With ten minutes left, the interviewer asks what the booking request looks like. They also ask what happens if the patient's phone retries it. The candidate has no answer ready, because neither question needs a load balancer.
This guide uses that same clinic booking API from start to finish. You will see the flow of the round, a worked design, and the details that tend to separate a pass from a strong pass.
What is an API design interview?
An API design interview is a round where you design the interface other programs use to talk to a service. An API, or application programming interface, is that agreed way for one program to ask another for data or actions.
You are judged on the contract: the URLs, the request and response bodies, the status codes and the error format. You are also judged on how the API behaves when networks fail and lists grow.
Formats can differ by company and by team, and we found no public standard for them as of 24 October 2026. Ask your recruiter whether you will talk at a whiteboard, write in a shared document or write a little code.
| Round | Main question | What you produce | Where depth goes |
|---|---|---|---|
| API design | What does the contract look like? | Endpoints, request and response shapes, status codes, errors | Retries, paging, versioning, edge cases |
| System design | How does the whole service work at scale? | Boxes and arrows, data flow, estimates | Scaling, storage, failure of parts |
| Low-level design | How is the code organised inside? | Classes, methods, relationships | Patterns, state, extensibility |
Which words do you need before an API design interview?
You need about ten words. Each one below is likely to come up, so learn them before the worked example.
- Resource: a thing your API manages, named as a noun, such as an appointment or a doctor.
- Endpoint: one HTTP method plus one path, such as POST /v1/appointments. The method says what to do; the path says to what.
- HTTP method: the verb of a request. GET reads, POST creates or triggers, PUT replaces, PATCH changes part, DELETE removes.
- Status code: the three-digit number in every response, such as 201 for created or 404 for not found.
- Safe method: a method meant to be read-only. RFC 9110, the core HTTP standard, lists GET, HEAD, OPTIONS and TRACE as safe.
- Idempotent method: sending it twice has the same intended effect as sending it once. RFC 9110 lists PUT, DELETE and the safe methods.
- Idempotency key: a unique value the client sends with a request, so the server can spot a repeat and not act twice.
- Pagination: returning a long list in pages. A cursor is a bookmark token that says where the next page starts.
- Problem details: a standard JSON shape for error responses, defined in RFC 9457.
- ETag: a version tag the server puts on a resource, so a client can say 'change this only if it is still that version'.
How does a 45-minute API design interview usually run?
A steady round moves from use cases to resources to endpoints, then into the hard details. The plan below is our suggested split for a 45-minute slot, not a published standard.
Minutes 0 to 5: clarify the use cases
Ask who calls the API and what they must do. For the clinic: patients find free slots, book one, see their bookings and cancel. Write these as short user actions.
Minutes 5 to 10: name the resources
Turn the nouns into resources: doctors, slots and appointments. Say how they relate: a doctor has many slots, and an appointment takes one slot.
Minutes 10 to 22: write the endpoints
List each endpoint with its method, path, request body, response body and success status code. Write one full example request and response for the most important call.
Minutes 22 to 35: go deep on the hard parts
Pick the risky calls and harden them: safe retries for booking, cursor paging for lists, clear errors for a slot clash.
Minutes 35 to 42: cover the edges
Mention authentication, rate limits, versioning and what happens when two patients grab the same slot at the same moment.
Minutes 42 to 45: summarise the trade-offs
Repeat the two or three choices you made on purpose and what each one costs. Invite the interviewer to push on any of them.
The flow of an API design round
Drag to exploreNotice that the deep dive only starts after the endpoints exist on the board. Hard details need a contract to attach to.
Diagram connections:
- Use cases to Resources (nouns become resources)
- Resources to Endpoints (one row per action)
- Endpoints to Deep dive (harden risky calls)
- Deep dive to Edges (then the edges)
- Edges to Trade-offs (close with trade-offs)
- Use cases: Find slots, book, list, cancel
- Resources: Doctors, slots, appointments
- Endpoints: Method, path, bodies, success code
- Deep dive: Retries, paging, errors
- Edges: Auth, rate limits, versions, races
- Trade-offs: Two or three choices and their cost
How do you turn requirements into resources and endpoints?
Underline the nouns in the use cases, make each one a resource, and give each action a standard method. Google's public API design guidance, AIP-121, describes this resource-oriented style: named resources plus a small set of standard methods.
Those standard methods are Get, List, Create, Update and Delete. AIP-121 adds custom methods only for actions that do not fit them. For our clinic, that gives the table below.
| Endpoint | What it does | Success code |
|---|---|---|
| GET /v1/doctors/{doctor_id}/slots?date=2026-11-03 | Lists free slots for one doctor on one day | 200 OK |
| POST /v1/appointments | Books a slot; needs an Idempotency-Key header | 201 Created, with a Location header |
| GET /v1/appointments/{appointment_id} | Reads one appointment | 200 OK |
| GET /v1/appointments?limit=20&cursor=... | Lists the caller's appointments, newest first, in pages | 200 OK |
| POST /v1/appointments/{appointment_id}:cancel | Cancels a booking but keeps its record | 200 OK, with the updated appointment |
| PATCH /v1/appointments/{appointment_id} | Moves a booking to a new slot; needs an If-Match header | 200 OK |
Why the paths look like that
Paths use plural nouns, and in most rows the action lives in the method. The /v1 prefix leaves room for a breaking change later. Our guide on API versioning strategies covers that choice in depth.
Slots sit under a doctor because a slot never exists without one. Appointments sit at the top level because a patient lists them across many doctors.
Cancel is the classic judgement call
You have three honest options for cancel. DELETE removes the appointment, which loses the history the clinic needs for records. PATCH with a status field works, but it hides an important business action inside a general update.
A custom method keeps the record and names the action. Google's AIP-136 says custom methods that change data use POST and add a colon and a verb, as in its ':archive' example. We used ':cancel' the same way.
Which HTTP methods and status codes should you pick?
Pick the method by its meaning in RFC 9110, and the status code by what actually happened. Getting these right is a cheap way to show you know HTTP, the protocol REST APIs are built on.
RFC 9110 calls GET, HEAD, OPTIONS and TRACE safe, meaning read-only from the client's point of view. It calls PUT, DELETE and the safe methods idempotent. POST is neither, and RFC 5789 says PATCH is neither as well.
That matters for retries. RFC 9110 says a client should not automatically retry a non-idempotent request unless it has some way to know the repeat is harmless. Our booking call is a POST, so it needs that way.
| Code | When the clinic API sends it | What the standard says |
|---|---|---|
| 200 OK | A read or a cancel succeeded | RFC 9110: the request succeeded |
| 201 Created | A booking was made | RFC 9110: a new resource was created; a Location header identifies it |
| 202 Accepted | Only if booking became slow background work | RFC 9110: accepted, but processing is not complete |
| 400 Bad Request | The Idempotency-Key header is missing | RFC 9110: a client error the server will not process |
| 401 Unauthorized | No valid login token was sent | RFC 9110: the server must also send a WWW-Authenticate header |
| 403 Forbidden | A patient tries to cancel someone else's booking | RFC 9110: understood, but refused |
| 404 Not Found | The appointment ID does not exist | RFC 9110: may also hide that a resource exists |
| 409 Conflict | The slot was booked by someone else | RFC 9110: conflicts with the resource's current state |
| 412 Precondition Failed | The If-Match version is out of date | RFC 9110: a condition in the headers was false |
| 422 Unprocessable Content | Well-formed JSON with a value that makes no sense | RFC 9110: syntax fine, instructions could not be processed |
| 429 Too Many Requests | The caller hit a rate limit | RFC 6585: may include a Retry-After header |
Two details are worth saying out loud. For another patient's appointment, you may answer 404 instead of 403, because RFC 9110 lets a server decline to disclose that a resource exists. And a 401 response must carry a WWW-Authenticate header.
How If-Match protects a reschedule
Say the patient and the clinic desk both move the same appointment at once. Without a check, the later write silently wins. With an ETag, the client sends If-Match with the version it last read.
If the appointment changed since then, RFC 9110 says the server must not apply the change, and it may answer 412 Precondition Failed. RFC 5789 advises this kind of conditional request for PATCH.
How do you make a booking request safe to retry?
Ask the client to send a unique Idempotency-Key header with every booking. The server stores the key with the result, and a repeat with the same key gets the stored result instead of a second booking.
Here is why it matters. The patient taps Book, the server books the slot, and the phone loses signal before the reply arrives. The app retries. Without a key, the server cannot tell a retry from a new booking.
Think of the token number a bank gives you at the counter. If you come back with the same token, the clerk looks it up and hands you the same receipt. They do not open a second deposit.
Where the picture breaks: a bank may keep tokens for years, but a server usually expires keys. The draft says a server may expire keys and should document its expiry policy.
The draft's rules are short. The key must be a string, and a UUID or similar random value is recommended. A key must not be reused with a different request body.
It also suggests status codes, each as a SHOULD rather than a MUST. Send 400 if a required key is missing. Send 422 if a key comes back with a different body. Send 409 if a retry arrives while the first request is still running.
One booking, sent twice with the same key
Drag to exploreNotice the second request never reaches the booking step. The key store answers it with the saved result, so the slot is booked once.
Diagram connections:
- Patient app to Appointments API (POST /v1/appointments)
- Appointments API to Key store (look up key)
- Key store to Key already seen? (result)
- Key already seen? to Book the slot (No)
- Key already seen? to Replay saved 201 (Yes, same body)
- Key already seen? to Reject with 422 (Yes, different body)
- Patient app: Phone → API: POST with key 8e03...
- Appointments API: API → key store: seen this key?
- Key store: Key → body fingerprint + saved reply
- Key already seen?: Decision made by the API
- Book the slot: API → database: insert once
- Replay saved 201: API → phone: same id, same body
- Reject with 422: API → phone: key reused, new body
A tiny API you can run
We built the clinic API in FastAPI 0.162.0 on Python 3.13 to check each claim above; pip pulled in Pydantic 2.14.1 with it. It keeps everything in memory, so it is a teaching demo, not production code.
To run it yourself, install the pinned versions with pip install fastapi==0.162.0 httpx==0.28.1. Save the file as app.py next to the test script below.
import base64, hashlib, json, uuid
from fastapi import FastAPI, Header
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
APPOINTMENTS = [] # newest last; each has a "seq" number
TAKEN_SLOTS = {} # slot_id: appointment id
SEEN_KEYS = {} # idempotency key: (body fingerprint, saved response)
class NewAppointment(BaseModel):
slot_id: str
patient_id: str
def problem(status, title, detail):
body = {"type": "about:blank", "title": title, "status": status, "detail": detail}
return JSONResponse(body, status_code=status, media_type="application/problem+json")
@app.post("/v1/appointments")
def book(body: NewAppointment, idempotency_key: str | None = Header(default=None)):
if idempotency_key is None:
return problem(400, "Missing Idempotency-Key", "Send a new random key with every booking.")
fingerprint = hashlib.sha256(body.model_dump_json().encode()).hexdigest()
if idempotency_key in SEEN_KEYS:
old_fingerprint, saved = SEEN_KEYS[idempotency_key]
if old_fingerprint != fingerprint:
return problem(422, "Idempotency-Key reused", "This key was sent with a different body.")
return JSONResponse(saved, status_code=201, headers={"Location": f"/v1/appointments/{saved['id']}"})
if body.slot_id in TAKEN_SLOTS:
return problem(409, "Slot already booked", f"Slot {body.slot_id} is taken. Pick another slot.")
appt = {"id": "apt_" + uuid.uuid4().hex[:8], "seq": len(APPOINTMENTS) + 1,
"slot_id": body.slot_id, "patient_id": body.patient_id, "status": "booked"}
APPOINTMENTS.append(appt)
TAKEN_SLOTS[body.slot_id] = appt["id"]
SEEN_KEYS[idempotency_key] = (fingerprint, appt)
return JSONResponse(appt, status_code=201, headers={"Location": f"/v1/appointments/{appt['id']}"})
def encode_cursor(seq):
return base64.urlsafe_b64encode(json.dumps({"before": seq}).encode()).decode()
def decode_cursor(cursor):
return json.loads(base64.urlsafe_b64decode(cursor.encode()))["before"]
@app.get("/v1/appointments")
def list_newest_first(limit: int = 2, cursor: str | None = None):
rows = sorted(APPOINTMENTS, key=lambda a: a["seq"], reverse=True)
if cursor:
before = decode_cursor(cursor)
rows = [a for a in rows if a["seq"] in range(1, before)]
page = rows[:limit]
more = bool(rows[limit:])
return {"items": page, "next_cursor": encode_cursor(page[-1]["seq"]) if more else None}
@app.get("/v1/appointments-by-offset")
def list_by_offset(limit: int = 2, offset: int = 0):
rows = sorted(APPOINTMENTS, key=lambda a: a["seq"], reverse=True)
return {"items": rows[offset:offset + limit]}The test script below calls the API with FastAPI's built-in test client, so no server needs to be started. It sends the same booking twice, then tries the mistakes.
from fastapi.testclient import TestClient
from app import app
client = TestClient(app)
order = {"slot_id": "dr7-2026-11-03-1030", "patient_id": "pat_42"}
key = {"Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324"}
first = client.post("/v1/appointments", json=order, headers=key)
retry = client.post("/v1/appointments", json=order, headers=key)
print("first:", first.status_code, first.json()["id"], first.headers["location"])
print("retry:", retry.status_code, retry.json()["id"], "same id:", first.json()["id"] == retry.json()["id"])
other = client.post("/v1/appointments", json={**order, "patient_id": "pat_99"}, headers=key)
print("same key, new body:", other.status_code, other.headers["content-type"], other.json()["title"])
no_key = client.post("/v1/appointments", json=order)
print("no key:", no_key.status_code, no_key.json()["title"])
clash = client.post("/v1/appointments", json={**order, "patient_id": "pat_7"},
headers={"Idempotency-Key": "a-different-key-1"})
print("slot clash:", clash.status_code, clash.json()["detail"])
bad = client.post("/v1/appointments", json={"slot_id": "x"}, headers={"Idempotency-Key": "k-bad"})
print("missing field:", bad.status_code, bad.headers["content-type"], bad.json()["detail"][0]["type"])Run python run_demo.py. You should see output like this, with a different random ID each time.
first: 201 apt_a91877f5 /v1/appointments/apt_a91877f5
retry: 201 apt_a91877f5 same id: True
same key, new body: 422 application/problem+json Idempotency-Key reused
no key: 400 Missing Idempotency-Key
slot clash: 409 Slot dr7-2026-11-03-1030 is taken. Pick another slot.
missing field: 422 application/json missingWhat just happened? The retry got 201 and the same ID, so one slot was booked once. The reused key with a new body got 422 in the problem details format. The slot clash got 409.
Look at the last line too. FastAPI's own validation error for a missing field is a 422 in plain application/json, not application/problem+json. If you promise problem details everywhere, you must add your own handler for validation errors.
Say that last point out loud in the interview. A unique constraint ensures a column's values are unique among all rows, as the PostgreSQL 18 documentation puts it. The same trick on slot_id stops two patients booking one slot.
Should you use offset or cursor pagination in the interview?
Use cursor pagination for a list that changes while people read it, and say why. Offset paging says 'skip 20, give me 20', so a new row at the top shifts everything down and the next page repeats a row.
Cursor paging says 'give me 20 older than this bookmark'. New rows at the top do not move the bookmark. We ran both styles on the demo, adding one booking between page 1 and page 2.
from fastapi.testclient import TestClient
from app import app
client = TestClient(app)
def book(n):
r = client.post("/v1/appointments", json={"slot_id": f"slot-{n}", "patient_id": "pat_42"},
headers={"Idempotency-Key": f"key-{n}"})
return r.json()["seq"]
for n in range(1, 6):
book(n) # appointments 1..5
off1 = client.get("/v1/appointments-by-offset", params={"limit": 2, "offset": 0}).json()["items"]
cur1 = client.get("/v1/appointments", params={"limit": 2}).json()
book(6) # a new booking arrives between page 1 and page 2
off2 = client.get("/v1/appointments-by-offset", params={"limit": 2, "offset": 2}).json()["items"]
cur2 = client.get("/v1/appointments", params={"limit": 2, "cursor": cur1["next_cursor"]}).json()
print("offset page 1:", [a["seq"] for a in off1], "page 2:", [a["seq"] for a in off2])
print("cursor page 1:", [a["seq"] for a in cur1["items"]], "page 2:", [a["seq"] for a in cur2["items"]])
print("next_cursor:", cur1["next_cursor"])Pause and predict: one booking arrives after page 1. Which style shows a row twice on page 2? Run python run_paging.py and compare with our output below.
offset page 1: [5, 4] page 2: [4, 3]
cursor page 1: [5, 4] page 2: [3, 2]
next_cursor: eyJiZWZvcmUiOiA0fQ==The offset version showed appointment 4 twice. The cursor version moved on cleanly to 3 and 2. The cursor text is the same on every run, because the sequence numbers are.
What a good cursor looks like
Our demo cursor is plain base64 text, which is easy to decode. Base64 is a way to write bytes as letters and digits. Our token decodes to the JSON text {"before": 4}, so any client can read or forge it.
Google's pagination guide, AIP-158, says page tokens must be opaque and that base64 alone is not enough. In an interview, say you would encrypt or sign the token so clients cannot read or change it.
- Treat the page size as a maximum. AIP-158 says an API may return fewer results than asked, even when more exist.
- Signal the end clearly. AIP-158 uses an empty next page token to mean there are no more pages.
- Make a total count optional. AIP-158 allows a total, and says it may be an estimate.
- Paginate from day one. AIP-158 calls adding pagination to an existing list method a backwards-incompatible change.
Our guide on API pagination with offset vs cursor goes much deeper and builds it step by step in Python.
How should an API return errors?
Return the right status code plus a body in the problem details format from RFC 9457. It gives every error the same JSON shape, so client developers write one error handler instead of many.
RFC 9457 replaced the older RFC 7807 and uses the media type application/problem+json. It defines five standard members: type, title, status, detail and instance.
- type: a URI that names the kind of problem. If you leave it out, it means about:blank.
- title: a short, human-readable summary of that kind of problem.
- status: the HTTP status code, repeated in the body.
- detail: an explanation of this one occurrence, written for a person.
- instance: a URI that identifies this specific occurrence.
For the slot clash, the demo returned this body with status 409. You may add your own fields, such as alternative slots. RFC 9457 says clients must ignore extension fields they do not recognise.
{
"type": "about:blank",
"title": "Slot already booked",
"status": 409,
"detail": "Slot dr7-2026-11-03-1030 is taken. Pick another slot."
}One warning earns points. RFC 9457 says problem details are not a debugging tool, and warns against exposing implementation details such as a stack dump. Log the stack trace; never send it to the client.
How are API design interviews scored?
Each company scores in its own way, and as of 24 October 2026 we found no public, shared rubric for this round. What we can give you is a practice rubric built from what the round tests.
Use it to mark your own mock answers. If a dimension is weak, the earlier section on it shows what a strong answer includes.
| Dimension | A strong answer shows | A weak answer shows |
|---|---|---|
| Requirements | Clear callers and use cases agreed before any endpoint | Endpoints written before knowing who calls them |
| Resources and endpoints | Nouns as resources, methods that match their meaning, consistent paths | Verbs in paths like /bookAppointment, mixed naming styles |
| HTTP semantics | Status codes that match the outcome, 201 with Location, 409 for clashes | 200 for everything, with an error flag inside the body |
| Reliability | Idempotency keys on creates, If-Match on updates, a plan for races | No answer to 'what if the client retries?' |
| Lists and errors | Cursor paging with a page limit, one error shape everywhere | Unbounded lists, ad hoc error text |
| Communication | States trade-offs and invites challenge | Defends every choice as the only option |
What follow-up questions come up in an API design round?
Follow-ups test whether your contract survives real use. Prepare a two-sentence answer for each of these, using the clinic API.
- How would you version this? Keep /v1, add fields without breaking anyone, and only create /v2 for a breaking change.
- How do you stop abuse? Rate limit per caller and return 429 Too Many Requests, which RFC 6585 says may include Retry-After.
- Two patients book the same slot at once. What happens? A unique constraint on slot_id lets one insert win; the API turns the other failed insert into a 409.
- Booking now calls a slow insurance check. What changes? Return 202 Accepted with a link to check status later, as RFC 9110 defines 202.
- Why not GraphQL or gRPC? Name what the callers need; our REST vs GraphQL vs gRPC guide compares the trade-offs.
- How do clients learn about cancellations by the clinic? Offer webhooks or a list endpoint they can poll with a cursor.
How do you explain an API design in a system design interview?
Sometimes the API is only one part of a system design round. Give it about five minutes, in this order, then return to the architecture.
Name the callers
Say who uses the API, such as the patient app and the clinic desk, and the three or four actions they need.
Show the resources
List the nouns and how they nest. For the clinic: doctors have slots, and appointments take one slot.
Write the key endpoints
Write three to five method-plus-path lines with their success codes. Write one full request and response.
Harden the create call
Say the booking needs an Idempotency-Key, and that the server stores key, body fingerprint and response.
Bound the lists
Say lists use a cursor and a maximum page size, so no response grows without limit.
Fix the error shape
Say every error uses RFC 9457 problem details, with a 409 for a slot clash.
Questions people ask
- How do I prepare for an API design interview?
- Practise designing three or four small APIs end to end out loud. Good practice prompts include a booking app, a to-do list, a comments thread and a file upload. For each, write the endpoints, one full request and response, the status codes, and your answer to 'what if the client retries?'. Then mark yourself against the practice rubric in this guide.
- Do I need to write code in an API design interview?
- Plan to write the contract, and be ready to write a little code too, because formats can differ by company and team. Ask your recruiter whether you will talk at a whiteboard, write in a shared document or build a small implementation. Practising with a tiny runnable API, like the FastAPI demo in this guide, prepares you for both.
- Should I use PUT or PATCH for updates?
- Use PUT to replace a whole resource and PATCH to change part of it. RFC 9110 defines PUT as idempotent, so repeating it has the same intended effect as sending it once. RFC 5789 says PATCH is neither safe nor idempotent. It recommends a conditional request with an ETag in If-Match, so the update fails if someone else changed the resource first.
- Is 422 or 400 the right code for a validation error?
- Both are defensible, so pick one and use it consistently. RFC 9110 says 400 covers a client error the server will not process, such as malformed syntax. It defines 422 for content that is well formed but whose instructions cannot be processed. One defensible split is 400 for broken JSON and 422 for valid JSON with bad values.
- Is the Idempotency-Key header an official standard?
- Not yet. As of 24 October 2026 it is an IETF working group draft, version 08, dated 22 October 2026, and not an RFC. In an interview, say it follows the IETF draft, and describe what the server stores and how long keys live.
- How is an API design interview different from a system design interview?
- An API design interview focuses on the contract that callers see: endpoints, request and response shapes, status codes, errors, paging and retries. A system design interview focuses on the parts behind the contract, such as servers, storage, caches and scaling. A system design round can include a short API step, so the skills overlap.
- Which mistake should I guard against most in an API design round?
- A mistake worth guarding against is skipping retries. It is easy to design a clean POST for creating something, then freeze when asked what happens if the client sends it twice. Prepare a short answer: the client sends an Idempotency-Key, the server stores it with the result, and a repeat gets the stored result back.
Sources and further reading
- RFC 9110: HTTP Semantics (safe and idempotent methods, status codes, If-Match)
- RFC 9457: Problem Details for HTTP APIs
- IETF draft: The Idempotency-Key HTTP Header Field (datatracker, version 08)
- RFC 5789: PATCH Method for HTTP
- RFC 6585: Additional HTTP Status Codes (429 Too Many Requests)
- Google AIP-158: Pagination
- Google AIP-121: Resource-oriented design
- Google AIP-136: Custom methods
- PostgreSQL 18 documentation: Constraints (unique constraints)
- FastAPI 0.162.0 on PyPI