API Basics
π Table of Contents
Behind every app on your phone is a quiet conversation happening over the internet β and the language of that conversation is the API. This post covers three essential API topics every system designer must know. You will start with What Is an API? β the contract that lets two programs talk, the request & response cycle, and the JSON format that carries data between them. Next you will learn REST & HTTP β the most common API style on the web, built on HTTP methods like GET and POST, resource URLs, and status codes that tell the client what happened. Finally you will explore API Authentication β how a server knows who is calling and whether they are allowed, covering API keys, tokens, JWT, and OAuth. Each topic is explained with real-world analogies, step-by-step examples, and clear diagrams β starting from zero.
π 1. What Is an API?
Almost nothing you do online is handled by a single program. Your weather app does not measure the temperature itself β it asks a weather company. Your travel app does not own any airplanes β it asks dozens of airlines for their prices. The mechanism that lets one program ask another for data or an action, in a structured and predictable way, is the API. In this section we will build that idea from scratch β what an API is, why every modern system depends on them, and exactly what happens during a single API call.
1.1 π― Introduction
Imagine you open a weather app and it shows 22Β°C and sunny. Your phone did not measure that temperature. Instead, the app sent a message over the internet to a weather company's server β something like "give me the current weather for Tokyo" β and the server replied with the data. That structured request-and-reply, following rules both sides agreed on in advance, is an API call.
API stands for Application Programming Interface. The key word is interface β a clearly defined boundary through which two programs talk. The app (the caller) never sees how the weather server works inside; it only needs to know how to ask and what shape the answer will take. An API is the contract that defines exactly those two things: what you can ask for, and what you will get back.
This happens everywhere. When you "Log in with Google," your app calls Google's API. When you pay with PayPal on a shopping site, the site calls PayPal's API. When Uber shows your car on a map, it calls Google Maps' API. APIs are the invisible glue connecting the entire internet.
1.2 π‘ Why It Matters
APIs are the backbone of how modern software is built. No company builds everything itself β they connect specialised services together through APIs. The scale is enormous: Google Maps handles billions of API calls per day, Stripe processes payments for millions of businesses entirely through its API, and Twitter/X served over 100 billion API calls per day at its peak. Studies suggest that more than 80% of all internet traffic is API calls between machines, not humans browsing web pages.
- APIs let teams build independently β the mobile team and the backend team agree on an API contract, then work in parallel without blocking each other.
- APIs let companies reuse instead of rebuild β why build a payment system when you can call Stripe's API in an afternoon?
- APIs are how microservices talk β in a large system, hundreds of internal services communicate with each other entirely through APIs.
- APIs create business ecosystems β by exposing an API, a company lets thousands of other developers build on top of it (the way Twilio powers SMS for countless apps).
Why system design cares: In almost every system design problem, one of the first steps is "define the API." Before you discuss databases or scaling, you decide what requests the system accepts and what it returns. The API is the contract everything else is built around.
1.3 π Real-world Analogy
Think of a restaurant menu. The menu lists exactly what you can order and what you will receive. You don't walk into the kitchen, and you don't need to know how the chef cooks β you just point at an item, and the waiter brings it back. The menu is the interface between you (the customer) and the kitchen (the complex system you never see).
An API is exactly that menu for software. It lists the available "dishes" (the things you can request), specifies how to order them, and guarantees the shape of what comes back β all without exposing the kitchen.
| Restaurant World | API World | Role |
|---|---|---|
| π The menu | π API documentation / contract | Defines what can be ordered and what you get |
| π£οΈ Placing an order | π€ API request | The client asks for something specific |
| π§βπΌ Waiter | π The API endpoint | Receives the order, passes it to the kitchen |
| π¨βπ³ Kitchen | βοΈ Server / business logic | Does the actual work, hidden from the customer |
| π½οΈ Food delivered to your table | π₯ API response (often JSON) | The result, in an agreed format |
| β "Sorry, we're out of that" | β οΈ Error response (e.g. 404) | A structured way to say the request failed |
The crucial insight: you only need the menu, not the recipe. As long as the menu (the API) stays the same, the kitchen can completely change how it cooks β new chefs, new equipment, new suppliers β and you never notice. This is why APIs let backend teams rebuild and scale their systems without breaking the apps that depend on them.
1.4 π Key Terms
| Term | Simple Definition | Quick Example |
|---|---|---|
| API | A defined interface that lets one program request data or actions from another | The Google Maps API, the Stripe API |
| Endpoint | A specific URL the client calls to access one capability of the API | https://api.weather.com/v1/forecast |
| Request | The message the client sends asking for something | "Get the forecast for Tokyo" |
| Response | The server's reply β the data asked for, or an error | A JSON object with temperature and conditions |
| Payload / Body | The actual data carried inside a request or response | The JSON describing a new order |
| JSON | A lightweight, human-readable text format for structured data | {"temp": 22, "unit": "C"} |
| Parameter | An input that customises a request | ?city=Tokyo&units=metric |
| Contract | The agreed rules: what to send and what comes back | The API documentation |
| Rate limit | A cap on how many requests a client may make in a time window | "100 requests per minute" |
Remember: An API is not a specific technology β it is an idea. REST, GraphQL, gRPC, and even a library function call are all APIs. They all share the same essence: a defined way for one piece of software to use another without knowing its internals.
1.5 π’ How It Works
Let us trace exactly what happens when your weather app fetches today's forecast for Tokyo. This single round-trip is the heart of every API call.
| Step | What Happens |
|---|---|
| β Build request | The app constructs a request to the weather API's endpoint, adding parameters: GET /v1/forecast?city=Tokyo&units=metric |
| β‘ Add credentials | The app attaches an API key in a header so the server knows who is calling (covered in Section 3). |
| β’ Send over HTTP | The request travels over the internet to the weather company's server using HTTPS. |
| β£ Server processes | The server validates the key, reads the parameters, looks up Tokyo's forecast in its database, and formats the result. |
| β€ Return response | The server sends back a status code (200 OK) and a JSON body with the data. |
| β₯ Client parses | The app reads the JSON, pulls out temp and condition, and displays "22Β°C, Sunny" on screen. |
Here is what the request and the JSON response actually look like on the wire:
Key insight: The app and the weather server may be written in completely different languages, run on different hardware, and be owned by different companies. They cooperate perfectly because they both agree on the contract: how to ask (the endpoint and parameters) and what comes back (the JSON shape). That agreement is the entire value of an API.
1.6 π Types & Variations
"API" is a broad idea, so it shows up in several flavours. We can group them two ways: by the architecture style they use, and by who is allowed to call them.
A. By Architecture Style
REST
The most common web API style. Uses HTTP methods and resource URLs, returns JSON. Simple and universal β covered in depth in Section 2.
GraphQL
The client asks for exactly the fields it needs in one query β no more, no less. Used by GitHub and Shopify to avoid over-fetching.
gRPC
A fast, binary protocol built for service-to-service calls inside large systems. Used heavily between microservices at Google.
SOAP
An older, XML-based, very strict style. Still common in banking and enterprise systems where formal contracts matter.
WebSocket
Keeps a two-way connection open for real-time data β live chat, stock tickers, multiplayer games β instead of one request per reply.
Library API
Not over the network at all β the functions a code library exposes for your program to call directly, like requests.get().
B. By Access Level
Public / Open API
Open to any external developer, usually with a key and rate limits. Example: the OpenWeather or Google Maps APIs.
Private / Internal API
Used only inside one company, between its own services. Most microservice traffic uses private APIs never exposed publicly.
Partner API
Shared with specific business partners under an agreement. Example: an airline exposing fares only to approved travel sites like Expedia.
For this post: When people say "API" on the web, they almost always mean a REST API returning JSON over HTTP. That is what Section 2 dives into. The other styles exist for specific needs β GraphQL for flexible queries, gRPC for fast internal calls, WebSocket for real-time streams.
1.7 π¨ Illustrated Diagram
The diagram below shows a single API call end to end: the client app sends a request to a specific API endpoint, the server runs its logic and reads the database, and a JSON response travels back. The client never touches the database directly β the API is the only door in.
Reading the diagram: The client sends a request with its API key β to the endpoint, which validates and forwards it β‘ to the server. The server queries β’ the database and gets rows back β£, then returns a clean JSON response β€ to the client. The endpoint is the public "menu"; everything to its right is the hidden kitchen.
1.8 β When to Use
You expose or call an API whenever two pieces of software need to cooperate without being merged into one. That covers almost every real system, but it helps to know when an API is the right tool β and when it is overkill.
| Use an API when⦠| You may not need one when⦠|
|---|---|
| A mobile app or website must talk to a backend server | Two functions live in the same program and can just call each other directly |
| You want to reuse another company's service (payments, maps, SMS) | The "integration" is a one-off script run manually once |
| You are splitting a system into microservices that must communicate | The data never leaves a single tiny script |
| You want external developers to build on top of your platform | Exposing the capability would create security or cost risk you can't control |
| Different teams need a stable contract to work in parallel | The contract would change every day β stabilise the design first |
Rule of thumb: If a boundary exists between two systems β different apps, different teams, different companies, or different services β put a well-defined API across it. The API becomes the stable promise that lets both sides change independently.
1.9 ποΈ Real-world Example β Booking a Flight on a Travel Site
Travel sites like Expedia or Skyscanner own no airplanes and run no payment networks. They are, in large part, an orchestra of API calls. Here is what happens when you search for a flight and book it:
| Step | Actor | What Happens |
|---|---|---|
| β | π± Your Browser | Sends GET /search?from=NRT&to=JFK&date=2026-06-15 to the travel site's API |
| β‘ | βοΈ Travel Site Server | Fans out calls to many airline APIs at once, asking each for fares on that route |
| β’ | βοΈ Airline APIs | Each airline returns JSON with its available flights and prices |
| β£ | βοΈ Travel Site Server | Merges and sorts all results, sends one combined JSON list back to your browser |
| β€ | π€ You | Pick a flight and click "Pay" β browser sends POST /bookings with your choice |
| β₯ | π³ Stripe / PayPal API | The server calls a payment API to charge your card securely |
| β¦ | π§ Email / SMS API | After payment succeeds, the server calls a messaging API to send your confirmation |
| β§ | π± Your Browser | Receives a 201 Created response with your booking reference |
Notice: A single flight booking triggered API calls to airlines, a payment provider, and a messaging service β none of which the travel site built itself. This is the real power of APIs: complex products are assembled by combining specialised services through their interfaces.
New terms above? The HTTP methods (GET,POST) and status codes (201 Created) are explained fully in Section 2. The API keys and tokens that keep these calls secure are covered in Section 3. For now, just notice how many independent APIs cooperate to serve one user action.
1.10 βοΈ Trade-offs
| β Advantages | β Disadvantages |
|---|---|
| Decoupling β the kitchen can change completely as long as the menu stays the same; backends evolve without breaking clients | Network dependency β every call is a round-trip that can be slow, fail, or time out |
| Reuse β call Stripe, Maps, or Twilio instead of building payments, mapping, or SMS yourself | Versioning pain β once others depend on your API, changing it can break them; you must version carefully |
| Parallel work β teams agree on a contract, then build both sides independently | Security surface β every public endpoint is a door attackers can probe; needs auth, rate limits, validation |
| Ecosystem β exposing an API lets outside developers extend your platform | Hidden cost β third-party APIs often charge per call and impose rate limits |
| Encapsulation β internal complexity and data stay hidden behind a clean interface | Debugging is harder β a failure may live in another company's service you cannot see into |
1.11 π« Common Mistakes
| # | β Common Mistake | β The Reality |
|---|---|---|
| 1 | "API" means a website | An API is an interface for programs, not people. A website is for humans to read; an API returns structured data (JSON) for other software to use. |
| 2 | API = REST | REST is just one popular style. GraphQL, gRPC, SOAP, WebSocket, and even a local library function are all APIs. REST is common, not synonymous. |
| 3 | The client needs to know how the server works | The whole point is that it does not. The client only knows the contract β the endpoint and the data shape. The server's internals stay hidden. |
| 4 | Skipping the contract and "just coding" | Without an agreed API contract, the frontend and backend drift apart and integration fails. Define the request and response shape first. |
| 5 | Returning raw database rows directly | A good API returns a clean, stable shape β not your internal table columns. Otherwise every database change breaks every client. |
| 6 | Ignoring errors and rate limits | Real API calls fail, time out, and get throttled. Robust clients handle error responses and retries β they don't assume every call succeeds. |
1.12 π Summary
- An API is a contract β it defines what one program can ask another for, and what it gets back.
- It hides the kitchen β callers use the interface without knowing the internals, so backends can change freely.
- JSON is the common language β most web APIs exchange data as lightweight, human-readable JSON.
- APIs come in styles and access levels β REST, GraphQL, gRPC, SOAP, WebSocket; and public, private, or partner.
- Modern systems are assembled from APIs β products combine specialised services (payments, maps, messaging) instead of building everything in-house.
1.13 ποΈ Design Challenge
π¬ Challenge: Design the API for a movie ticket booking app
You are designing the API behind an app like BookMyShow or Fandango. Think through the following:
- What endpoints would you expose? (Hint: think about browsing movies, picking a show, and booking seats.)
- For each endpoint, what would the request carry, and what JSON would the response return?
- Which third-party APIs would you call instead of building yourself?
- What should happen if two users try to book the same seat at the same time?
ποΈ Show Answer
Endpoints you might expose:
- π¬
GET /moviesβ list movies now showing - π
GET /movies/{id}/shows?city=Tokyoβ showtimes for a movie - πΊ
GET /shows/{id}/seatsβ which seats are free - ποΈ
POST /bookingsβ reserve seats and pay
Example contract for booking: the request body carries the show ID and chosen seats; the response returns a booking reference and status.
Third-party APIs to call:
- π³ A payment API (Stripe/PayPal) to charge the card
- π§ An email/SMS API (SendGrid/Twilio) to deliver the ticket
- πΊοΈ A maps API to show the cinema location
Two users, one seat:
The seat must be locked the moment one user starts checkout, so the second user's request returns a 409 Conflict ("seat no longer available"). This is a concurrency problem solved with short-lived locks or a database transaction β patterns we will revisit in later phases of the series.
1.14 βοΈ Cloud Service Mapping
In the cloud, you rarely expose your servers directly. Instead, you put a managed API layer in front of them that handles routing, validation, and throttling. These are the core services for hosting and managing an API on each platform:
| Need | AWS (Primary) | GCP | Azure |
|---|---|---|---|
| Host & manage an API β a front door that receives all API calls | Amazon API Gateway | Apigee / API Gateway | Azure API Management |
| Run the code behind it β serverless function that responds to calls | AWS Lambda | Cloud Functions | Azure Functions |
| Build a GraphQL API β managed flexible-query endpoint | AWS AppSync | Apigee (with GraphQL) | Azure API Management |
Simplest AWS picture: A client calls API Gateway (the public endpoint) β Gateway validates the request and forwards it to a Lambda function (your logic) β Lambda returns JSON β Gateway sends it back to the client. That is a complete, scalable API with no servers to manage.
π 2. REST & HTTP
Now that you know what an API is, the next question is: what rules do most web APIs actually follow? The answer is REST, an architectural style that runs on top of the HTTP protocol. Together they give the web a simple, uniform vocabulary: address a resource with a URL, act on it with an HTTP method like GET or POST, and read the status code to learn what happened. In this section you will learn the anatomy of an HTTP request, the methods and status codes that power every REST API, what makes an API truly RESTful, and how REST compares to alternatives like GraphQL, gRPC, and WebSocket β so you can choose the right one in a system design.
2.1 π― Introduction
Imagine you are building an online bookstore. You need to list all books, show one book's details, add a new book, update a price, and remove a book that's out of print. That is five different actions on one kind of thing β a "book." REST gives you a clean, predictable way to express all five using nothing but a URL and an HTTP method.
REST stands for Representational State Transfer. It is not a protocol or a library β it is a style, a set of conventions for designing APIs. HTTP (HyperText Transfer Protocol) is the actual protocol the browser already uses to load every web page, and REST simply reuses it. In a REST API, each "thing" is a resource with its own URL (/books/42), and the HTTP method you use (GET, POST, PUT, DELETE) says what you want to do to it.
π REST vs HTTP: HTTP is the transport β the rules for sending a request and getting a response. REST is a discipline for how to use HTTP well: nouns in the URL, verbs as HTTP methods, meaningful status codes, and no server-side session state. You can use HTTP without being RESTful, but you cannot be RESTful without HTTP.
2.2 π‘ Why It Matters
REST is the lingua franca of the web. The vast majority of public web APIs are REST β including GitHub, Stripe, Twitter/X, and Shopify. Surveys of public APIs consistently put REST well above 70% of all of them. When a system design problem says "design the API," the default expectation is a REST API returning JSON over HTTP.
- REST is uniform β once you learn GET/POST/PUT/DELETE, every REST API feels familiar; you don't relearn the basics per service.
- REST is stateless β each request carries everything the server needs, so any server can handle any request. That is what lets you put dozens of identical servers behind a load balancer and scale horizontally.
- REST is cacheable β GET responses can be cached by browsers, CDNs, and proxies, cutting load dramatically.
- REST uses plain HTTP β it works with every language, every browser, every tool (
curl, Postman) with zero special setup.
Why system design cares: Statelessness is the single most important property here. Because a REST server keeps no memory of past requests, you can run many copies of it and route any request to any copy. This is the foundation of horizontal scaling β a theme that returns in almost every later topic in this series.
2.3 π Real-world Analogy
Think of a library front desk. Every book is a resource with a shelf address. You don't wander the stacks yourself β you make a request at the desk, and you phrase it as an action on a specific book: "show me book #42," "add this new book," "update this book's record," "remove this book." The librarian performs the action and hands you a slip telling you how it went β "done," "not found," or "you're not allowed."
| Library World | REST / HTTP World | Meaning |
|---|---|---|
| π A specific book | π Resource URL β /books/42 | The thing you are acting on |
| π "Show me this book" | GET /books/42 | Read, without changing anything |
| β "Add this new book" | POST /books | Create a new resource |
| βοΈ "Update this record" | PUT /books/42 | Replace/modify the resource |
| ποΈ "Remove this book" | DELETE /books/42 | Delete the resource |
| π§Ύ The slip: "done / not found / not allowed" | π Status code β 200 / 404 / 403 | How the request went |
Notice the pattern: the book (noun) goes in the URL, and the action (verb) is the HTTP method. A well-designed REST API never puts verbs in the URL β you never see /getBook or /deleteBook42, because the method already says the verb.
2.4 π Key Terms
| Term | Simple Definition | Quick Example |
|---|---|---|
| HTTP | The protocol browsers and servers use to exchange requests and responses | Every web page load is HTTP(S) |
| REST | A style for designing APIs using HTTP methods and resource URLs | GitHub's API is RESTful |
| Resource | Any "thing" the API exposes, identified by a URL | /users/7, /orders/55 |
| HTTP Method | The verb that says what action to take on a resource | GET, POST, PUT, PATCH, DELETE |
| Status Code | A 3-digit number in the response saying how it went | 200 OK, 404 Not Found, 500 Error |
| Header | Key-value metadata attached to a request or response | Content-Type: application/json |
| Body / Payload | The data sent with a request or returned in a response | The JSON for a new book |
| Stateless | The server keeps no memory between requests; each is self-contained | Every call re-sends its auth token |
| Idempotent | Doing it once or many times gives the same result | GET, PUT, DELETE are idempotent; POST is not |
| CRUD | The four basic data operations: Create, Read, Update, Delete | Maps to POST, GET, PUT, DELETE |
2.5 π’ How It Works
A REST call is just a well-structured HTTP request and response. Let us break down the four parts that make it work: the request anatomy, the methods, the status codes, and the rules that keep it stateless.
A. Anatomy of a Request & Response
Every HTTP request has four parts: a method + path (the action and the resource), headers (metadata like content type and auth), and an optional body (data, used by POST/PUT). The response mirrors it: a status code, headers, and a body. Here is a request to add a book to our store:
And the server's response β a 201 Created status with the newly created resource in the body:
B. HTTP Methods & CRUD
Each HTTP method maps to one of the four basic data operations, known as CRUD. This mapping is the heart of REST.
| Method | CRUD | What It Does | Example | Safe / Idempotent |
|---|---|---|---|---|
| GET | Read | Fetch a resource; never changes data | GET /books/42 | β Safe & idempotent |
| POST | Create | Create a new resource | POST /books | β Not idempotent |
| PUT | Update | Replace a resource entirely | PUT /books/42 | β Idempotent |
| PATCH | Update | Modify part of a resource | PATCH /books/42 | β οΈ Usually not |
| DELETE | Delete | Remove a resource | DELETE /books/42 | β Idempotent |
Idempotency matters in design: If a network hiccup makes a client retry a request, an idempotent method (GET, PUT, DELETE) is safe to repeat β the result is the same. POST is not: retrying "create order" could charge a customer twice. This is why payment APIs add an idempotency key to make POST safe to retry.
C. HTTP Status Codes
The status code is the first thing a client reads. They come in five families, grouped by the first digit:
| Range | Meaning | Common Codes |
|---|---|---|
| 2xx β | Success β the request worked | 200 OK Β· 201 Created Β· 204 No Content |
| 3xx βͺοΈ | Redirection β look elsewhere | 301 Moved Permanently Β· 304 Not Modified |
| 4xx π | Client error β the caller did something wrong | 400 Bad Request Β· 401 Unauthorized Β· 403 Forbidden Β· 404 Not Found Β· 429 Too Many Requests |
| 5xx π₯ | Server error β the server failed | 500 Internal Server Error Β· 502 Bad Gateway Β· 503 Service Unavailable |
The 4xx vs 5xx rule: 4xx means "you made a mistake" (fix your request β wrong URL, bad data, missing auth). 5xx means "we made a mistake" (the server broke; retrying later may help). Returning the right family is critical β a server that returns 200 for an error makes every client misbehave.
D. Statelessness & REST Constraints
What makes an API truly "RESTful" is a small set of constraints. The most important for system design is statelessness: the server stores nothing about the client between requests. Every request must carry its own context β including who the caller is (the auth token). The benefits compound:
- Stateless β any server can handle any request, so you scale by simply adding more servers.
- Uniform interface β resources as URLs, actions as methods, consistent everywhere.
- Cacheable β responses say whether they can be cached, letting CDNs and browsers serve them without hitting the server.
- Clientβserver separation β the frontend and backend evolve independently as long as the contract holds.
2.6 π Types & Variations β REST vs Other API Styles
REST is the default, but it is not the only option. In system design you are expected to know the main alternatives and, more importantly, when each one is the better choice. You rarely implement these by hand β you justify picking one. Here are the four styles you should recognise:
REST
Resources + HTTP methods + JSON. Simple, cacheable, universal. The default for public web and mobile APIs. Can over-fetch (returns fixed fields) or need many round-trips.
GraphQL
One endpoint; the client asks for exactly the fields it wants in a single query. Solves over-fetching and under-fetching. Used by GitHub and Shopify for rich, mobile-friendly clients.
gRPC
Binary protocol over HTTP/2 using Protocol Buffers. Very fast and compact. Ideal for internal service-to-service calls in microservices, not for browsers.
WebSocket
A persistent, two-way connection for real-time data. The server can push without being asked. Used for chat, live feeds, notifications, and multiplayer games.
Side by side, the trade-offs become clear:
| Style | Transport | Data Format | Communication | Best For |
|---|---|---|---|---|
| REST | HTTP/1.1 | JSON (text) | Request β response | Public APIs, CRUD, web & mobile |
| GraphQL | HTTP | JSON (text) | Request β response (flexible query) | Mobile clients, avoiding over-fetch |
| gRPC | HTTP/2 | Protobuf (binary) | Request β response + streaming | Internal microservice calls, low latency |
| WebSocket | TCP (upgraded from HTTP) | Any (often JSON) | Two-way, persistent, real-time | Chat, live updates, presence, games |
SOAP, briefly: You may still meet SOAP β an older, strict, XML-based style used in some banking and enterprise systems. For new designs it is rarely chosen, but it is worth recognising the name.
2.7 π¨ Illustrated Diagram
The diagram below shows the same resource β a book β acted on by the four main HTTP methods. One URL pattern, four verbs, four outcomes. This is the uniform interface that makes REST so easy to learn.
Reading the diagram: The client uses one resource path (/books and /books/42) with different methods to read, create, update, and delete. The server translates each into a database operation and replies with the matching status code. Same noun, different verbs β that is REST in one picture.
2.8 β When to Use
REST is the right default for the large majority of APIs. But knowing when to reach for GraphQL, gRPC, or WebSocket instead is exactly the kind of decision a system design expects you to justify. Use this decision guide:
| Reach for REST when⦠| Reach for an alternative when⦠|
|---|---|
| You are building a public API or a standard CRUD service | Mobile clients over-fetch or need many round-trips β GraphQL |
| You want caching, simplicity, and universal tooling | Two internal microservices need fast, low-latency calls β gRPC |
| Clients are browsers, mobile apps, or third-party developers | The client needs live server-pushed updates β WebSocket |
| Resources map cleanly to nouns (users, orders, books) | You need bidirectional streaming or real-time presence β WebSocket |
A quick way to choose, phrased as questions you can ask in a design discussion:
- Is it a public/CRUD API for varied clients? β REST.
- Do clients need flexible, precise field selection? β GraphQL.
- Is it internal, high-throughput, latency-sensitive service-to-service traffic? β gRPC.
- Does the server need to push data in real time? β WebSocket (or Server-Sent Events for one-way push).
Rule of thumb: Start with REST. Switch only when a concrete requirement forces it β real-time push (WebSocket), internal speed (gRPC), or client-driven queries (GraphQL). "We use REST for the public API and gRPC between internal services" is a very common, very defensible architecture.
2.9 ποΈ Real-world Example β The GitHub REST API
GitHub's public REST API is a textbook example of clean design. Every "thing" on GitHub β a repository, an issue, a user β is a resource with a predictable URL, and you act on it with standard HTTP methods. Here is a typical sequence when an app manages issues on a repo:
| Step | Request | What Happens |
|---|---|---|
| β | GET /repos/octocat/hello/issues | Lists all open issues β returns 200 OK with a JSON array |
| β‘ | GET /repos/octocat/hello/issues/7 | Fetches issue #7 in detail β 200 OK, or 404 if it doesn't exist |
| β’ | POST /repos/octocat/hello/issues | Creates a new issue from the JSON body β returns 201 Created |
| β£ | PATCH /repos/octocat/hello/issues/7 | Updates issue #7's title or state β 200 OK |
| β€ | (no token) | Any write without a valid token returns 401 Unauthorized |
| β₯ | (too many calls) | Exceeding the rate limit returns 429 Too Many Requests |
Creating an issue looks like this on the wire β note the noun in the URL, the verb as the method, and JSON in both directions:
Notice the discipline: nouns in the URL (/issues), verbs as methods (POST to create), correct status codes (201, 401, 429), and JSON bodies. That consistency is exactly why developers can pick up the GitHub API in minutes β and why REST became the web's default.
2.10 βοΈ Trade-offs
| β Advantages | β Disadvantages |
|---|---|
| Simple & universal β plain HTTP and JSON; works with every language and tool | Over-fetching β a fixed endpoint may return more fields than the client needs |
| Stateless β scalable β any server handles any request; scale by adding servers | Under-fetching β getting related data may take several round-trips (the "N+1" problem) |
| Cacheable β GET responses cache cleanly in browsers, CDNs, and proxies | No built-in real-time β push requires WebSocket or polling on top |
| Uniform & predictable β same method/status conventions across every REST API | Text overhead β JSON is larger and slower to parse than binary formats like Protobuf |
| Great tooling β curl, Postman, browser dev tools all speak HTTP natively | Loose by convention β "RESTful" is a style, so poorly designed REST APIs are common |
2.11 π« Common Mistakes
| # | β Common Mistake | β The Reality |
|---|---|---|
| 1 | Putting verbs in the URL | Endpoints like /getBook or /createUser break REST. The URL is the noun (/books); the method is the verb (GET, POST). |
| 2 | Using GET to change data | GET must be safe β it never modifies anything. Crawlers and caches replay GETs freely; using one to delete or update causes chaos. |
| 3 | Returning 200 for everything | Errors need the right status. Return 404 for not found, 400 for bad input, 401/403 for auth, 500 for server faults β not 200 with an "error" field. |
| 4 | Storing session state on the server | REST is stateless. Keeping per-client state on one server breaks horizontal scaling. Put state in a token or shared store, not in server memory. |
| 5 | Ignoring idempotency on retries | Retried POSTs can duplicate orders or charges. Use idempotency keys, or design create operations to be safely repeatable. |
| 6 | No versioning | Changing a live API breaks every client. Version it (/v1/books) so you can evolve without breaking existing callers. |
2.12 π Summary
- REST is a style, HTTP is the protocol β nouns in the URL, verbs as methods, JSON in the body.
- Methods map to CRUD β GET reads, POST creates, PUT/PATCH update, DELETE removes.
- Status codes tell the story β 2xx success, 4xx your fault, 5xx server's fault.
- Statelessness enables scale β no server-side session means any server can serve any request.
- Know the alternatives β GraphQL for flexible queries, gRPC for internal speed, WebSocket for real-time push; start with REST and switch only when a requirement demands it.
2.13 ποΈ Design Challenge
β Challenge: Design a RESTful API for a to-do app
You are designing the API behind a simple to-do list app where users create, view, complete, and delete tasks. Think through the following:
- What resource URLs and HTTP methods would you expose for the four actions?
- Which status code should each return on success β and what should happen for a task that doesn't exist?
- Which of your endpoints are idempotent, and why does that matter?
- If the app later needs a live "shared list" that updates instantly across devices, which API style would you add β and why not just REST?
ποΈ Show Answer
Endpoints (noun in URL, verb as method):
| Action | Request | Success Code |
|---|---|---|
| List tasks | GET /tasks | 200 OK |
| Create a task | POST /tasks | 201 Created |
| View one task | GET /tasks/9 | 200 OK (404 if missing) |
| Mark complete | PATCH /tasks/9 | 200 OK |
| Delete a task | DELETE /tasks/9 | 204 No Content |
Idempotency: GET, PUT, and DELETE are idempotent β calling them repeatedly leaves the system in the same state. That matters because a client can safely retry them after a network failure. POST is not idempotent: a retried "create task" could add the task twice, so you might add an idempotency key.
Live shared list: Plain REST can't push updates β the client would have to poll GET /tasks repeatedly, which is wasteful and laggy. Add a WebSocket connection so the server pushes changes to every device the instant a task changes. REST still handles the create/update/delete; WebSocket handles the real-time broadcast.
2.14 βοΈ Cloud Service Mapping
Cloud platforms provide managed gateways that host REST APIs and handle routing, throttling, and (in some cases) WebSocket and gRPC traffic, so you don't run that plumbing yourself:
| Need | AWS (Primary) | GCP | Azure |
|---|---|---|---|
| Host a REST API β managed HTTP front door | API Gateway (REST / HTTP API) | Apigee / API Gateway | Azure API Management |
| Real-time / WebSocket β push connections | API Gateway (WebSocket API) | Cloud Run / Firebase | Azure Web PubSub |
| GraphQL endpoint β managed flexible queries | AWS AppSync | Apigee (with GraphQL) | Azure API Management |
Simplest AWS picture: Expose a REST API on API Gateway β it routes each method to a Lambda function or backend service β the function returns JSON with the right status code. For real-time features, switch the same gateway to a WebSocket API.
π 3. API Authentication
An open API is an open door. Once you expose endpoints to the world, the server needs to answer two questions on every single request: who is calling? and are they allowed to do this? The first is authentication, the second is authorization, and together they are what keep your data, your users, and your costs safe. In this section you will learn the main ways APIs prove identity β API keys, tokens, JWT, and OAuth β how a stateless token flow actually works, and which method to choose for a given system.
3.1 π― Introduction
Imagine a photo-printing app asks to access your Google Photos so it can print your pictures. You click "Allow" β and it works. But notice what you never did: you never gave the app your Google password. Instead, Google handed the app a limited token that lets it read your photos and nothing else, which you can revoke at any time. That is API authentication done right, and the mechanism behind it is called OAuth.
Two related ideas sit at the heart of this topic, and mixing them up is the most common beginner error:
- Authentication (AuthN) β "Who are you?" The server verifies your identity, usually by checking a credential like a password, an API key, or a token.
- Authorization (AuthZ) β "What are you allowed to do?" Once identity is known, the server decides which actions and data you may access.
Authentication always comes first β you can't decide what someone is allowed to do until you know who they are. The photo app was authenticated (Google knew which app it was) and authorized for a narrow scope (read your photos, but not delete them or read your email).
3.2 π‘ Why It Matters
Every public endpoint is a target. Industry reports estimate that APIs are now the most common attack surface for web applications, with the majority of organisations reporting an API-related security incident. A single unprotected endpoint can leak millions of user records β and a leaked API key can run up enormous bills on a paid service before anyone notices.
- Data protection β without authentication, anyone who guesses your URL can read or modify your users' data.
- Accountability β identity lets you log who did what, essential for auditing and abuse investigation.
- Rate limiting & billing β you can only enforce "100 requests per minute" or "charge per call" if you know which client is calling.
- Least privilege β scopes and roles let you give each caller exactly the access it needs and no more, limiting the blast radius of a leak.
β οΈ Authentication is never optional in design. In any system design discussion, as soon as you draw an API, you should be ready to say how it authenticates callers. "All endpoints require a bearer token over HTTPS, validated at the API Gateway" is the kind of sentence that shows you think about security from the start.
3.3 π Real-world Analogy
Think of checking into a hotel. At the front desk you show your ID β that is authentication, proving who you are. In return you get a key card β a token. The key card opens your room and the gym, but not other guests' rooms or the staff office β that is authorization, defined by what the card is permitted to do. The card expires at checkout, and the front desk can deactivate it instantly if it's lost.
| Hotel World | API Auth World | Meaning |
|---|---|---|
| πͺͺ Showing your ID at check-in | π Logging in with credentials | Authentication β proving identity |
| π³ The key card you receive | ποΈ Access token (e.g. JWT) | A short-lived proof you can present later |
| πͺ Card opens your room + gym only | π Scopes / permissions | Authorization β what you may access |
| β° Card stops working at checkout | β Token expiry | Access is time-limited by design |
| π« Front desk deactivates a lost card | β»οΈ Token revocation | Access can be withdrawn |
| π€ Showing the card, not your ID, at the gym | π¨ Sending the token on each request | You don't re-prove identity every time |
The key insight: you show your ID once, then carry a key card you present everywhere else. APIs work the same way β you authenticate once to get a token, then attach that token to every later request instead of sending your password again and again.
3.4 π Key Terms
| Term | Simple Definition | Quick Example |
|---|---|---|
| Authentication | Verifying who the caller is | Checking a password or token |
| Authorization | Deciding what the caller may do | "Can read photos, cannot delete" |
| Credential | Any secret used to prove identity | Password, API key, private key |
| API Key | A long secret string identifying a calling application | sk_live_a1b2c3d4 |
| Token | A temporary credential issued after login, sent on each request | A bearer token in a header |
| Bearer Token | A token where "whoever holds it" is granted access | Authorization: Bearer <token> |
| JWT | A self-contained, signed token carrying user data as JSON | eyJhbGci... |
| OAuth 2.0 | A standard for granting an app limited access on your behalf β without sharing your password | "Log in with Google" |
| Scope | A named permission attached to a token | photos.read |
| Refresh Token | A long-lived token used only to get new short-lived access tokens | Renews access without re-login |
3.5 π’ How It Works
Modern APIs almost always use token-based authentication. Let us break down how it works: the difference between AuthN and AuthZ, the token flow itself, what's inside a JWT, and why HTTPS is non-negotiable.
A. Authentication vs Authorization
These two steps happen on every protected request, in order. Authentication answers "who are you?" by validating the token. Authorization then answers "are you allowed to do this?" by checking the token's scopes or the user's role against the action requested. A valid token with the wrong scope returns 403 Forbidden; a missing or invalid token returns 401 Unauthorized.
B. The Token-Based Flow
The flow has two phases β log in once, then reuse the token. This keeps the API stateless: the server doesn't remember the client between calls; the token itself carries the proof.
| Step | What Happens |
|---|---|
| β Log in | The client sends credentials once (e.g. POST /login with email + password). |
| β‘ Issue token | The server verifies them and returns an access token (often a JWT) plus a refresh token. |
| β’ Store token | The client keeps the token (in memory or secure storage). |
| β£ Send on each call | Every later request carries the token in the header: Authorization: Bearer <token>. |
| β€ Validate | The server checks the token's signature and expiry β no database lookup needed for a JWT β then authorizes the action. |
| β₯ Refresh | When the access token expires, the client uses the refresh token to get a new one β no re-login. |
C. Anatomy of a JWT
A JWT (JSON Web Token) is the most common access token format. It is three Base64 parts joined by dots β header.payload.signature. The header says how it's signed, the payload carries claims (who the user is, scopes, expiry), and the signature proves it hasn't been tampered with. Because the signature can be verified with a secret key alone, the server needs no database lookup to trust it β that is what makes JWTs stateless and fast.
β οΈ A JWT payload is encoded, not encrypted. Anyone holding the token can read its contents β only the signature is protected. Never put passwords or secrets in a JWT payload. The signature stops tampering; it does not hide the data.
D. HTTPS Is Mandatory
Every authentication method here sends a secret over the network β an API key, a password, or a bearer token. Over plain HTTP, anyone on the path can read it and impersonate the caller. HTTPS encrypts the entire request, including headers, so the token can't be stolen in transit. Authentication without HTTPS is no security at all.
3.6 π Types & Variations
There are a handful of authentication methods you'll meet in practice. Each fits a different situation β from simple server-to-server calls to letting a third-party app act on a user's behalf.
API Key
A single long secret string sent in a header. Simple, identifies an application (not a user). Great for server-to-server and public data APIs. Easy to leak if careless.
Basic Auth
Username + password Base64-encoded in the header. Simple but sends credentials on every call β only acceptable over HTTPS, and largely superseded by tokens.
Bearer Token / JWT
A signed, expiring token issued after login, sent as Authorization: Bearer. Stateless and scalable β the dominant choice for modern APIs and microservices.
OAuth 2.0
Delegated access: a user lets one app use another on their behalf without sharing a password. Powers "Log in with Google/GitHub." Issues scoped, revocable tokens.
Session Cookie
Classic web approach: the server stores a session and the browser sends a cookie. Stateful β simple for single web apps, harder to scale across many servers.
Mutual TLS (mTLS)
Both client and server present certificates to prove identity. Strong and common for sensitive internal service-to-service traffic in zero-trust networks.
π API key vs token β the key difference: an API key usually identifies an application and is long-lived, while a token (JWT) identifies a user session, carries scopes, and expires. OAuth is not a fourth competitor β it's a framework that issues tokens; the token it hands out is typically a bearer token/JWT.
3.7 π¨ Illustrated Diagram
The diagram below shows the token-based flow end to end: the client logs in once to get a token, then presents that token on every later call to the API, which validates it before responding. The login step and the data step are cleanly separated.
Reading the diagram: The client authenticates once at the auth server β and receives a token β‘. From then on it attaches that token to every API request β’. The API server validates the token's signature and scopes before touching the database β£β€ and returns the result β₯. Notice the API server never sees the password β only the token.
3.8 β When to Use
Picking the right method is a design decision you should be able to justify. The choice comes down to who is calling and on whose behalf. Use this guide:
| Method | Use it when⦠| Avoid it when⦠|
|---|---|---|
| API Key | A server or script calls your API to access public or app-level data | You need to identify individual end users or fine-grained permissions |
| Bearer Token / JWT | Users log into your own app and call your API; stateless microservices | You can't store the token securely on the client |
| OAuth 2.0 | A third-party app needs limited access to a user's data on another service | It's your own first-party app β full OAuth is overkill, a plain token is enough |
| Session Cookie | A traditional server-rendered web app with one backend | You need to scale across many stateless servers or serve non-browser clients |
| Mutual TLS | Sensitive internal service-to-service calls in a zero-trust network | Public clients (browsers, mobile apps) β cert management is impractical |
Rule of thumb: For a typical app β "users log in, mobile/web client calls our API" β use JWT bearer tokens over HTTPS. The moment a third party needs access to a user's data without their password, reach for OAuth 2.0. For pure machine-to-machine, an API key (or mTLS for sensitive internal traffic) is usually enough.
3.9 ποΈ Real-world Example β "Log in with Google" (OAuth 2.0)
Back to the photo-printing app that wants your Google Photos. Here is the OAuth 2.0 flow that lets it read your photos without ever seeing your Google password:
| Step | Actor | What Happens |
|---|---|---|
| β | π± Photo App | Redirects you to Google, asking for the photos.read scope |
| β‘ | π Google | Asks you to log in (on Google's own page) and shows a consent screen: "Photo App wants to view your photos" |
| β’ | π€ You | Click Allow β your password stays with Google, never the app |
| β£ | π Google | Sends the app a one-time authorization code |
| β€ | π± Photo App | Exchanges that code (plus its own secret) for an access token scoped to photos.read |
| β₯ | π± Photo App | Calls GET /photos with the token; Google returns your photos β and only photos |
| β¦ | π€ You (later) | Can revoke the app's access anytime in Google settings, with no password change |
Contrast that with a simple paid API like a weather or payment service, where no end user is involved β you just authenticate the application itself with an API key:
Why OAuth is brilliant: three separate problems are solved at once β the app never learns your password, it gets only the narrow scope you approved, and you can revoke it independently. That separation is exactly why "Log in with Google/Apple/GitHub" is everywhere.
3.10 βοΈ Trade-offs
Token-based authentication (JWT) is the modern default, so it's worth weighing its strengths against the stateful session approach it largely replaced:
| β Advantages of Token-Based Auth | β Disadvantages / Cautions |
|---|---|
| Stateless β the token is self-contained, so any server can validate it; scales horizontally with no shared session store | Hard to revoke early β a valid JWT works until it expires; instant revocation needs a denylist or short lifetimes |
| Cross-domain & mobile friendly β works cleanly for APIs, mobile apps, and multiple services, unlike cookies | Token theft = impersonation β a stolen bearer token is usable by anyone; HTTPS and secure storage are essential |
| Fast validation β signature check needs no database lookup | Payload is readable β encoded, not encrypted; never store secrets in it |
| Fine-grained scopes β permissions travel inside the token | Size β a JWT is larger than a session ID and is sent on every request |
| Decoupled auth β a dedicated auth server can issue tokens many services trust | Clock & key management β expiry checks and signing-key rotation must be handled correctly |
3.11 π« Common Mistakes
| # | β Common Mistake | β The Reality |
|---|---|---|
| 1 | Hardcoding API keys in client code or Git | Keys in front-end JavaScript or committed to a repo are public. Keep secrets server-side, in environment variables or a secrets manager, and rotate any that leak. |
| 2 | Authentication over plain HTTP | Any token or key sent over HTTP can be sniffed and reused. Always require HTTPS for every authenticated endpoint. |
| 3 | Confusing authentication with authorization | Knowing who someone is (AuthN) is not the same as letting them act (AuthZ). A logged-in user must still be checked against scopes/roles for each action. |
| 4 | Putting secrets in a JWT payload | The payload is only Base64-encoded, not encrypted β anyone can read it. Store identifiers and scopes, never passwords or sensitive data. |
| 5 | Tokens that never expire | A non-expiring token is a permanent key if stolen. Use short-lived access tokens plus refresh tokens so leaked tokens die quickly. |
| 6 | No rate limiting per identity | Without per-key/per-user limits, one client can overwhelm your API or rack up costs. Tie rate limits to the authenticated identity. |
3.12 π Summary
- AuthN β AuthZ β authentication proves who you are; authorization decides what you may do.
- Token-based auth is the default β log in once, then send a bearer token (often a JWT) on every request.
- A JWT is signed, not secret β the signature blocks tampering, but the payload is readable; keep secrets out of it.
- OAuth grants delegated access β let a third-party app act for a user with a scoped, revocable token and no password sharing.
- HTTPS, expiry, and scopes are non-negotiable β encrypt the channel, expire tokens, and grant least privilege.
3.13 ποΈ Design Challenge
π Challenge: Design authentication for a fitness platform
You run a fitness platform with a mobile app, a public API for third-party developers, and internal microservices. Think through the following:
- How should your own mobile app users authenticate to your API?
- A third-party app wants to read a user's workout history. How do you let it β without the user giving it their password?
- Your internal "billing service" calls your "user service." How should those internal calls authenticate?
- How do you make sure a stolen token can't be used forever?
ποΈ Show Answer
Mobile app users β JWT bearer tokens. The user logs in once; your auth server issues a short-lived access token (JWT) and a refresh token. The app sends Authorization: Bearer <token> on every call, over HTTPS. Any server can validate the token without a session store.
Third-party access β OAuth 2.0. The third-party app sends the user to your consent screen requesting a scope like workouts.read. The user approves, and the app receives a scoped, revocable token β never the password. The user can revoke it anytime.
Internal service-to-service β mTLS or short-lived service tokens. The billing and user services authenticate each other with mutual TLS certificates (or signed service tokens) inside the private network β no human user is involved.
Limiting stolen tokens: make access tokens short-lived (e.g. 15 minutes) and use refresh tokens to renew. For instant kill-switch, keep a small revocation denylist checked at the gateway. Always require HTTPS and store tokens in secure storage, never in plain local storage.
3.14 βοΈ Cloud Service Mapping
You rarely build authentication from scratch. Cloud platforms offer managed identity services that issue and validate tokens, run OAuth flows, and plug straight into your API gateway:
| Need | AWS (Primary) | GCP | Azure |
|---|---|---|---|
| User sign-up / login & tokens β managed user pools with OAuth/JWT | Amazon Cognito | Identity Platform / Firebase Auth | Microsoft Entra ID (Azure AD B2C) |
| Authorize API calls β validate tokens at the gateway | API Gateway Authorizers | Apigee / API Gateway | API Management policies |
| Service & resource permissions β control who can do what | AWS IAM | Cloud IAM | Azure RBAC |
| Store secrets & keys β keep API keys out of code | AWS Secrets Manager | Secret Manager | Azure Key Vault |
Simplest AWS picture: Users authenticate through Cognito, which issues a JWT β the client sends it to API Gateway, where an authorizer validates the token and scopes before the request ever reaches your Lambda or service. API keys and signing secrets live in Secrets Manager, never in code.
π References
- MDN Web Docs β HTTP & Web APIs β The definitive beginner-to-advanced reference for HTTP methods, status codes, headers, and how web APIs work.
- REST API Tutorial (restfulapi.net) β Clear explanations of REST principles, resource modelling, and HTTP status code usage.
- System Design Interview (Vol. 1) β Alex Xu β Uses APIs as the contract layer in nearly every system design walkthrough.
- OAuth 2.0 & JWT β RFC 6749 and RFC 7519 β The official specifications behind modern token-based API authentication.
- Cloudflare Learning Center β What is an API? β Beginner-friendly, visual explanations of APIs, REST, and authentication.