DevToolBoxGRATIS
Blogg

HTTP Statuskoder Guide: Komplett referens for REST API:er

15 min lasningby DevToolBox

What Are HTTP Status Codes?

HTTP status codes are three-digit numbers returned by a server in response to a client's request. Every time your browser visits a webpage or your application calls an API, the server responds with a status code indicating whether the request succeeded, failed, or requires further action. Understanding HTTP status codes is essential for building robust APIs, debugging network issues, and creating proper error handling.

Status codes are grouped into five classes by their first digit: 1xx (Informational), 2xx (Success), 3xx (Redirection), 4xx (Client Error), and 5xx (Server Error). This guide covers every commonly used status code with practical examples of when to use each in REST APIs.

Look up any HTTP status code instantly with our HTTP Status Code Reference tool.

1xx Informational Responses

1xx status codes indicate that the server received the request and the client should continue. These are rarely encountered in typical web development but are important for specific protocols and long-running connections.

100 Continue

The server received the request headers and the client should proceed to send the body. This is used with the Expect: 100-continue header, allowing the client to check if the server will accept the request before sending a large body.

# Client sends headers first
POST /upload HTTP/1.1
Host: api.example.com
Content-Length: 50000000
Expect: 100-continue

# Server responds: OK, send the body
HTTP/1.1 100 Continue

101 Switching Protocols

The server is switching to a different protocol as requested by the client. Most commonly seen when upgrading from HTTP to WebSocket.

# WebSocket upgrade request
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade

# Server agrees to switch
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade

103 Early Hints

Allows the server to send preliminary headers before the final response, enabling the browser to start preloading resources while the server prepares the full response.

2xx Success

2xx status codes indicate the request was successfully received, understood, and accepted. These are the codes you want to see in your API responses.

200 OK

The most common success code. The request succeeded and the response body contains the requested data. Use 200 for successful GET requests and PUT/PATCH updates that return the updated resource.

# GET request - return data
GET /api/users/123
HTTP/1.1 200 OK
Content-Type: application/json

{"id": 123, "name": "Alice", "email": "alice@example.com"}
// REST API: When to use 200
// GET /users - list users
// GET /users/123 - get a specific user
// PUT /users/123 - update a user (return updated resource)
// PATCH /users/123 - partial update (return updated resource)
// POST /search - search (when not creating a resource)

201 Created

A new resource was successfully created. Use 201 for POST requests that create a new entity. The response should include the created resource and a Location header pointing to the new resource.

# POST request - create new resource
POST /api/users
Content-Type: application/json

{"name": "Bob", "email": "bob@example.com"}

HTTP/1.1 201 Created
Location: /api/users/456
Content-Type: application/json

{"id": 456, "name": "Bob", "email": "bob@example.com"}

202 Accepted

The request has been accepted for processing, but processing is not yet complete. Use 202 for asynchronous operations like batch jobs, email sending, or video processing where the result is not immediately available.

# Async operation
POST /api/reports/generate
HTTP/1.1 202 Accepted
Content-Type: application/json

{"status": "processing", "jobId": "abc-123", "checkUrl": "/api/jobs/abc-123"}

204 No Content

The request succeeded but there is no content to return. Use 204 for successful DELETE requests and PUT/PATCH updates when you do not need to return the updated resource.

# DELETE request - resource removed, nothing to return
DELETE /api/users/123
HTTP/1.1 204 No Content

# PUT request - update succeeded, no body needed
PUT /api/users/123/settings
HTTP/1.1 204 No Content

3xx Redirection

3xx status codes indicate the client must take additional action to complete the request, usually by following a redirect to a different URL.

301 Moved Permanently

The resource has permanently moved to a new URL. Search engines transfer SEO value to the new URL. Browsers and clients cache this redirect. Use 301 when you permanently rename or restructure URLs.

# Old URL permanently redirects to new URL
GET /old-page
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page

# Common use cases:
# - HTTP to HTTPS redirect
# - www to non-www (or vice versa)
# - Old URL structure to new URL structure
# - Domain migration

