Back to guides

GUIDE / api

REST API Status Codes: The Complete Reference for Testers

Master REST API status codes with a complete tester cheat sheet for 2xx, 4xx, and 5xx responses, error validation, and practical test design.

By The Testing AcademyPublished July 9, 2026Updated July 9, 202619 min read

If you test backends, REST API status codes are not trivia. They are the first signal every client, monitor, and automated check uses to decide success, retry, auth failure, or server fault. A 200 that hides an error body, a 500 for bad input, or a 401 that should have been 403 will break integrations even when the JSON looks “mostly right.”

This guide is a practical reference for QA engineers. You will get a clear map of status families, a tester-focused HTTP status codes cheat sheet, deep coverage of 2xx, 4xx, and 5xx behavior, REST API error response validation patterns, worked test cases, and the common mistakes that create false confidence in API suites.

Why REST API Status Codes Matter in Testing

HTTP status codes are part of the contract between producer and consumer. The body describes details. The status describes the outcome class.

When status codes are wrong, several layers fail at once:

  • Frontend error handling shows the wrong message or no message.
  • Mobile clients retry endlessly or never retry when they should.
  • API gateways and load balancers route or throttle incorrectly.
  • Observability dashboards count failures as successes.
  • Contract and integration tests pass for the wrong reason.

A strong API tester does not only assert expect(status).toBe(200). A strong API tester asks whether the status matches the intent of the operation, the authentication state, the resource state, and the agreed API design.

If you are new to API testing as a discipline, start with the broader workflow in the API testing tutorial, then come back here when you design status and error assertions.

The Five Status Code Families

HTTP status codes are three-digit numbers grouped by the first digit.

FamilyRangeMeaning for testers
1xx Informational100-199Interim responses. Rare in ordinary REST CRUD tests.
2xx Success200-299Request was accepted and completed successfully from the protocol view.
3xx Redirection300-399Client must take another action, often follow a new location.
4xx Client error400-499The request is wrong, unauthorized, forbidden, not found, or otherwise rejected as a client problem.
5xx Server error500-599The server failed to fulfill a seemingly valid request.

Your default mental model as a tester:

  • 2xx: happy path or accepted processing.
  • 4xx: the client should change something.
  • 5xx: the server or dependency failed; investigate infrastructure, code, or upstream services.

Do not treat status codes as decoration. Treat them as first-class expected results.

REST API Status Codes Cheat Sheet for Testers

Use this table as a day-to-day reference when designing cases.

CodeNameTypical API meaningTester focus
200OKSuccessful GET, PUT, PATCH, or action with a bodyBody shape, fields, headers, caching
201CreatedResource created, often after POSTLocation header, created entity, id stability
202AcceptedAsync work accepted but not finishedJob id, polling contract, eventual status
204No ContentSuccess with empty body, often DELETE or updateEmpty body, no accidental JSON payload
301/302/307/308RedirectsResource moved or temporary redirectFollow policy, HTTPS, method preservation
400Bad RequestMalformed request or generic client errorParse errors, missing structure, message quality
401UnauthorizedMissing or invalid authenticationWWW-Authenticate, token expiry, refresh
403ForbiddenAuthenticated but not allowedRole and scope enforcement
404Not FoundResource missing or not visibleSoft delete, tenancy isolation, IDOR risks
405Method Not AllowedHTTP method not supported for resourceAllow header, method matrix
409ConflictState conflict, duplicate, version clashConcurrency, unique constraints
410GoneResource permanently removedClient cache and retry behavior
412Precondition FailedETag or If-Match failedOptimistic locking
415Unsupported Media TypeWrong Content-TypeJSON vs form vs multipart
422Unprocessable EntitySemantic validation failureField errors, business rules
429Too Many RequestsRate limit exceededRetry-After, limit headers
500Internal Server ErrorUnhandled server failureNo secrets in body, logging, alerts
502Bad GatewayUpstream invalid responseDependency failures
503Service UnavailableTemporary outage or maintenanceRetry guidance, health endpoints
504Gateway TimeoutUpstream timeoutTimeouts and cascading failure

Print this mentally before every API exploratory session. Then go deeper on the codes your product actually uses.

2xx Status Codes: Success Is Not One Thing

200 OK

