Reading HTTP Status Codes During Integration Work
The status code is your first clue about who has to fix it: the side that sent the request, or the side that received it. Misreading it means escalating to the wrong team.
The first digit sets the category. 2xx means success, 3xx a redirect, 4xx means your request is at fault, and 5xx means the server is. That 4xx/5xx split matters: 4xx says do not retry until something is fixed, 5xx says it is reasonable to try again later.
The ones you actually meet
| Code | Meaning | What to check |
|---|---|---|
| 200 OK | Succeeded | Still read the body — some systems return 200 with an error inside |
| 201 Created | A new record exists | Record the returned ID for reconciliation |
| 400 Bad Request | The request is malformed | Invalid JSON, missing required field, wrong data type |
| 401 Unauthorized | Not authenticated | Wrong credentials, expired token, signature mismatch |
| 403 Forbidden | Authenticated but not allowed | Role lacks permission, or record access is restricted |
| 404 Not Found | No such address or record | Wrong URL, wrong internal ID, or the record was deleted |
| 409 Conflict | Clashes with current state | A duplicate, or someone changed the record first |
| 422 Unprocessable | Well-formed but rejected | Parsed fine, failed a business rule |
| 429 Too Many Requests | Calling too often | Rate limited — back off and retry gradually |
| 500 Internal Server Error | The server failed | Not your side; include the timestamp when you report it |
| 502 / 503 / 504 | Gateway, overloaded, timeout | Usually transient; safe to retry with a delay |
401 and 403, the pair most often swapped
401 means the server does not know who you are — the credentials failed. 403 means it knows exactly who you are and the answer is still no. Adding permissions will never cure a 401, and swapping tokens will never cure a 403. Confusing the two sends the fix around in circles.
429 is not an error, it is a brake
The system limits how many calls it accepts per unit of time. Answering it by retrying faster only extends the block. The correct response is exponential backoff: wait one second, then two, then four. If a Retry-After header is present, honour it.