303 See Other

When the result of a request is viewable at a different URI, the server responds with 303 See Other. The Location header links to an alternative page, such as an upload confirmation message, rather than the recently uploaded resource. The method for the follow-up request is GET or HEAD.

Usage

The 303 See Other status code is typically returned after a POST, PUT, or DELETE request. The result of the operation is viewable at a different URL, and the client fetches the new resource with a GET request to the specified Location.

303 vs 302

Both codes point the client at a different address for the current request, and both leave the original address in the index. The separation is precision.

303 See Other is unambiguous. The client issues a GET against the address in Location whatever method started the exchange, other than HEAD, which stays HEAD. The code states the conversion outright rather than leaving to client behavior.

302 leaves room for interpretation. Its specification expects the method to repeat, while the Fetch Standard requires browsers to convert a redirected POST into a GET. The gap between the written behavior and the browser mandate is the reason 303 exists.

Choosing 303 after a form submission makes the intent explicit and produces the same result on every client, rather than the result most clients happen to produce. Choosing 302 works in browsers and gets less predictable with API clients and libraries implementing the specification to the letter.

303 vs 307

Both codes are temporary redirects leaving the original address indexed, and they take opposite positions on the request method.

303 See Other converts the follow-up request to GET, or HEAD where the original request used HEAD, whatever method started the exchange. 307 preserves the original method and body exactly.

The opposition makes the choice straightforward once the goal is clear. A POST handler sending the client to a result page wants 303, because the result is a document to retrieve rather than an action to repeat, and refreshing the result page reloads the document instead of resubmitting the form. Redirecting a request needing to happen again at a different address wants 307, because the method and payload survive the hop.

Reaching for 302 instead leaves the outcome to client convention rather than stating either intent.

Example

The client requests deletion of a specific resource. The server sends 303 See Other because the original location no longer holds a viewable resource and points to a confirmation page at the new Location.

Request

DELETE /tasks/314 HTTP/1.1
Host: www.example.re

Response

HTTP/1.1 303 See Other
Location: http://www.example.re/confirmation/delete.html

Code references

.NET

HttpStatusCode.SeeOther

Rust

http::StatusCode::SEE_OTHER

Rails

:see_other

Go

http.StatusSeeOther

Symfony

Response::HTTP_SEE_OTHER

Python3.5+

http.HTTPStatus.SEE_OTHER

Java

java.net.HttpURLConnection.HTTP_SEE_OTHER

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_SEE_OTHER

Angular

@angular/common/http/HttpStatusCode.SeeOther

See also

Last updated: August 17, 2026