{ }HttpStatus.com

200 OK

The request succeeded and the response body, if any, contains the requested representation or the result of the action.

Defined in RFC 9110 §15.3.1

What 200 means

HTTP 200 OK is the baseline success response for the whole HTTP protocol: the request was understood, accepted, and processed without error, and the response carries the outcome the client asked for. For GET, that means the requested representation of the resource is in the body. For POST, PUT, PATCH, or DELETE, it means the action completed and the body, if present, describes the result. Because 200 covers such a broad range of outcomes, it is deliberately generic; more specific 2xx codes like 201, 202, or 204 exist to communicate additional nuance that 200 alone does not carry.

200 is by far the most common status code on the web, returned for ordinary page loads, API reads, health checks, and successful writes alike, which means it is also the code most often misused. A frequent anti-pattern is returning 200 for requests that actually failed at the application level, with an error message and error code embedded in the JSON body instead of using an appropriate 4xx or 5xx status. This defeats HTTP-aware tooling: caches, monitoring, load balancers, and generic HTTP clients all read the status line first, and a 200 wrapped around an error looks like success to every layer that is not specifically parsing the body.

Whether a 200 response is cacheable depends on the method and the response headers, not the status code alone; GET responses are cacheable by default subject to Cache-Control and validators like ETag or Last-Modified, while responses to POST, PUT, and DELETE are not cached unless explicit caching headers say otherwise. A 200 in response to a conditional GET (with If-None-Match or If-Modified-Since) means the representation changed since the client's cached copy, which is why servers should prefer 304 Not Modified when nothing has actually changed, saving bandwidth on both sides.

Browsers render 200 responses as normal pages, and most HTTP client libraries treat status codes in the 200-299 range as success without raising an exception, which is exactly why silently swallowing errors inside a 200 body is so dangerous for API consumers relying on that default behavior. REST API design guides consistently recommend reserving 200 for genuinely successful, synchronous requests and using the more specific 2xx, 4xx, or 5xx codes everywhere else so both humans and automated tooling can trust the status line.

Common causes

  • A GET request successfully retrieved an existing resource and the server returned its current representation.
  • A POST, PUT, PATCH, or DELETE request completed successfully and the server chose to return a body describing the result rather than an empty 204.
  • A health check, ping, or monitoring endpoint confirmed the service is reachable and functioning.
  • An API handler caught an application-level error but, instead of setting an error status, returned 200 with an error object in the JSON body.
  • A framework's default response for any unhandled route that does not explicitly set a status code.

How to fix a 200

If you are the client (browser user or API caller)

  • Never assume a 200 status alone means success; check the response body for an application-level error field when the API is known to embed errors that way.
  • Rely on the Content-Type header to correctly parse the body, since a 200 can carry HTML, JSON, plain text, or binary data depending on the endpoint.
  • Use conditional requests with If-None-Match or If-Modified-Since so a fully cached copy is not re-downloaded when the server would otherwise reply 304.
  • Log or alert on unexpected 200 responses that lack the fields your integration depends on, since a silent schema change can otherwise slip through undetected.

If you run the server

  • Return the actual outcome-specific status code, 201 for created resources, 204 for empty successful writes, 4xx or 5xx for failures, instead of always defaulting to 200.
  • Never encode an application error inside a 200 response body; use the matching 4xx or 5xx status so caches, proxies, and generic clients behave correctly.
  • Set explicit Cache-Control, ETag, or Last-Modified headers on cacheable 200 GET responses to enable conditional requests and reduce redundant transfers.
  • Keep the response body's structure consistent for a given endpoint so clients can rely on the shape of a 200 response, not just its presence.

Example

GET /api/users/42 HTTP/1.1
Host: api.example.com
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=60
ETag: "a1b2c3"

{
  "id": 42,
  "name": "Ada Lovelace",
  "email": "ada@example.com"
}
A GET request returns the current representation of an existing resource.

Try it live

Our free status responder returns a real HTTP 200 you can point tests, monitors or a browser at.

GET https://mcp.httpstatus.com/status/200

Related status codes

Tools for debugging this