200 OK means the request succeeded and the response usually contains a body. Common for GET, PUT, PATCH, and some POST actions that do not create a new resource identity.

Tester checks:

  • Status is 200 only when the business operation truly succeeded.
  • Response schema matches the contract.
  • Important fields are present, typed correctly, and consistent with the database or secondary reads.
  • Pagination metadata is correct when listing resources.
  • Sensitive fields are redacted for the caller’s role.

Anti-pattern: returning 200 for every response, including validation failure, and putting "error": true in the body. That design forces every client to reimplement status logic.

201 Created

201 Created is the preferred success code after creating a resource. The response should make the new resource discoverable.

Tester checks:

  • Status is 201, not 200, when creation is the main outcome.
  • Location header points to the new resource when the API design includes it.
  • Body includes the created id and key attributes.
  • Repeating the same create request behaves as designed: either another 201, a 409 conflict, or an idempotent 200/201 with the same resource.

202 Accepted

202 Accepted means the server accepted work that will finish later. This is common for exports, bulk imports, video processing, or long report generation.

Tester checks:

  • Immediate response includes a job id, status URL, or operation id.
  • Polling the status endpoint eventually yields success, failure, or timeout states.
  • Clients do not treat 202 as final completion.
  • Failed async jobs surface a terminal error state rather than hanging forever.

204 No Content

204 No Content means success with no response body. Common for DELETE and some updates.

Tester checks:

  • Body is truly empty.
  • Clients that always call .json() do not crash.
  • DELETE of an already deleted resource returns the designed code: 204, 404, or 410, consistently.

3xx Status Codes: Redirects in API Land

REST APIs use redirects less often than websites, but they still appear with:

  • HTTP to HTTPS upgrades.
  • Legacy URL migrations.
  • CDN or API gateway routing.
  • OAuth authorization endpoints.

Tester checks:

  • Whether the HTTP client follows redirects automatically.
  • Whether auth headers are stripped or preserved across hosts.
  • Whether POST becomes GET after some redirects.
  • Whether sensitive tokens appear in redirected query strings.

If your suite silently follows redirects, you can miss a breaking URL change. Add at least one test that inspects the first response status and Location header.

4xx Status Codes: Where Most Functional Defects Live

Client error codes are the richest area for QA design because they encode product rules.

400 Bad Request

Use and expect 400 when the request cannot be processed because it is malformed or otherwise invalid as sent.

Examples:

  • Body is not valid JSON.
  • Required top-level field is missing.
  • Query parameter type is wrong.
  • Unsupported combination of filters.

Tester focus:

  • Message is actionable without leaking internals.
  • Invalid requests never partially commit data.
  • Consistent mapping: similar defects produce similar codes.

401 Unauthorized

Despite the historical name, 401 is about authentication failure, not authorization.

Expect 401 when:

  • No token or credentials are provided.
  • Token is expired, malformed, or signed with the wrong key.
  • Basic auth credentials are wrong.
  • Session cookie is missing or invalid.

Tester checks:

  • Protected routes reject anonymous access.
  • Expired JWT returns 401, not 500.
  • Error body does not reveal whether a username exists if that is a security requirement.
  • WWW-Authenticate or documented auth error shape is present when required.

Deepen this area with API authentication testing.

403 Forbidden

403 means the server knows who you are and still refuses the action.

Examples:

  • Viewer role tries to delete a project.
  • Token scope lacks orders:write.
  • Tenant A token tries to read Tenant B data and the API chooses 403 instead of 404.

Security note: some teams intentionally return 404 for cross-tenant access to avoid resource enumeration. Others return 403. Both can be valid. The tester’s job is to verify the chosen policy is consistent and documented.

404 Not Found

404 means the target resource is not available to the caller.

Tester checks:

  • Unknown ids return 404.
  • Soft-deleted resources behave as designed.
  • Nested routes such as /users/{id}/orders/{orderId} validate ownership.
  • 404 bodies remain safe and consistent.

405 Method Not Allowed

Expect 405 when a resource exists but the method is wrong, such as DELETE /health or PUT /login.

Tester checks:

  • Method matrix matches documentation.
  • Allow header lists permitted methods when the API provides it.

409 Conflict

409 is powerful for real systems because state conflicts are common.

