Anatomy of a response
What comes back?
You send a request, you get a response. You've already seen the response body in the previous lessons: it's JSON. But there's more to a response than just the data. Let's look at what the server actually sends back.
The status code (did it work?)
Every response comes with a status code: a three-digit number that tells you what happened. You've probably seen some of these without realizing it. Ever landed on a "404 Not Found" page? That's a status code.
Let's see them in action. Hit "Send request" on each of these and watch what happens:
User #1 exists. You should get a 200 OK with the data:
User #9999 doesn't exist. The server can't find it:
This endpoint requires authentication. You didn't provide any, so the server rejects you:
Three different URLs, three different status codes. Now let's put names on them.
2xx: success. Everything went well.
200 OK: the request worked, here's the data you asked for. That's what you got for/users/1.201 Created: the resource was created successfully (after a POST).204 No Content: the request worked, but there's nothing to send back (common after a DELETE).
4xx: you made a mistake. Something is wrong with the request.
400 Bad Request: the server didn't understand your request. Maybe a required field is missing or the JSON is malformed.401 Unauthorized: you didn't provide valid credentials. That's what happened with/auth/me. The server doesn't know who you are.403 Forbidden: the server knows who you are, but you don't have permission to do this.404 Not Found: the resource you asked for doesn't exist. That's what happened with/users/9999. Wrong ID.
5xx: the server broke. The request might be fine, but something went wrong on the other end.
500 Internal Server Error: something crashed on the server. Not your fault.503 Service Unavailable: the server is overloaded or down for maintenance. Try again later.
The first digit tells you the category: 2 = success, 4 = client error, 5 = server error. That alone helps you triage problems fast. If you see a 4xx, check your request. If you see a 5xx, it's on the server's side.
The response body (the data)
This is the part you already know well. The body is the JSON that the server sends back.
For a successful GET request, it's the data you asked for. This one asks for just 1 user (limit=1), and only three fields: firstName, email, and age (select=firstName,email,age). Try it:
Notice a few things in the response. The actual user data is inside the "users" array, but there's extra info around it: "total" is the total number of users in the database, "limit" is how many you asked for, and "skip" is how many were skipped from the start (here 0, because you started from the beginning). This is pagination: the API doesn't dump all 208 users at once, it gives you a slice. You could ask for the next page with skip=1. This pattern shows up in almost every API that returns lists.
Error responses
When something goes wrong, the server still sends back JSON. But instead of the data you wanted, you get an error message.
A 400 Bad Request might look like:
{
"status": "Error",
"code": 400,
"message": "Missing required field: email"
}
A 401 Unauthorized:
{
"status": "Error",
"code": 401,
"message": "Invalid API key"
}
A 404 Not Found:
{
"status": "Error",
"code": 404,
"message": "User not found"
}
This is why status codes and error messages matter for product work. When a user sees a generic "Something went wrong" screen, the API response behind it often says exactly what happened. If you can read that response, you can give your engineering team a much more precise bug report than "it doesn't work."
The response headers
Just like requests have headers, responses have them too. They contain metadata about the response: how big it is, when it was generated, what format the data is in, etc.
You won't need to read response headers very often as a PM, but two are worth knowing:
Content-Type: application/jsonconfirms the response body is JSONX-RateLimit-Remaining: 47tells you how many API calls you have left before being throttled (we'll talk about rate limiting in a later chapter)
Your first POST request
So far, every request you've sent has been a GET: "give me this data." But APIs aren't read-only. You can also create data by sending a POST request with a body.
Here's what's happening below: you're asking DummyJSON to create a new user. The body (the orange block) contains the data you're sending: a first name, a last name, an email, and an age. Hit "Send request" to see what comes back.
You should get a 201 Created. Look at the response carefully: you sent four fields, but the server sent back five. It added an id. You didn't choose that ID. The server generated it.
This is a pattern you'll see everywhere. When you create an account on any app, you provide your name and email. The server assigns you a user ID, a creation date, default settings. You send the minimum, the response comes back enriched.
One important note: DummyJSON is a fake API for learning. It pretends to create the user and gives you a realistic response, but nothing is actually saved. If you send the same request twice, you'll get the same result. Real APIs (Stripe, Twilio, your own app's backend) would actually store the data.
Key takeaways
- Status codes tell you if it worked (2xx), if you made a mistake (4xx), or if the server broke (5xx)
- The response body is JSON, whether it's data or an error message
- Error responses often contain a
messagethat explains exactly what went wrong - A request sends the minimum. The response comes back enriched with IDs, timestamps, and computed fields.