302 Found (Temporary Redirect)

The resource is temporarily available at a different URL. The client should continue using the original URL for future requests. Use 302 for temporary redirects like maintenance pages or A/B testing.

# Temporary redirect (e.g., during maintenance)
GET /dashboard
HTTP/1.1 302 Found
Location: /maintenance

# Or redirect after form submission
POST /login
HTTP/1.1 302 Found
Location: /dashboard

303 See Other

The response to the request can be found at a different URL using a GET request. Used to redirect after a POST/PUT/DELETE to prevent form resubmission (Post/Redirect/Get pattern).

304 Not Modified

The resource has not been modified since the last request. The client should use its cached copy. This code is critical for performance — it saves bandwidth by avoiding retransmitting unchanged resources.

# Client sends conditional request
GET /api/users/123
If-None-Match: "etag-abc123"

# Server: resource unchanged, use your cache
HTTP/1.1 304 Not Modified

# Or with date-based caching
GET /api/data
If-Modified-Since: Tue, 15 Jan 2026 12:00:00 GMT

HTTP/1.1 304 Not Modified

307 Temporary Redirect

Like 302, but guarantees the HTTP method will not change. If the original request was POST, the redirect will also be POST. Use 307 when you need to preserve the request method.

308 Permanent Redirect

Like 301, but guarantees the HTTP method will not change. Use 308 when you need a permanent redirect that preserves POST/PUT methods.

4xx Client Errors

4xx status codes indicate the client made an error. The request contains bad syntax, invalid parameters, or lacks proper authentication. The client should modify the request before retrying.

400 Bad Request

The server cannot process the request due to a client error: malformed syntax, invalid parameters, or missing required fields. This is the general-purpose client error code.

# Missing required field
POST /api/users
Content-Type: application/json

{"name": "Alice"}

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Bad Request",
  "message": "Validation failed",
  "details": [
    {"field": "email", "message": "Email is required"},
    {"field": "name", "message": "Name must be at least 2 characters"}
  ]
}
// Common causes of 400 errors:
// - Missing required request body fields
// - Invalid JSON syntax
// - Invalid query parameters
// - Invalid date formats
// - Number out of range
// - Invalid enum values

401 Unauthorized

The request requires authentication. The client must provide valid credentials (API key, JWT token, or session cookie). Despite the name, this is about authentication (identity), not authorization (permissions).

# No token provided
GET /api/profile
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

{"error": "Unauthorized", "message": "Authentication token is required"}

# Expired or invalid token
GET /api/profile
Authorization: Bearer expired-token-here
HTTP/1.1 401 Unauthorized

{"error": "Unauthorized", "message": "Token has expired"}

403 Forbidden

The server understood the request but refuses to authorize it. Unlike 401, the client's identity is known but they lack permission to access the resource. Re-authenticating will not help.

# Authenticated but not authorized
GET /api/admin/users
Authorization: Bearer valid-user-token

HTTP/1.1 403 Forbidden
{"error": "Forbidden", "message": "Admin role required"}

# 401 vs 403:
# 401: "I don't know who you are. Please log in."
# 403: "I know who you are, but you can't access this."

404 Not Found

The server cannot find the requested resource. This is the most recognized error code on the web. In APIs, use 404 when a specific resource does not exist.

# Resource does not exist
GET /api/users/999999
HTTP/1.1 404 Not Found

{"error": "Not Found", "message": "User with ID 999999 does not exist"}

# Invalid endpoint
GET /api/nonexistent
HTTP/1.1 404 Not Found

{"error": "Not Found", "message": "Endpoint /api/nonexistent does not exist"}

405 Method Not Allowed

The HTTP method is not supported for the requested resource. The response must include an Allow header listing the supported methods.

# DELETE not allowed on this endpoint
DELETE /api/users
HTTP/1.1 405 Method Not Allowed
Allow: GET, POST

