Module 0.4
How the Web Works
What is HTTP?
Every time you visit a website, call an API, or send data to a server, you're using HTTP (HyperText Transfer Protocol). It's the language that web clients and servers speak to each other.
HTTP is a request-response protocol: a client sends a request, a server sends back a response. That's the entire model. No persistent connection, no ongoing conversation β just ask and answer.
Real-world usage: Every AI API β Anthropic, OpenAI, Google β is an HTTP API. When your Python agent calls client.messages.create(), it's sending an HTTP POST request to https://api.anthropic.com/v1/messages. When your agent fetches data from the web, it's making HTTP GET requests. Understanding HTTP isn't optional for agent development β it's the transport layer everything rides on.
Key terms:
- Client β the program making the request (your code, your browser,
curl) - Server β the program receiving the request and sending back a response
- URL β the address of the resource you're requesting
- Header β metadata about the request or response (auth tokens, content type)
- Body β the actual data payload (your prompt, the model's response)
Anatomy of a URL
https://api.anthropic.com/v1/messages?model=claude-sonnet-4-6&stream=true
β β β β
scheme host path query parameters
- Scheme (
https) β the protocol.https= encrypted,http= not. Always usehttpsfor APIs. - Host (
api.anthropic.com) β the server's address. - Path (
/v1/messages) β which resource on the server you want. - Query parameters (
?model=...&stream=true) β optional key-value pairs that modify the request.
HTTP Methods
HTTP has several methods (verbs) that tell the server what you want to do:
| Method | Purpose | Example |
|---|---|---|
| GET | Read/retrieve data | Fetch a webpage, list items |
| POST | Create/send data | Send a prompt to Claude, submit a form |
| PUT | Replace/update entirely | Replace a user profile |
| PATCH | Update partially | Change just the user's email |
| DELETE | Remove data | Delete an API key |
For AI APIs, you'll use POST almost exclusively. Sending a prompt to Claude is a POST request with a JSON body. GET is for fetching things without sending data.
Status Codes
Every HTTP response includes a status code β a three-digit number that tells you what happened:
| Range | Meaning | Common Codes |
|---|---|---|
| 2xx | Success | 200 OK, 201 Created |
| 3xx | Redirect | 301 Moved, 304 Not Modified |
| 4xx | Client error (your fault) | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests |
| 5xx | Server error (their fault) | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
The ones you'll see most in agent development:
- 200 β it worked
- 401 β your API key is wrong or missing
- 429 β you're sending too many requests (rate limited). Back off and retry.
- 500/502/503 β the API service is having issues. Retry with exponential backoff.
Why it matters for agents: Your agent will hit 429s and 500s regularly. If you don't handle them, your agent crashes. Production agents always implement retry logic with exponential backoff for these codes.
JSON
JSON (JavaScript Object Notation) is the data format of the modern web. Every AI API sends and receives JSON.
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "What is the capital of France?"
}
]
}JSON has six data types: strings ("hello"), numbers (42), booleans (true/false), null, arrays ([1, 2, 3]), and objects ({"key": "value"}). That's it. Nothing else.
In Python, you'll use the json module or libraries that handle serialization automatically:
import json
data = {"model": "claude-sonnet-4-6", "max_tokens": 1024}
json_string = json.dumps(data) # Python dict β JSON string
parsed = json.loads(json_string) # JSON string β Python dictREST APIs
REST (Representational State Transfer) is a design pattern for web APIs. Most APIs you'll interact with β including Claude's β follow REST conventions.
The key idea: resources have URLs, and you use HTTP methods to act on them.
GET /v1/models β List available models
POST /v1/messages β Create a new message (send a prompt)
GET /v1/messages/{id} β Get a specific message by ID
DELETE /v1/messages/{id} β Delete a message
REST APIs are stateless β each request contains all the information the server needs. The server doesn't remember your previous requests. This is why you send the entire conversation history in every Claude API call.
curl: Your HTTP Swiss Army Knife
curl is a command-line tool for making HTTP requests. It's pre-installed on most systems and is the fastest way to test an API.
# Simple GET request
curl https://api.github.com/users/octocat
# POST request to Claude API
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 256,
"messages": [{"role": "user", "content": "Hello!"}]
}'The flags:
-Hβ set a header-dβ send data in the request body-X POSTβ set the HTTP method (implicit when using-d)
When something goes wrong with an API, curl is your first debugging tool. Strip away the SDK, strip away the framework, and make the raw HTTP request. If curl works but your code doesn't, the problem is almost certainly in your code.