Examples:

  • Creating a user with an email that already exists.
  • Updating a stale version with optimistic locking.
  • Transitioning an order from shipped back to draft illegally.

Tester checks:

  • Concurrent updates do not corrupt data.
  • Conflict responses identify the conflicting constraint without oversharing.
  • Clients can recover: fetch latest version, choose a new unique value, or cancel.

415 Unsupported Media Type

Expect 415 when Content-Type is wrong, such as sending XML to a JSON-only endpoint or forgetting multipart boundaries for uploads.

422 Unprocessable Entity

Many modern APIs use 422 when the request is syntactically valid JSON but fails domain validation.

Examples:

  • Password too short.
  • End date before start date.
  • Quantity below minimum order size.

Whether your API uses 400 or 422, pick one rule and test it everywhere. Inconsistency is itself a defect for client authors.

429 Too Many Requests

Rate limits protect systems and fair use policies.

Tester checks:

  • Burst traffic eventually returns 429.
  • Retry-After or rate limit headers are present if documented.
  • Legitimate traffic still succeeds under normal load.
  • Auth endpoints are protected against credential stuffing patterns.

5xx Status Codes: Server Failures and Dependency Pain

500 Internal Server Error

500 means an unexpected server-side failure. It should be rare in stable releases.

Tester checks:

  • Forcing invalid server conditions does not expose stack traces, SQL, tokens, or file paths.
  • Known bad inputs produce 4xx, not 500.
  • 500s are logged with correlation ids.
  • Health and readiness probes do not report healthy when critical dependencies are down, if that is the design.

502 Bad Gateway and 504 Gateway Timeout

These usually mean a proxy or gateway received an invalid or slow response from an upstream service.

Tester checks:

  • Chaos or dependency-down tests produce the expected gateway behavior.
  • Timeouts are bounded.
  • Partial upstream failures degrade gracefully where required.

503 Service Unavailable

503 often means temporary overload, maintenance, or intentional shedding.

Tester checks:

  • Maintenance mode returns 503 with clear messaging.
  • Retry guidance exists when appropriate.
  • Critical write paths fail safely without partial commits.

REST API Error Response Validation

Status codes alone are not enough. Pair every important status with body and header checks.

A useful error response often includes:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Quantity must be at least 1.",
    "details": [
      {
        "field": "quantity",
        "issue": "min",
        "provided": 0
      }
    ],
    "requestId": "req_8f2c1a"
  }
}

Validation checklist:

  1. Status code matches the failure class.
  2. Content-Type is the documented error media type.
  3. Machine-readable code is stable for clients.
  4. Human message is clear and non-leaky.
  5. Field-level details exist for validation failures.
  6. requestId or correlation id is present for support.
  7. No stack traces, secrets, hostnames, or raw SQL.
  8. Localization rules are respected if the product supports them.

For Postman-based execution and scripting patterns, see the Postman tutorial.

Designing Test Cases Around Status Codes

Do not write one giant “status code test.” Write intent-based cases that use status codes as expected results.

Example: Create Order API

CaseSetupRequestExpected statusExtra assertions
Happy createValid buyer token, in-stock SKUPOST valid order201Body has order id, Location optional
Missing authNo tokenPOST valid order401No order created
Wrong roleViewer tokenPOST valid order403No order created
Unknown SKUValid tokenPOST unknown sku404 or 422Error code stable
Quantity 0Valid tokenPOST quantity 0400 or 422Field error on quantity
Duplicate idempotency keySame key twicePOST same payload200/201 consistentSame order id returned
Stock raceLast item reservedConcurrent POSTsone 201, one 409/422Inventory never negative
Server forced faultDependency downPOST valid order503/502/500 as designedSafe error body

This table forces the suite to cover auth, validation, conflict, and dependency classes instead of only the happy path.

Method and Status Expectations

Different methods have different common success codes.

MethodCommon successCommon failure codes
GET200401, 403, 404, 429, 500
POST create201 or 200400, 401, 403, 409, 422
POST action200 or 202400, 401, 403, 409, 422
PUT200 or 204400, 401, 403, 404, 412, 422
PATCH200 or 204400, 401, 403, 404, 412, 422
DELETE200, 204, or 404/410 policy401, 403, 404, 409