{"error": "Method Not Allowed", "message": "DELETE is not supported. Use GET or POST."}

409 Conflict

The request conflicts with the current state of the resource. Use 409 for duplicate entries, version conflicts, or operations that violate business rules.

# Duplicate email
POST /api/users
{"name": "Alice", "email": "alice@example.com"}

HTTP/1.1 409 Conflict
{"error": "Conflict", "message": "A user with email alice@example.com already exists"}

# Optimistic locking conflict
PUT /api/articles/123
If-Match: "etag-old-version"

HTTP/1.1 409 Conflict
{"error": "Conflict", "message": "Resource was modified by another request"}

422 Unprocessable Entity

The request is syntactically correct but semantically invalid. Use 422 for validation errors where the JSON is well-formed but the values are wrong. Some APIs use 400 instead; both approaches are valid.

# Valid JSON but invalid values
POST /api/users
{"name": "A", "email": "not-an-email", "age": -5}

HTTP/1.1 422 Unprocessable Entity
{
  "error": "Validation Error",
  "details": [
    {"field": "name", "message": "Must be at least 2 characters"},
    {"field": "email", "message": "Must be a valid email address"},
    {"field": "age", "message": "Must be a positive number"}
  ]
}

429 Too Many Requests

The client has sent too many requests in a given time period (rate limiting). The response should include a Retry-After header indicating when the client can retry.

# Rate limit exceeded
GET /api/data
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706792400

{"error": "Too Many Requests", "message": "Rate limit exceeded. Try again in 60 seconds."}

5xx Server Errors

5xx status codes indicate the server failed to fulfill a valid request. These are server-side problems that the client cannot fix by modifying their request.

500 Internal Server Error

A generic server-side error. Something went wrong on the server that was not expected. This is the catch-all error code for unhandled exceptions, crashes, or bugs.

# Server encountered an unexpected error
GET /api/users
HTTP/1.1 500 Internal Server Error

{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred. Please try again later.",
  "requestId": "req-abc-123"
}
// Best practices for 500 errors:
// - Log the full error details server-side
// - Return a generic message to the client (no stack traces!)
// - Include a request ID for debugging
// - Set up monitoring/alerting for 500 errors
// - Never expose internal implementation details

501 Not Implemented

The server does not support the functionality required to fulfill the request. Use 501 for API endpoints that are planned but not yet built.

# Feature not yet implemented
POST /api/v2/export
HTTP/1.1 501 Not Implemented

{"error": "Not Implemented", "message": "Export feature is coming in v2.1"}

502 Bad Gateway

The server, acting as a gateway or proxy, received an invalid response from the upstream server. Common with reverse proxies (Nginx), load balancers, and API gateways when the backend service is down or responding incorrectly.

# Nginx cannot reach the backend
GET /api/data
HTTP/1.1 502 Bad Gateway

# Common causes:
# - Backend service crashed
# - Backend not started
# - Misconfigured proxy settings
# - Network issues between proxy and backend
# - Backend returning malformed responses

503 Service Unavailable

The server is temporarily unable to handle requests. Use 503 during planned maintenance, when the server is overloaded, or when a critical dependency is down. Include a Retry-After header when possible.

# Planned maintenance
GET /api/users
HTTP/1.1 503 Service Unavailable
Retry-After: 3600

{"error": "Service Unavailable", "message": "Server is under maintenance. Expected back at 14:00 UTC."}

# Database connection pool exhausted
GET /api/data
HTTP/1.1 503 Service Unavailable
Retry-After: 30

{"error": "Service Unavailable", "message": "Server temporarily overloaded. Please retry."}

504 Gateway Timeout

The server, acting as a gateway, did not receive a timely response from the upstream server. Similar to 502 but specifically about timeout rather than an invalid response.

# Backend took too long to respond
GET /api/heavy-report
HTTP/1.1 504 Gateway Timeout

# Common causes:
# - Slow database queries
# - Long-running computations
# - Upstream service timeout
# - Network latency issues

HTTP Status Codes Quick Reference Table

