QA Interview Hub · Knowledge base · Quizzes

API

Status codes

401 vs 403, 400 vs 422, 500 vs 503

401 Unauthorized means the client isn't authenticated: there is no token, or it is invalid or expired. 403 Forbidden means the client is authenticated but has no rights to the resource, for example an ordinary user going to an admin endpoint. In short: 401 is "who are you?", 403 is "I know who you are, but you may not".

400 Bad Request means the request is syntactically incorrect: broken JSON, a wrong data type, a missing required parameter. 422 Unprocessable Entity means the request is syntactically correct but fails business validation, for example the email is already taken or the end date is before the start date. Many APIs use 400 for both cases, so it is worth checking against the contract.

500 Internal Server Error is an unexpected error on the server, most often a bug in the code, and for a tester it is always a reason to file a defect. 503 Service Unavailable means the service is temporarily unavailable: overload, maintenance, a dependency not responding. Often 503 comes with a Retry-After header.

Groups and a table of codes

The first digit is the group: 1xx informational, 2xx success, 3xx redirection, 4xx client error, 5xx server error.

CodeMeaningWhen to expect
200 OKSuccess with a bodyGET, a successful PUT or PATCH
201 CreatedThe resource was createdPOST
204 No ContentSuccess without a bodyDELETE
301 / 302RedirectionA changed URL, a redirect to login
304 Not ModifiedData hasn't changed, take it from cacheCaching
400 Bad RequestAn invalid requestBroken JSON, a missing required field
401 UnauthorizedNot authenticatedNo token or an expired one
403 ForbiddenKnown who, but no rightsAn ordinary user goes to the admin area
404 Not FoundNo such resourceA nonexistent id
405 Method Not AllowedThe method isn't supportedDELETE on an endpoint that doesn't have it
409 ConflictA state conflictA duplicate email, a parallel change
415 Unsupported Media TypeAn unsupported body formatA wrong Content-Type
422 Unprocessable EntitySyntax OK, a business rule violatedAn amount greater than the balance
429 Too Many RequestsThe request limit was exceededRate limiting
500 Internal Server ErrorAn unhandled server errorAlways a bug
502 / 503 / 504A gateway problem, the service unavailable, a timeoutA crash or an overload
In an interview: I go by the first digit: 2xx is success, 4xx means the client sent something wrong, 5xx is a problem on the server. I check the specific code against the documentation, because teams use, for example, 400 and 422 differently.

The most popular traps

401 vs 403 is the most popular question: 401 is "who are you?", 403 is "I know who you are, but you may not". That is, 401 is an authentication problem (no token, it is expired or corrupted), 403 is an authorisation one (the user has no role or rights for this resource).

A bug or not. Invalid input must give a 4xx with a clear message. A 500 for bad input is a bug, even if "an error did come back": 500 means the server didn't handle the situation and an exception was thrown somewhere. Likewise a 200 with { "error": "..." } in the body is a bug: clients, monitoring and automated tests go by the status and will consider such a request successful.

A few more points I pay attention to:

  • A 201 on creation should come with the new resource's id in the body or a URL in the Location header.
  • A 204 must not have a body; if there is one, the client may ignore it.
  • A 404 for someone else's resource instead of 403 is normal practice: that way the API doesn't reveal that the resource exists.
  • The error body must not contain a stack trace, an SQL query or internal paths.
In an interview: 401 is not authenticated, 403 is authenticated but without rights. A 500 in response to invalid data is always a bug, as is a 200 with an error in the body.