Lesson 2 of 4 · Network Plumbing & External APIs
HTTP Methods & Status Codes
Read a complete HTTP exchange, choose the right method, interpret success and failure, and inspect real responses before building your API interface.
This lesson is locked. You can read ahead, but finish earlier stops to earn progress.
Listen
Watch
Read
One exchange has two sides
Imagine your product page asks an API for product 42. The browser sends a request containing a method, a destination, headers and sometimes a body. The server sends a response containing a status code, headers and sometimes a body. A request describes what you want; a response reports how that particular attempt was handled.
These are fictional, simplified HTTP/1.1 messages for reading practice, not commands to paste into a terminal:
GET /api/products/42 HTTP/1.1 Host: shop.example.com Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{"id":42,"name":"Desk lamp","price":29}Read the request: GET is the method, /api/products/42 is the path, and Host identifies the destination hostname. Accept says which response format the client would like. Read the response: 200 is the status, Content-Type describes the returned body, and the JSON contains the product. The blank line separates headers from a body.
HTTP/2 and HTTP/3 represent messages differently; tools still expose methods, headers and status codes. You might see HTTP/2 200 without the words “OK”. The numeric code, not an English phrase, is what your program should inspect.
URL, headers and body do different jobs
In https://shop.example.com/api/products?limit=5, HTTPS selects the secure scheme, the hostname identifies the service, the path selects the resource and the query string supplies a parameter. limit=5 is not an HTTP header. A URL fragment such as #details stays in the browser and is not sent as part of the HTTP request target.
- Request headers provide metadata: accepted formats, authentication and the format of a body you send.
- Request body carries submitted data, such as a new product's fields. Not every request has one.
- Response headers describe the result, such as its content type, caching rules or a newly created resource's location.
- Response body may contain JSON, HTML, text, an image or error details. An API does not guarantee JSON just because its URL contains /api.
Content-Type: application/json describes the body on that side of the exchange. Accept: application/json asks for a response format; it does not convert HTML into JSON. Sending valid JSON also does not guarantee valid business data: {"price":-20} can be syntactically correct but unacceptable to a product API.
Choose a method from the API contract
An endpoint is not just a path: the method matters too. GET /api/products and POST /api/products can be different operations at the same URL. Read the API documentation before sending a request; the method alone cannot tell you all required fields or permissions.
| Method | Usual intent |
|---|---|
| GET | Retrieve a representation of a resource |
| POST | Submit data for processing, often creating a resource |
| PUT | Create or replace the target resource's representation |
| PATCH | Apply a partial change using the API's patch format |
| DELETE | Request removal of a resource |
| HEAD | Retrieve GET-like headers without a response body |
| OPTIONS | Ask about supported communication options |
For a typical product API, GET /api/products lists products; GET /api/products/42 reads one; POST /api/products creates one; PATCH /api/products/42 changes selected fields; DELETE /api/products/42 removes it. These are examples of a contract, not routes you can assume every API provides.
PUT is not simply another spelling of PATCH
If documentation defines PUT as a full replacement, sending only a new name may remove or reset fields you omitted. PATCH can change only the name, but its accepted format still depends on the API. Never experiment with updates or deletions against a real account just to find out what happens.
Safe and idempotent: why repeated requests matter
Safe methods, such as GET and HEAD, are intended for retrieval without requested state changes. Servers can still record access logs. Never put a “delete account” action behind GET merely because a link is easy to build.
Idempotent means repeating the same request has the same intended effect on server state as sending it once. PUT and DELETE are defined to be idempotent; deleting an already deleted resource may return a different status, but it should not delete something else. POST is not generally idempotent: submitting an order twice can create two orders. PATCH is not guaranteed idempotent; “increase quantity by one” differs from “set quantity to three”.
If a create-order request times out, you may not know whether the server already created the order. Blindly retrying can duplicate it. Follow the API's retry or idempotency-key guidance, and avoid double submissions while a request is pending. You do not need to build that system yet; you do need to recognise the risk.
Read the status family first, then the exact code
| Family | What it tells you |
|---|---|
| 1xx | Interim information; usually handled by networking tools |
| 2xx | The request succeeded according to its operation |
| 3xx | Redirection or cache-related handling |
| 4xx | The server could not fulfil the request as made |
| 5xx | The server or an upstream service failed to fulfil it |
Do not translate this into “4xx is always the learner's fault; 5xx can be ignored.” A 404 can be expected, a 429 can be a service limit, and a 500 in your own app may be a bug you must investigate. Status is evidence about one attempt, not a judgment about a person.
Success is not always 200, and not always JSON
- 200 OK: successful retrieval or processing; inspect the content type and body.
- 201 Created: a resource was created. A Location header may identify its URL, and the body may describe it.
- 202 Accepted: processing was accepted but may not be finished. Do not announce a completed job unless the API confirms it.
- 204 No Content: successful request with no response body. Trying to parse an empty body as JSON will fail even though the operation succeeded.
Redirects and caching
301/308 commonly indicate a permanent redirect; 302/307 commonly indicate a temporary one. The Location header gives the next destination. 307 and 308 preserve the method; 301/302 may change POST to GET in clients. A 303 directs the client to retrieve another resource, normally with GET after a submission. Let the API documentation guide you rather than treating all redirects alike.
A 304 Not Modified is a response to a conditional request: reuse the cached representation. It is not a new JSON body and not an ordinary failure. Browsers often handle redirects and caching automatically, which is why the final displayed page can hide an earlier response.
Client-side conditions: choose the next action
- 400 Bad Request: malformed or unacceptable input under this API's rules. Read the error body; check required fields, types, query parameters and request format.
- 401 Unauthorized: valid authentication credentials are missing or unacceptable. Check the API's sign-in/token instructions; the name is misleading because this is primarily an authentication problem. A WWW-Authenticate header can describe the challenge.
- 403 Forbidden: the server refuses the action. The account may be authenticated but lack permission; repeatedly signing in does not necessarily fix it.
- 404 Not Found: the route or resource is unavailable, or the service may be hiding its existence. Check spelling, base URL, identifier and access rules. A missing product is not automatically a broken server.
- 405 Method Not Allowed: that resource does not support your method. Check the contract and the Allow response header; changing GET to POST at random is not a solution.
- 409 Conflict: the operation conflicts with current state, such as a duplicate name or stale update. Refresh or resolve the conflict before resubmitting.
- 415 Unsupported Media Type: the service cannot handle the submitted format. Compare Content-Type with the actual body and API documentation.
- 422 Unprocessable Content: the service understands the format but rejects its meaning, often field validation. APIs differ in whether they use 400 or 422 for validation.
- 429 Too Many Requests: a rate limit was reached. Honour Retry-After when supplied; do not run a tight retry loop or keep clicking.
Server-side conditions: investigate the right layer
500 Internal Server Error is a generic unexpected server failure. 502 Bad Gateway means a gateway received an invalid upstream response. 503 Service Unavailable can indicate temporary unavailability or overload. 504 Gateway Timeout means a gateway waited too long for an upstream response.
For your own service, inspect its logs and dependencies. For somebody else's API, check the status page and documentation, preserve non-sensitive diagnostic details and present a useful temporary failure state. A delayed retry may be appropriate for a read; automatic retries for writes require more care.
Worked diagnosis: read all three pieces
Imagine a product submission responds with:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{"error":"price must be a non-negative number"}The method/path tell you which operation you attempted; 400 tells you it was rejected as made; the body identifies a field to correct. Sending the exact same payload again is unlikely to help. Compare the submitted price and its type with the documentation, correct the input, and only then retry.
Now imagine GET /api/products/42 returns 404 and an HTML error page. Do not try to solve that by parsing the HTML as JSON or hiding the exception. Check the URL and status first. If the URL is right but that product does not exist, “Product not found” may be the correct interface state.
Inspect a real exchange in the browser
- Open a browser's developer tools and select Network. On desktop Chrome/Edge, use the menu's developer-tools option; Safari may require enabling developer features first.
- With Network open, visit
https://official-joke-api.appspot.com/random_jokeor reload it. Select the request for random_joke, not an unrelated favicon request. A direct visit is a document request; an app's fetch request usually appears under Fetch/XHR. - In Headers, find Request URL, Request Method and Status Code. Inspect response Content-Type. In Response or Preview, read the returned body.
- Identify the JSON setup and punchline fields. Record the actual status you observed: a public service can fail or limit requests.
- If investigating a redirect, enable Preserve log before navigating so earlier requests are not cleared. Compare the original and final URLs.
Do not share screenshots of authentication headers, cookies or private responses. The practice endpoint requires no secret. If developer tools are unavailable on your current device, read the supplied messages now and do the inspection later on your computer.
Terminal practice: four response codes
Open the VS Code terminal. On Mac use curl; on Windows PowerShell use curl.exe so an older PowerShell alias does not substitute a different command. The -i option includes response headers alongside the body. Run one command at a time:
curl -i https://official-joke-api.appspot.com/random_joke curl -i https://httpbin.org/status/400 curl -i https://httpbin.org/status/401 curl -i https://official-joke-api.appspot.com/not-a-real-route-4821
curl.exe -i https://official-joke-api.appspot.com/random_joke curl.exe -i https://httpbin.org/status/400 curl.exe -i https://httpbin.org/status/401 curl.exe -i https://official-joke-api.appspot.com/not-a-real-route-4821
These GET requests are read-only practice and align with the later Terminal Network Recon activity. The expected statuses are 200, 400, 401 and 404 respectively, but inspect the actual output. The httpbin status routes deliberately generate a code: the 401 there is not asking you to supply a real account credential, and the 400 does not mean your practice command is malformed.
For each output, record the requested method/URL, returned code, a response header and whether a body exists. Do not invent an error body if the service sends none. A proxy may print an initial connection-established line; distinguish that from the endpoint's final response. curl -I is different from curl -i: uppercase I requests HEAD and normally omits the body. Do not use it when the activity asks for complete GET outputs.
If the endpoint is temporarily unavailable or returns an unexpected code, record it honestly and retry once later rather than manufacturing the expected output. In a terminal, curl can finish without a transport error even when the HTTP response is 404: command completion does not equal API success.
No response is different from an error response
A DNS failure, connection failure, TLS problem or timeout can prevent you from receiving an HTTP response at all. You cannot label that “a 500” unless a server actually returned 500. A browser CORS restriction may also prevent JavaScript from reading a response that the network received; inspect Network and the console rather than assuming the response body was accessible.
In the next lesson, fetch normally resolves with a Response for HTTP errors such as 404 or 500; it does not automatically throw just because the code is 4xx/5xx. Check res.ok or res.status before parsing and displaying data. res.ok covers 200–299, but even then you must account for 204 and the expected body format. Network or browser-access failures can instead reject the request.
Check your understanding before moving on
Choose a method and a likely next action for each case, then compare with the reasoning:
- Load a product list: GET; expect a representation, commonly 200, and check its format before reading it.
- Create a product from a form: POST under this example contract; 201 can indicate creation. Prevent accidental duplicate submissions.
- Change only the product name: PATCH if the API supports it; follow its field/patch format rather than sending a partial PUT blindly.
- Delete a product: DELETE under the contract; 204 can mean success without a body. Do not attempt JSON parsing when there is no body.
- A validly signed-in learner lacks permission: 403 is plausible; explain the access restriction rather than repeatedly asking them to log in.
- A request exceeds a rate limit: 429; inspect Retry-After and wait rather than retrying continuously.
- No server response arrives: investigate connectivity and browser errors; no numeric HTTP status has been established.
You are ready to build the API interface when you can separate method, URL, headers, status and body; explain 200/400/401/404 using actual outputs; and distinguish an HTTP rejection from a failed network request. These rehearsals do not add progress requirements: the next lesson teaches fetch, and the optional curl branch collects the four terminal outputs.
Key terms
- Method
- The requested operation, interpreted alongside the API's path and contract.
- Headers / body
- Message metadata / the optional content being sent.
- Status code
- A three-digit result returned in an HTTP response.
- Idempotent
- Repeating a request has the same intended server-state effect as sending it once.
- 401 / 403
- Authentication is required or invalid / the action is refused.
Summary — copy into your notes
- Read method, URL, headers, status and body separately; use the API's documented contract.
- GET retrieves, POST submits, PUT replaces, PATCH partially changes and DELETE removes.
- Interpret the exact status and error details; 4xx and 5xx guide diagnosis, not blame.
- 204 has no body; network failures may have no HTTP status; inspect responses before parsing them.