Document the policy your API chose, then test for consistency across resources.

Idempotency and Status Codes

Idempotency changes what status codes are acceptable on retries.

Examples:

  • DELETE of an existing resource returns 204. DELETE again returns 204 or 404, depending on design.
  • PUT of the same representation twice should not create duplicates.
  • POST with an idempotency key should not create two charges.

Tester rule: for every non-safe method that can be retried by clients or gateways, define the second-call status and body. Then automate both first and second calls.

Caching Headers and Status Codes

Status codes interact with caching.

  • 200 responses may include ETag, Cache-Control, or Last-Modified.
  • Conditional requests may return 304 Not Modified.
  • Error responses are often non-cacheable and should say so when needed.

Tester checks:

  • Unauthorized responses are not cached as public content.
  • 304 clients still have a usable local representation.
  • Stale error pages are not served as success.

GraphQL and Status Codes: A Short Contrast

GraphQL often returns HTTP 200 even when the operation contains errors in the errors array. That difference confuses REST-trained testers.

For GraphQL-specific validation of queries, mutations, schema, and errors, use the dedicated guide on how to test GraphQL APIs. Keep REST status semantics for REST endpoints, and do not force GraphQL into a pure REST status model unless your gateway deliberately does so.

Observability: What Status Codes Should Trigger

Status codes are product signals and operational signals.

Status patternLikely action
Spike in 401Auth outage, bad client deploy, expired secrets
Spike in 403Permission bug or role misconfiguration
Spike in 404Bad release links, client bug, data migration issue
Spike in 429Abuse, missing backoff, too-low limits
Spike in 5xxRegression, dependency failure, capacity problem

As a tester, include at least one release check that compares status code rates before and after deploy in non-prod or canary environments.

Sample Automated Assertions

Here is a concise pattern many API suites use:

// Example using a generic HTTP client style
const res = await api.post("/orders", {
  headers: { Authorization: `Bearer ${buyerToken}` },
  body: { sku: "SKU-1", quantity: 1 },
});

expect(res.status).toBe(201);
expect(res.headers["content-type"]).toMatch(/application\/json/);
expect(res.data.id).toMatch(/^ord_/);
expect(res.data.status).toBe("created");

// Negative: missing token
const anon = await api.post("/orders", {
  body: { sku: "SKU-1", quantity: 1 },
});
expect(anon.status).toBe(401);
expect(anon.data.error.code).toBe("UNAUTHENTICATED");
expect(JSON.stringify(anon.data)).not.toMatch(/stack|password|secret/i);

Notice the assertions cover status, headers, business fields, and safety of the error payload.

Common Mistakes With REST API Status Codes

Mistake 1: Asserting Only the Happy Path Status

A suite that only checks 200/201 will miss auth holes, validation gaps, and conflict bugs. Add negative and state-based cases early.

Mistake 2: Treating All 4xx as Equivalent

401, 403, 404, and 422 imply different client fixes. Collapsing them into “client error” loses diagnostic value and weakens contract tests.

Mistake 3: Returning 500 for Bad Input

If a missing field crashes the server, that is a defect. Invalid client input should usually become a controlled 4xx response.

Mistake 4: Success Status With Failure Body

200 OK plus "success": false breaks standard HTTP tooling. Prefer correct status families.

Mistake 5: Inconsistent Codes Across Similar Endpoints

If /users returns 422 for validation and /orders returns 400 for the same class of problem, client authors will need special cases forever. Consistency is a quality attribute.

Mistake 6: Leaky 5xx Bodies

Stack traces, internal hostnames, and SQL fragments in 500 responses are security and reliability issues. Assert their absence.

Mistake 7: Ignoring Rate Limits and Async Codes

Teams often forget 202 and 429 until production traffic hits them. Include at least smoke coverage for async acceptance and throttling if those features exist.

Mistake 8: No Correlation Between Status and Side Effects

A 201 must create. A 4xx must not create. A failed payment should not leave an order marked paid. Always verify side effects, not only the status line.

Practical Testing Workflow

