When a server returns a 2xx status code, it means the request was received, understood, and processed successfully. That is the entire point of the 2xx class – the client’s request worked. But “worked” means different things depending on which 2xx code the server returns.
A 200 means the server is returning the result you asked for. A 201 means a new resource was created. A 204 means the operation succeeded but there is nothing to send back. A 202 means the server accepted the request but has not finished processing it yet. Each code communicates something specific about what happened, and using the right one matters for API design, caching behavior, and client-side logic.
This guide covers every 2xx status code you will encounter in practice, when to use each one, the headers that should accompany them, and the common mistakes that cause bugs in API clients and broken caching.
200 OK#
The most common HTTP status code. A 200 means the request succeeded and the server is returning a response body with the result.
HTTP/1.1 200 OK
Content-Type: application/json
{"id": 42, "name": "Example", "status": "active"}
A 200 is the default success response for GET requests. The client asked for something, and here it is. For POST requests, a 200 means the operation completed and the response body contains the result or a status message.
When to use 200
- GET requests that return data: fetching a user, listing products, loading a page
- POST requests that perform an action and return a result: processing a payment, running a calculation, submitting a search query
- PUT/PATCH requests that update a resource and return the updated version
When not to use 200
Do not return 200 when a new resource was created – use 201 instead. Do not return 200 with an empty body when a DELETE succeeds – use 204. Do not return 200 when the request was accepted but processing has not finished – use 202.
A common anti-pattern in API design is returning 200 for everything, including errors:
HTTP/1.1 200 OK
{"success": false, "error": "User not found"}
This forces the client to parse the response body to determine if the request actually succeeded. Use the appropriate status code instead – a 404 for not found, a 401 for unauthorized, a 500 for server errors. Status codes exist so clients can handle success and failure without inspecting the body.
201 Created#
A 201 means the request succeeded and a new resource was created as a result. This is the correct response for POST requests that create something – a new user account, a new blog post, a new order, a new API key.
HTTP/1.1 201 Created
Location: /api/users/42
Content-Type: application/json
{"id": 42, "name": "Jane", "email": "jane@example.com", "created_at": "2026-04-08T14:30:00Z"}
The Location header
A 201 response should include a
Location
header containing the URL of the newly created resource. This tells the client where to find the thing that was just created without having to parse the response body for an ID and construct the URL itself.
Location: /api/users/42
Not including the
Location
header is technically valid but makes the API harder to use. Clients that follow the REST convention expect to receive the URL of the new resource in this header.
Response body
The response body should contain a representation of the created resource. This saves the client from making a follow-up GET request to retrieve the resource it just created. Include at minimum the server-generated fields: the ID, creation timestamp, and any default values the server applied.
When to use 201
- POST /api/users with user data – user was created, return the user with their new ID
- POST /api/orders with order details – order was created, return the order with its status
- POST /api/files with a file upload – file was stored, return the file metadata with its URL
201 and idempotency
If a client sends the same POST request twice (due to a network retry, a double-click, or a timeout), should the server create two resources or one? This is the idempotency question, and the status code communicates the answer:
- First request: server creates the resource, returns 201 Created
- Second request (duplicate): server detects the duplicate and returns 200 OK with the existing resource, or 409 Conflict if duplicates are not allowed
The status code tells the client whether it created something new (201) or received something that already existed (200). This distinction matters for billing APIs, order systems, and any endpoint where duplicate creation has consequences.
Common mistake: returning 200 instead of 201
Many APIs return 200 for creation operations. The client has no way to distinguish “the resource was created” from “the resource already existed” without parsing the response body. Using 201 makes this distinction at the protocol level – any HTTP client library can check the status code without custom logic.
202 Accepted#
A 202 means the server accepted the request and will process it later. The request is valid and the server intends to act on it, but processing has not completed yet. This is the correct response for asynchronous operations.
HTTP/1.1 202 Accepted
Content-Type: application/json
{"status": "processing", "job_id": "abc-123", "check_url": "/api/jobs/abc-123"}
When to use 202
- Long-running operations that take more than a few seconds: video encoding, report generation, large data imports, bulk email sends
- Queued operations where the request is added to a processing queue: webhook deliveries, background job submissions
- Operations that depend on external services where the result is not immediately available
How the client knows when processing is done
The 202 response should include information about how to check the status:
- A URL to poll for status (the
check_urlin the example above) - An estimated completion time
- A webhook URL where the server will POST the result when processing finishes
Without this, the client has no way to know when the operation completes. A 202 without status checking information is technically valid but practically useless.
202 vs 200
If the operation completes synchronously (within the request-response cycle), return 200 with the result. If the operation is queued or deferred, return 202. The distinction tells the client whether the result is already available or if it needs to check back later.
204 No Content#
A 204 means the request succeeded but there is no content to return. The server processed the request, the operation was successful, and there is intentionally nothing in the response body.
HTTP/1.1 204 No Content
No response body. No
Content-Type
header. Just the status code and any relevant headers.
When to use 204
- DELETE requests where the resource was successfully deleted. There is nothing to return because the resource no longer exists.
- PUT/PATCH requests where the update succeeded but the client does not need the updated resource back (for example, a settings toggle where the client already knows the new value because it sent it).
- POST requests that perform an action with no meaningful result to return: “mark all notifications as read,” “clear cache,” “send ping.”
204 in WordPress REST API
The WordPress REST API uses 204 for DELETE operations. When you delete a post through the API:
DELETE /wp-json/wp/v2/posts/42
WordPress returns a 200 with the deleted post data by default (to give you one last look at what was removed). With the
?force=true
parameter, it permanently deletes the post and returns the trashed post object. Some custom endpoints return 204 for delete operations when there is no meaningful data to return.
204 vs 200 with empty body
A 200 with an empty body and a 204 are functionally similar, but they communicate different things:
- 200 with
{}means “the operation succeeded, and here is the result – it happens to be empty” - 204 means “the operation succeeded, and I am intentionally not sending you anything”
For DELETE operations, 204 is the standard choice. For GET operations, 204 is almost never correct – if a GET returns no data, that usually means the resource does not exist (404) or the collection is empty (200 with an empty array).
Common mistake: including a body with 204
A 204 response must not contain a body. If you return a body with a 204 status code, some HTTP clients and proxies will ignore the body, while others will try to parse it and potentially fail. If you need to return data, use 200 instead.
206 Partial Content#
A 206 means the server is returning only part of the resource because the client requested a specific range. This is used for resumable downloads, video streaming, and large file transfers where the client fetches the content in chunks.
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/4096
Content-Length: 1024
Content-Type: application/octet-stream
How range requests work
The client sends a
Range
header specifying which bytes it wants:
GET /video.mp4 HTTP/1.1
Range: bytes=0-1023
The server returns a 206 with a
Content-Range
header showing which bytes are included and the total size. The client can then request the next chunk:
Range: bytes=1024-2047
This is how video players seek to a specific position without downloading the entire file, how browsers resume interrupted downloads, and how download managers split files into parallel streams.
When you see 206
You typically do not send 206 responses manually. Your web server (Nginx, Apache) handles range requests automatically for static files. If you are building an API that serves large files, you need to implement range request handling in your application code, but for most web hosting scenarios the web server takes care of it.
If you are seeing unexpected 206 responses in your access logs, it usually means clients (often bots or download tools) are making range requests against your files. This is normal behavior.
Other 2xx codes#
203 Non-Authoritative Information
The response is a modified version of the original server’s response. This is rare and primarily used by transforming proxies that modify the response before forwarding it. You will almost never need to use or handle this code.
205 Reset Content
Tells the client to reset the document view – for example, clearing a form after submission. This was designed for HTML form workflows and is rarely used in modern APIs. Most applications handle form resets client-side with JavaScript.
207 Multi-Status (WebDAV)
Used in WebDAV operations that affect multiple resources. The response body contains status information for each resource. If you are not working with WebDAV, CalDAV, or CardDAV, you will not encounter this.
208 Already Reported (WebDAV)
Used inside a 207 Multi-Status response to avoid repeating the same information. WebDAV-specific and not relevant to standard web development.
2xx codes in context with other HTTP classes#
The 2xx class is one of five:
- 1xx Informational – the server received the request and is continuing to process it
- 2xx Success – the request succeeded
- 3xx Redirection – the client needs to take additional action, like following a redirect to a new URL
- 4xx Client Error – the request was invalid. The client sent something wrong: bad syntax, missing authentication (401), forbidden resource (403), wrong HTTP method (405), or too many requests
- 5xx Server Error – the server failed while processing a valid request. 500, 502, 503, 504
When designing an API, using the correct status code from each class makes the API self-documenting. A client that checks the status code can determine what happened without parsing the response body, and HTTP infrastructure (caches, proxies, CDNs, monitoring tools) can make intelligent decisions based on the status code alone.
Quick reference#
| Code | Name | When to use |
|---|---|---|
| 200 | OK | Request succeeded, response body contains the result |
| 201 | Created | New resource created, include Location header |
| 202 | Accepted | Request accepted, processing will happen later |
| 204 | No Content | Operation succeeded, no body to return |
| 206 | Partial Content | Returning a requested byte range of a resource |
Common mistakes#
| Mistake | Why it matters |
|---|---|
| Returning 200 for everything, including errors | Clients cannot distinguish success from failure without parsing the body |
| Returning 200 when a resource was created | Client cannot tell if the resource was created or already existed |
| Including a response body with 204 | Some clients and proxies will break or ignore the body |
| Not including Location header with 201 | Client has to parse the body to find the new resource URL |
| Returning 204 for GET requests with no results | Use 200 with an empty collection or 404 if the specific resource does not exist |
| Returning 202 without a way to check status | Client has no way to know when processing completes |