Every API response starts with a three-digit status code. It's the API's one-line summary of what happened to your request, and it's the first thing to check when you test one.
The good news: you don't need to memorise dozens of codes. A handful cover almost everything you'll see, and the first digit alone tells you most of the story.
The first digit tells you who's responsible
| Range | Meaning | In plain English |
|---|---|---|
2xx |
Success | It worked |
3xx |
Redirection | Look somewhere else |
4xx |
Client error | Something is wrong with your request |
5xx |
Server error | Something went wrong on the server |
This split matters when you're testing. A 4xx usually means the API is behaving correctly by rejecting a bad request. A 5xx almost always means there's a bug for the developer to fix.
The success codes
200 OK
The request worked and the response body contains the result. You'll see this for most successful GET requests, and often for updates.
201 Created
The request worked and created something new, like a customer or an order. A well-designed API returns 201 after a successful POST that creates a record, and usually includes the new record (with its ID) in the body.
204 No Content
The request worked, but there's nothing to send back. It's common after a DELETE, or an update that doesn't return the updated record. An empty body with a 204 is correct, not a bug.
Tip
If the acceptance criteria say "creates a customer" and the API returns
200instead of201, it isn't necessarily broken, but it's worth asking the developer which one the team's API standard expects.
The client errors (your request has a problem)
400 Bad Request
The server couldn't accept the request as sent. Typical causes are invalid JSON, a missing required field, or a value in the wrong format. A good API also explains what's wrong in the body:
{
"error": "validation_failed",
"message": "email must be a valid email address"
}
Some APIs use 422 Unprocessable Content for the same situation: the JSON is valid, but the data inside it isn't acceptable.
401 Unauthorized
The API doesn't know who you are. Either you didn't send credentials, or the token you sent is missing, expired or wrong. Despite the name, 401 is about authentication (proving who you are).
403 Forbidden
The API knows who you are, but you're not allowed to do this. For example, a regular user trying to delete another user's order. Retrying with the same token won't help.
Note
An easy way to remember it:
401means "who are you?",403means "I know who you are, and the answer is no."
404 Not Found
The thing you asked for doesn't exist. Either the URL is wrong (check for typos and the right version, such as /v1/ against /v2/), or the record with that ID isn't there.
405 Method Not Allowed
The endpoint exists but doesn't accept that method, for example sending DELETE to an endpoint that only supports GET.
409 Conflict
The request clashes with the current state of the data, such as creating a customer with an email address that's already registered.
429 Too Many Requests
You've sent too many requests in a short time and the API is asking you to slow down. Wait a moment and try again.
The server errors (the server has a problem)
500 Internal Server Error
Something broke on the server while handling your request. When you're testing, a 500 is almost always worth a bug report, even if your request was wrong. Bad input should get a helpful 4xx, not a crash.
502, 503 and 504
These usually point to infrastructure rather than the code itself: a server that's down, overloaded or too slow to respond. If they appear in a test environment, let the team know, then try again later.
How to check status codes like a tester
Getting a status code back is easy. The skill is knowing whether it's the right one. For each scenario in a story, write down the code you expect before you click Send:
| Scenario | Expected |
|---|---|
| Fetch an existing order | 200 |
| Create a valid order | 201 |
| Create an order with a missing field | 400 (or 422) |
| Fetch an order with no token | 401 |
| Fetch someone else's order | 403 (or 404, if the API hides other people's data) |
| Fetch an order that doesn't exist | 404 |
Then let Postman check it for you. In the request's Scripts → Post-response tab:
pm.test("Order was created", () => {
pm.response.to.have.status(201);
});
Two things to watch for:
- Errors disguised as success. Some APIs return
200with"success": falsein the body. If a failed request gets a2xx, flag it: other systems will treat it as success. - Vague errors. A
400with an empty body forces whoever uses the API to guess what went wrong. Asking for a clear message is a fair request.
Quick reference
| Code | Name | Usually means |
|---|---|---|
200 |
OK | It worked |
201 |
Created | It worked and created a record |
204 |
No Content | It worked; nothing to return |
400 |
Bad Request | Your data is invalid |
401 |
Unauthorized | Missing or invalid credentials |
403 |
Forbidden | You're not allowed to do this |
404 |
Not Found | Wrong URL or no such record |
409 |
Conflict | Clashes with existing data |
422 |
Unprocessable Content | Valid JSON, unacceptable values |
429 |
Too Many Requests | Slow down |
500 |
Internal Server Error | The server crashed: report it |
503 |
Service Unavailable | The server is down or overloaded |
The best way to learn these is to see them. In our update-order exercise you send a change to an existing order and interpret the status code that comes back.