{ }HttpStatus.com

303 See Other

The response to the request can be found under a different URL and should be retrieved with a GET.

Defined in RFC 9110 §15.4.4

What 303 means

A 303 response redirects the client to a different resource using GET, regardless of the original request method. It was introduced in HTTP/1.1 specifically to resolve the ambiguity that plagued 302: where 302 left it unclear whether the method should change, 303 states unambiguously that the client must issue a GET to the Location URL, without carrying over the original request body.

This makes 303 the semantically correct status for the post/redirect/get pattern, since it removes any guesswork about client behavior. A typical use is a form submission or an API action (like creating an order) that responds with 303 pointing at a URL representing the result of that action, such as the newly created resource or a status page, so a page refresh safely re-issues a GET instead of resubmitting the original POST.

303 is also common in RESTful APIs to decouple an action endpoint from a result resource: a client POSTs to trigger asynchronous work, and the server responds 303 pointing to a URL where the result (or its current status) can be fetched with GET. This differs from 202 Accepted, which does not necessarily imply a redirect target, and from 201 Created, which returns the created resource’s location directly rather than instructing a follow-up GET.

Browsers do not cache 303 responses by default, and unlike 301/308 there is no expectation that the redirect is long-lived or that link equity should transfer, so it carries no particular SEO implication beyond a normal temporary redirect.

Common causes

  • A server wants to guarantee the client switches to GET after a POST, PUT, or DELETE, removing the ambiguity 302 has historically had.
  • A form submission handler redirects to a confirmation or receipt page after processing.
  • A REST API returns 303 after an action endpoint to point the client at a resource representing the result.
  • An asynchronous job endpoint redirects to a status URL that can be polled with GET.
  • A framework’s "redirect after write" helper is configured to use 303 explicitly instead of the framework default of 302.

How to fix a 303

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

  • Always follow a 303 with a GET request to the Location URL, dropping the original request body.
  • Do not resubmit the original POST/PUT data to the Location; treat it as a fresh resource fetch.
  • If building a client library, ensure your redirect handling special-cases 303 to force GET even if it otherwise preserves methods for 307/308.
  • Use the returned resource at Location as the authoritative result of the original action, not the original request’s response body.

If you run the server

  • Return 303 (not 302) whenever you specifically want the client to switch to GET after a non-GET request, for unambiguous behavior across all HTTP-compliant clients.
  • Point Location at a URL that meaningfully represents the outcome of the action, such as the created resource, an order confirmation, or a job status endpoint.
  • Avoid chaining a 303 into another redirect; resolve straight to the final GET-able resource.
  • Pair 303 with appropriate resource state (200 on the target) so the redirected GET does not itself need further explanation.

Example

POST /orders HTTP/1.1
Host: shop.example.com
Content-Type: application/json

{ "item": "widget", "qty": 2 }

HTTP/1.1 303 See Other
Location: https://shop.example.com/orders/12345

GET /orders/12345 HTTP/1.1
Host: shop.example.com
Creating an order via POST, then redirecting with 303 to fetch it via GET.

Try it live

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

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

Related status codes

Tools for debugging this