APIs
An API (Application Programming Interface) is a contract: a defined set of requests a client is allowed to make of a service, and the responses it can expect back, without needing to know anything about how that service is actually implemented. It's the same idea as a function signature, just exposed across a network boundary instead of within one process — and that network boundary is what turns "just call a function" into an entire module's worth of design decisions.
Most APIs on the web ride on top of HTTP/HTTPS: a client sends a request with a method, a path, headers, and optionally a body, and the server replies with a status code, headers, and optionally a body. Everything else in this module — gateways, REST vs. GraphQL, idempotency, rate limiting — is really about refining pieces of that one basic exchange.
The contract is the point​
The value of an API isn't the code behind it — it's that the client and server can change independently as long as neither breaks the contract. A team can rewrite their entire service's internals, swap databases, or rearchitect from a monolith to microservices, and as long as the API's requests and responses stay the same, every client keeps working without a single line of its own code changing. This decoupling is what makes horizontal scaling practical at an organizational level, not just a machine level: teams can scale independently the same way servers do, because the API is the stable interface between them.
Breaking the contract — renaming a field, changing what a status code means, removing a parameter — breaks every client that depends on it, which is why API versioning and backward compatibility (covered in API Design) are treated as first-class engineering concerns, not an afterthought.
HTTP methods carry meaning​
Part of the contract is which HTTP method is used for which kind of operation. Interviewers notice when a candidate says "the client sends a POST and gets back a 201" instead of "the client saves the data" — it's more precise, and it signals fluency with the actual protocol:
| Method | Purpose | Typical success status |
|---|---|---|
GET | Retrieve a resource, no side effects | 200 OK |
POST | Create a resource, or trigger a non-idempotent action | 201 Created |
PUT | Replace a resource entirely | 200 OK / 204 No Content |
PATCH | Partially update a resource | 200 OK |
DELETE | Remove a resource | 204 No Content |
Some of these methods carry a stronger guarantee than just "does the thing": GET, PUT, and DELETE are specified to be idempotent — calling them once or a hundred times should leave the system in the same state — while POST generally isn't. That distinction turns out to matter a lot for retry logic, and gets its own full treatment in Idempotency.
Status codes as a contract too​
The status code range tells the client, at a glance and without parsing a body, roughly what happened:
- 2xx — success. The request was understood and processed.
- 3xx — redirection. The client needs to look somewhere else.
- 4xx — client error. The request itself was malformed, unauthorized, or asked for something that doesn't exist — retrying it unmodified won't help.
- 5xx — server error. Something broke on the server's side; a retry might succeed.
That 4xx/5xx split is a genuinely useful piece of design vocabulary: it's the difference between "the client should fix its request" and "the client can safely retry as-is," which is exactly the kind of distinction a well-designed retry policy (and later, Rate Limiting's 429 status) depends on.
APIs aren't only for external clients​
It's easy to picture an API as "the thing a mobile app calls," but internally, every service-to-service call in a microservices architecture is also an API — and often a more heavily used one than anything a human client hits directly. Treating internal calls with the same contract discipline (explicit versioning, stable error formats, documented expectations) is what keeps a large distributed system's services independently deployable instead of secretly coupled through undocumented behavior.
Why this matters in an interview​
Naming an API's shape explicitly — "the client hits POST /orders, gets a 201 with the new order's ID" — is a small habit that consistently reads as more senior than describing the same interaction in prose. It also forces you to notice the harder questions early: is this operation idempotent, does it need to be paginated, what does the error response look like — all of which are exactly what the rest of this module works through in detail.
Designing behind a stable API contract: pros and cons​
Pros
- Client and server evolve independently as long as the contract holds
- Hides implementation details, so internals can be rewritten freely
- Gives teams (and services) a clear, testable boundary of responsibility
Cons
- Any breaking change to the contract breaks every client depending on it
- Requires upfront design discipline — naming, structure, and errors are hard to change later
- Versioning and backward compatibility become ongoing maintenance work
Further Reading​
- MDN Web Docs — HTTP request methods — the authoritative reference for method semantics and idempotency guarantees.
- MDN Web Docs — HTTP response status codes — a complete reference for what each status code range signals to a client.
Saved locally in your browser — visible in the sidebar as you go.