CodeNameWhen to Use
200OKSuccessful GET, PUT, PATCH requests
201CreatedSuccessful POST that creates a resource
204No ContentSuccessful DELETE or update with no response body
301Moved PermanentlyPermanent URL change (SEO redirect)
302FoundTemporary redirect
304Not ModifiedResource unchanged, use cached version
400Bad RequestInvalid syntax, missing fields
401UnauthorizedMissing or invalid authentication
403ForbiddenAuthenticated but not authorized
404Not FoundResource does not exist
405Method Not AllowedHTTP method not supported for endpoint
409ConflictDuplicate entry or version conflict
422Unprocessable EntityValidation errors (semantic)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnhandled server exception
502Bad GatewayUpstream server returned invalid response
503Service UnavailableServer maintenance or overloaded
504Gateway TimeoutUpstream server timed out

REST API Status Code Best Practices

  • Be specific: Use 201 for creation, not 200. Use 204 for deletion, not 200. Specific codes help clients handle responses correctly.
  • Use 4xx for client errors, 5xx for server errors: If the client can fix the problem by changing the request, use 4xx. If the problem is on the server, use 5xx.
  • Include error details: Return a JSON body with error message, error code, and details (especially for 400/422 validation errors).
  • Never expose internals in 5xx: Do not include stack traces, database errors, or internal paths in error responses. Log them server-side and return a generic message.
  • Use Retry-After headers: For 429 (rate limiting) and 503 (maintenance), include a Retry-After header to tell clients when to retry.
  • Include Location headers for 201: When creating resources, include a Location header pointing to the new resource URL.
  • Consistent error format: Use the same error response structure throughout your API for easy client-side error handling.

Frequently Asked Questions

What is the difference between 401 and 403?

401 Unauthorized means the client has not provided authentication credentials or the credentials are invalid. The solution is to log in or provide a valid token. 403 Forbidden means the client is authenticated (the server knows who they are) but lacks permission to access the resource. Re-authenticating will not help; the user needs different permissions or a different role.

Should I use 400 or 422 for validation errors?

Both are valid choices. 400 Bad Request is more commonly used and widely understood. 422 Unprocessable Entity is more specific: the syntax is correct but the semantic content is invalid. Popular frameworks like Rails use 422 for validation errors, while many REST APIs use 400. The important thing is consistency within your API.

When should I use 404 vs 204?

Use 404 when the resource genuinely does not exist and the client needs to know. Use 204 when the request succeeded but there is simply no content to return (like a successful DELETE). If a GET request finds no results for a collection, return 200 with an empty array, not 404.

What is the difference between 302 and 307?

Both are temporary redirects. 302 Found historically allowed browsers to change the HTTP method (e.g., POST became GET after redirect). 307 Temporary Redirect guarantees the method and body are preserved. Use 307 when redirecting POST or PUT requests to ensure the method does not change. For GET redirects, 302 and 307 behave identically.

How should I handle 5xx errors in my application?

Implement retry logic with exponential backoff for 500, 502, 503, and 504 errors. For 503, honor the Retry-After header if present. Log the error with the request ID for debugging. Display a user-friendly error message and offer a retry option. Set up monitoring to alert your team when 5xx error rates spike.

𝕏 Twitterin LinkedIn
Var detta hjälpsamt?

Håll dig uppdaterad

Få veckovisa dev-tips och nya verktyg.

Ingen spam. Avsluta när som helst.

Try These Related Tools

4xxHTTP Status Code Reference{ }JSON Formatter

Related Articles

HTTP-huvuden Komplett lista och referens

Komplett referens för HTTP-huvuden med exempel.

HTTP-statuskoder: Komplett referensguide för utvecklare

Komplett HTTP-statuskodreferens: 1xx-5xx med praktiska förklaringar, API best practices och debuggingtips.

REST API Best Practices: Den Kompletta Guiden för 2026

Lär dig REST API design best practices: namnkonventioner, felhantering, autentisering och säkerhet.