Skip to content

Inspect a request

  • Lesson 3
  • 35 min
  • Module 1: Understand the web request

What you will be able to do

See exactly what a client sent and what the server answered, with two tools that you always have: the browser’s developer tools and curl. When an API “does not work”, this is the first thing to check.

Before you startWhat to know and to have readyAbout 35 minutes

What you need to know

What you need on your computer

  • A desktop browser: Chrome, Edge or Firefox. Safari works too, after you turn on Settings › Advanced › Show features for web developers.
  • curl. It is included in macOS, Windows 10 and 11, and most Linux systems. On Windows, type curl.exe (see below).
  • An internet connection. The examples use Postman Echo and the course’s public data file.

Tested with curl 8.7 on macOS and Chrome 141.

Every desktop browser has developer tools: a panel that shows what a page does. The Network tab lists every request that the page makes, with its full request and response.

  1. Open a new browser tab.
  2. Open the developer tools: press F12, or Cmd+Option+I on macOS. Select the Network tab.
  3. In the address bar, open https://raw.githubusercontent.com/Nextia-Intelligence/nextia-learning-labs/main/C02/data/tickets.json.
  4. In the Network tab, select the row tickets.json.
  5. Look at Headers. Find the request method (GET), the status code (200), and the response header content-type.
  6. Look at Response (or Preview). It shows the body: the 15 tickets.

The developer tools show requests that the browser makes. They are the best tool when a web page uses your API, because you see the request exactly as that page sends it. To send a request that you design, use curl.

curl sends one request from the terminal, and shows the response. Each part of the request is an option:

Option Meaning
-i Show the response headers, not only the body.
-v Show everything: DNS, connection, TLS, the request headers and the response headers.
-X POST Use this method. Without it, curl uses GET.
-H "Name: value" Add a request header.
--data @file.json Send the contents of this file as the body.
-s Silent: no progress bar.

Worked example: a request and its response

Section titled “Worked example: a request and its response”

Amira sends a GET and shows the response headers with -i:

Terminal (on Windows: curl.exe)
curl -i "https://postman-echo.com/get?status=open"
Output (shortened)
HTTP/2 200
content-type: application/json; charset=utf-8
content-length: 231
server: cloudflare
{"args":{"status":"open"},"headers":{"host":"postman-echo.com","accept":"*/*","user-agent":"curl/8.7.1",...},"url":"https://postman-echo.com/get?status=open"}

Read it from the top: the protocol and status code (HTTP/2 200), the response headers, an empty line, then the body. Postman Echo’s body shows what it received: the query parameter, and the headers that curl added for her (accept, user-agent).

Then she sends a POST with a JSON body. First, she saves the body in a file, ticket.json:

ticket.json
{"subject": "Charged twice for March", "body": "Same invoice two times."}
Terminal (on Windows: curl.exe)
curl -i -X POST https://postman-echo.com/post -H "Content-Type: application/json" --data @ticket.json
Output (shortened)
HTTP/2 200
content-type: application/json; charset=utf-8
{"data":{"subject":"Charged twice for March","body":"Same invoice two times."},"headers":{"content-type":"application/json",...},"json":{"subject":"Charged twice for March","body":"Same invoice two times."},...}

The json field shows that the server read the body as JSON, because of the Content-Type header.

-v (verbose) shows the steps from Browser-to-server basics. Lines that start with * are curl’s notes, > is what curl sent, and < is what it received. Here, Postman Echo returns a 503 on purpose:

Terminal (on Windows: curl.exe)
curl -v https://postman-echo.com/status/503
Output (the important lines)
* Host postman-echo.com:443 was resolved.
* Connected to postman-echo.com (162.159.142.41) port 443
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
> GET /status/503 HTTP/2
> Host: postman-echo.com
< HTTP/2 503
< content-type: application/json; charset=utf-8
{"status":503}

DNS worked (was resolved), the connection worked (Connected ... port 443), TLS worked (SSL connection using TLSv1.3), and the request was sent. The server answered with 503. The network worked completely. The application reported a problem. This is the most important difference in this module.

  1. Make a folder for this module’s practice files, and move into it:

    Terminal window
    mkdir -p ~/projects/http-practice
    cd ~/projects/http-practice

    On Windows, mkdir ~/projects/http-practice works without -p.

  2. Make ticket.json with the body from the worked example.

  3. Send it with curl -i -X POST, as in the worked example. Find the status code, the content-type header, and the json field in the body.

  4. Send the same request without the -H "Content-Type: application/json" option. Compare the response. Which header did curl send instead? (Look in the headers field of the body.)

  5. Run curl -v https://postman-echo.com/status/404. Find the line that shows the connection, the line that shows the request, and the line with the status code.

Show what you should see in step 4

Without your header, curl sends content-type: application/x-www-form-urlencoded, the format of an HTML form. So Postman Echo reads the body as a form. In the form field, the whole JSON text is the name of one field, with an empty value. The server did what the header said. The API that you build answers 422 for the same request. Always send the Content-Type header with a body.

Your turn: read a response you did not design

Section titled “Your turn: read a response you did not design”

Open the developer tools on any web page that you use often, and reload the page. Find one request whose response type is JSON (the Type column shows fetch, xhr or json). For that request, write down:

  1. The method, the host and the path.
  2. Two request headers, and what you think each one is for.
  3. The status code, and the response content-type.
  4. One field from the response body, and what you think it means.

There is no single right answer. The goal is to read a real request part by part, as you will read your own API’s requests.

Common mistake

A successful connection with an application error

Symptom: a request “fails”, and you start to check the internet connection, the firewall or DNS. But curl shows a status code, such as 404, 422 or 500.

Cause: any status code proves that DNS, the connection and TLS worked, and that the application answered. The problem is in the request (a 4xx code) or in the application (a 5xx code), not in the network.

Fix:

  1. Run the request with curl -v. If you see a < HTTP/... line with a status code, the network is fine.
  2. For a 4xx code, read the response body. A good API says what is wrong with the request.
  3. For a 5xx code, read the application’s logs. The client cannot fix it.
  4. Only if there is no status code (Could not resolve host, Couldn't connect to server, a timeout or an SSL error), check the URL, the network and the server.

Check your understanding

Module check: curl -v shows 'Connected to api.example.com port 443', a TLS line, and then '< HTTP/2 500'. Explain why the network connection worked but the request still failed, and who must fix it.

Show the answer

The connection line and the TLS line show that DNS, the connection and the encryption all worked, and the server received the request. 500 is the application’s answer: it had an unexpected error while it handled the request. The network is fine, and sending the same request again usually does not help. The people who run the API must fix it, with the help of its logs. If it were 503, a later attempt could work. If it were a 4xx code, the client would have to change the request.

Check your understanding

Why does this course send JSON bodies from a file with --data @ticket.json, instead of typing the JSON in the command?

Show the answer

Typing JSON in a command depends on the shell’s rules for quotes, and Windows PowerShell changes the quotes before curl receives them. A file avoids the shell completely, so the same command works on macOS, Linux and Windows. The file is also easy to read, change and keep with the project.

Recap

  • The Network tab in the developer tools shows every request that a page makes, with its headers and body.
  • curl sends a request that you design: -i shows the response headers, -v shows every step, -X, -H and --data @file.json build the request. On Windows, type curl.exe.
  • A status code means that the network worked and the application answered. Without a status code, the failure is in the URL, the network or the server.

You can now read any request and response. In the next module, you build the server side: a FastAPI service.

Next: Environment and first endpoint