Use this workflow when a new endpoint lands:

  1. Read the OpenAPI or docs for declared status codes.
  2. List success codes by method.
  3. List auth failure, permission failure, not found, validation, and conflict cases.
  4. Map each case to an expected status and body shape.
  5. Add side-effect checks for writes.
  6. Add safety checks for error payloads.
  7. Automate the stable high-value cases.
  8. Exploratory-test weird combinations: duplicate headers, wrong Accept, stale ETags, replayed requests.
  9. Compare observed codes with monitoring dashboards in lower environments.

For deliberate practice, open a QABattle API challenge in the battle arena and score yourself on whether you predicted the correct status family before you saw the response.

Status Codes in Contract Testing

Consumer-driven contracts should include status expectations, not only payload shapes. A consumer that expects 201 and receives 200 may still parse the body and then fail in production edge paths.

When services evolve independently, contract tests catch status drift early. If your architecture is moving toward microservices, pair this reference with contract testing with Pact.

Interview and Review Language You Can Reuse

When reviewing an API design or answering interview questions, use precise phrases:

  • “401 means authentication failed. 403 means authorization failed.”
  • “I validate status, body schema, headers, and side effects together.”
  • “Invalid input should not become 500.”
  • “Idempotent retries need an explicit second-response policy.”
  • “Error bodies need stable machine codes and safe human messages.”

That language signals senior API testing judgment.

Checklist: REST API Status Codes Before Release

  • Documented status codes match implemented behavior.
  • Happy path uses the correct 2xx code for the method.
  • Missing auth returns 401 on protected routes.
  • Wrong role or scope returns 403 or the documented isolation code.
  • Unknown resources return 404 or 410 as designed.
  • Validation failures return 400 or 422 consistently.
  • Conflicts return 409 where state clashes are possible.
  • Rate limits return 429 with retry guidance when applicable.
  • Async accepts return 202 with a status tracking mechanism.
  • 5xx responses never leak secrets or stack traces.
  • Write failures do not partially commit critical data.
  • Monitoring alerts exist for abnormal 4xx and 5xx rates.

Final Takeaways

REST API status codes are a shared language for product behavior under success and failure. Testers who master them find higher severity defects faster because they can spot semantic mismatches, not only schema mismatches.

Remember the core rules:

  • Status family must match outcome class.
  • Body and headers must support the status.
  • Side effects must agree with success or failure.
  • Consistency across endpoints is part of quality.
  • Safety matters as much as correctness for error responses.

Use this reference while designing cases, reviewing OpenAPI files, writing automation, and triaging production incidents. When the status line tells the truth, every client above the API becomes easier to build, test, and trust.

If you want structured practice across API scenarios, create an account on QABattle sign-up and work through API track battles that force you to justify expected codes before you run the request.

FAQ

Questions testers ask

What are the most common HTTP status codes?

The most common HTTP status codes testers meet are 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity, 429 Too Many Requests, 500 Internal Server Error, and 503 Service Unavailable. Learn the meaning of each family, then verify the body and headers with the status.

What is the difference between 401 and 403?

401 Unauthorized means the request lacks valid authentication, so the client should sign in or send a valid token. 403 Forbidden means the server understood the identity but refuses the action, usually because of permissions, roles, or policy. 401 is about who you are. 403 is about what you are allowed to do.

When should an API return 400 vs 422?

400 Bad Request usually means the request is malformed: invalid JSON, wrong types, missing required structure, or a client message the server cannot parse. 422 Unprocessable Entity is often used when syntax is valid but business validation fails, such as an email already registered or a date in the past. Many APIs still map both cases to 400, so test against the actual contract.

What is the difference between 404 and 410?

404 Not Found means the resource does not exist or is not visible to the caller. 410 Gone means the resource used to exist and has been permanently removed. Use 410 when clients should stop requesting the URL. Use 404 when the resource is missing, hidden, or never existed.

Should failed validation return 200 with an error body?

No. Successful HTTP status codes should not carry business failure. Returning 200 with {"success": false} hides failures from clients, monitors, and automated tests that trust status families. Prefer a 4xx status plus a structured error body. If a legacy API still returns 200 for failures, document that behavior and assert both status and payload.

How should testers validate REST API error responses?

Validate the status code, Content-Type, error code or type, human-readable message, field-level details when relevant, correlation or request IDs, and absence of stack traces or secrets. Then check that retries, logging, and client handling behave correctly for that status family.