What Is a Web API?
A web API is like a phone line into your program. Other programs call it over the internet to ask questions or send data. This lesson teaches the vocabulary: HTTP methods, URLs, status codes. No code yet.
REST-style HTTP API with JSON. GET/POST/PUT/DELETE, status codes, content negotiation. If you know this, skim the tables and jump to the PRIMM-AI+ section to test yourself.
In Chapter 65, James built a CLI for SmartNotes. He types smartnotes add "Python Tips" "My first note" in a terminal and it works. Then his colleague asks: "Can I add notes from my phone?" James pauses. There is no terminal on a phone. The CLI works for people who sit at a computer. It does not work for browsers, mobile apps, chatbots, or other programs.
"In the warehouse," James says, "we had a phone system for order inquiries. Customers did not drive to the loading dock to check their shipments. They called a number, gave an order ID, and got a status update. The phone system was the API. It let people access information without being physically present."
Emma nods. "Same idea. Your CLI is the loading dock: you have to be there to use it. A web API is the phone system: anyone, anywhere, can call in."
HTTP: The Language of the Web
When your browser loads a website, it sends an HTTP request to a server. The server sends back an HTTP response. Every interaction on the web follows this pattern: request in, response out.
A web API uses the same protocol, but instead of sending back a web page, it sends back data (usually JSON). The client could be a browser, a mobile app, a Python script, or another server.
HTTP defines four primary methods. Each one maps to an operation:
| Method | Operation | Example | Warehouse Analogy |
|---|---|---|---|
| GET | Read data | Fetch a list of notes | "What is in stock?" |
| POST | Create data | Add a new note | "I am shipping you a new pallet" |
| PUT | Update data | Replace a note's body | "Replace the label on pallet #42" |
| DELETE | Remove data | Delete a note | "Remove pallet #42 from the dock" |
The method tells the server what you want to do. The URL tells the server what you want to do it to.
GET /notes → Fetch all notes
GET /notes/5 → Fetch note #5
POST /notes → Create a new note
PUT /notes/5 → Update note #5
DELETE /notes/5 → Delete note #5
Notice the pattern: the URL identifies the resource (/notes or /notes/5), and the method identifies the action. This combination of method + URL is called a route.
Status Codes: The Answer Format
When a server handles your request, it sends back a number called a status code. The code tells you what happened without reading the full response.
| Code | Name | Meaning | Warehouse Response |
|---|---|---|---|
| 200 | OK | Request succeeded, here is the data | "Order found. Here are the details." |
| 201 | Created | New resource created successfully | "New item received and cataloged." |
| 404 | Not Found | The requested resource does not exist | "No item with that ID in the warehouse." |
| 422 | Unprocessable Entity | The request data was invalid | "The shipping label is missing required fields." |
Status codes group into families:
- 2xx codes mean success (200, 201, 204)
- 4xx codes mean the client made a mistake (400, 404, 422)
- 5xx codes mean the server had an error (500, 503)
You do not need to memorize all codes. The four in the table above cover most API work. The FastAPI docs page (Lesson 2) shows you which codes each route can return.
Request and Response
Every HTTP interaction has two parts: a request from the client and a response from the server.
A request contains:
| Part | What it is | Example |
|---|---|---|
| Method | What to do | POST |
| URL | What resource | /notes |
| Body (optional) | Data to send | {"title": "Python Tips", "body": "My first note"} |
A response contains:
| Part | What it is | Example |
|---|---|---|
| Status code | What happened | 201 |
| Body | Data returned | {"id": 1, "title": "Python Tips", "body": "My first note", "word_count": 3} |
The body uses JSON (JavaScript Object Notation) as the data format. You already know JSON from Ch 62 (file I/O). It looks like a Python dictionary, and Pydantic (Ch 55) can convert between JSON and Python objects automatically. That connection is why FastAPI uses Pydantic for its request and response models.
Here is a complete round trip:
Client sends:
POST /notes
{"title": "Python Tips", "body": "My first note"}
Server processes:
1. Validates the data (title and body are present)
2. Creates the note (assigns id, calculates word_count)
3. Saves to storage
Server responds:
201 Created
{"id": 1, "title": "Python Tips", "body": "My first note", "word_count": 3}
The client sends data, the server validates it, does the work, and sends back a result. If the client sends bad data (missing title, for example), the server responds with 422 instead of 201, and the body explains what went wrong.
PRIMM-AI+ Practice: Predict the Status Code
Predict [AI-FREE]
Press Shift+Tab to enter Plan Mode.
For each request below, predict the status code the server would return. Write your answers on paper before checking.
| # | Request | Your prediction |
|---|---|---|
| A | GET /notes (5 notes exist) | _____ |
| B | GET /notes/99 (only 5 notes exist) | _____ |
| C | POST /notes with {"title": "Test", "body": "Hello"} | _____ |
| D | POST /notes with {"title": "Test"} (body is missing) | _____ |
| E | DELETE /notes/3 (note 3 exists) | _____ |
Rate your confidence from 1 to 5 for each.
Check your predictions
| # | Request | Status Code | Why |
|---|---|---|---|
| A | GET /notes | 200 OK | Notes exist, server returns them |
| B | GET /notes/99 | 404 Not Found | Note 99 does not exist |
| C | POST /notes with valid data | 201 Created | New note created successfully |
| D | POST /notes with missing body | 422 Unprocessable Entity | Required field missing |
| E | DELETE /notes/3 | 200 OK | Note deleted (some APIs return 204 No Content) |
If you got A, B, and C right, you understand the core pattern. D and E have subtleties: 422 vs 400 for validation errors, and 200 vs 204 for deletions. You will see these in practice in Lesson 3.
Run
Press Shift+Tab to exit Plan Mode.
Open your browser and navigate to any public API. Try this in your terminal:
curl -s https://httpbin.org/get | python -m json.tool
Output:
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org"
},
"origin": "203.0.113.42",
"url": "https://httpbin.org/get"
}
You just sent a GET request and received a JSON response. httpbin.org is a test API that echoes your request back. Try a POST:
curl -s -X POST https://httpbin.org/post -H "Content-Type: application/json" -d '{"title": "Test"}' | python -m json.tool
The response includes a "json" field containing the data you sent. This is the request/response cycle in action.
Investigate
Run /investigate in Claude Code and ask: "What is the difference between a 400 Bad Request and a 422 Unprocessable Entity? When would a server use one versus the other?"
The answer reveals a design decision you will make in Lesson 3 when you build your own routes.
Modify
Take the curl POST command above. Change the body to send {"title": "Test", "body": "Hello World", "tags": ["python", "notes"]}. Run it and compare the response. What changed in the echoed JSON? This is exactly the kind of data your SmartNotes API will accept.
Make [Mastery Gate]
Without looking at the tables above, write a reference card on paper (or a text file) listing:
- The four HTTP methods and what each does
- Four status codes and what each means
- The three parts of a request and the two parts of a response
Then check your card against this lesson. If you got 9 out of 9, you are ready for Lesson 2.
Try With AI
If Claude Code is not already running, open your terminal, navigate to your SmartNotes project folder, and type claude. If you need a refresher, Chapter 44 covers the setup.
Prompt 1: Map CLI to API
My SmartNotes CLI has these commands:
- smartnotes add "title" "body"
- smartnotes list
- smartnotes search "query"
- smartnotes export --format json
Map each CLI command to an HTTP route. For each one,
tell me: the HTTP method, the URL path, whether
it needs a request body, and what status code a
successful response would return.
What you're learning: CLI commands and API routes solve the same problems with different interfaces. This mapping exercise builds the bridge between what you already know (CLI) and what you are about to build (API). The AI may suggest route patterns you had not considered, like using query parameters for search instead of a request body.
Prompt 2: Status Code Scenarios
I am building a note-taking API. For each scenario,
tell me the correct HTTP status code and explain why:
1. User requests GET /notes and there are zero notes
2. User sends POST /notes with an empty title
3. User sends DELETE /notes/5 but note 5 was already deleted
4. User sends GET /notes?tag=python and no notes have that tag
5. The server crashes while saving a note
What you're learning: Status codes encode specific meanings. Scenario 1 is tricky: an empty list is still a valid response (200, not 404). Scenario 3 tests idempotency. The AI's explanations reveal design choices you will face when building routes.
Prompt 3: Design a Different API
I understand HTTP methods, URLs, status codes, and
request/response bodies. Design an API for a completely
different domain: a recipe manager. List 5 routes with
their method, URL, request body (if any), and
success/error status codes. Use the same patterns as
SmartNotes but apply them to recipes.
What you're learning: API design is a transferable skill. By applying the same patterns to a different domain, you confirm that HTTP concepts are not specific to notes. The AI may introduce patterns like nested routes (/recipes/5/ingredients) that preview more advanced API design.
James looks at the table of HTTP methods. "GET is checking the warehouse inventory. POST is receiving a new shipment. PUT is relabeling an existing pallet. DELETE is removing one from the dock."
"Exactly," Emma says. "And the status codes are the warehouse clerk's responses. 200: here is your item. 404: we do not have that. 422: your request form is filled out wrong."
She tilts her head. "I remember when I first learned REST. I spent two hours trying to decide whether updating a note should use PUT or PATCH. Turned out neither choice mattered for that project. The important thing was picking one and being consistent." She pauses. "The real skill is not memorizing codes. It is knowing which questions matter and which ones you can defer."
"So now I know what an API IS," James says. "But I have not built one."
"Next lesson. You will have a running API in ten minutes."