HTTP 303

303 See Other

Redirect

The server is redirecting the client to a different URL using a GET request, regardless of the method used in the original request. 303 was introduced in HTTP/1.1 specifically to give servers a way to instruct clients to switch to GET. Solving the ambiguity around 302 where the spec said one thing and clients did another. The canonical use case is the Post/Redirect/Get pattern after a form submission.

When does this happen?

Return 303 after a successful POST when you want the browser to fetch a different resource with GET. Typically a result, confirmation, or detail page. The Post/Redirect/Get pattern prevents the dreaded "are you sure you want to resubmit the form?" dialog when a user refreshes the page after submitting. Without the 303, refreshing would resend the POST and could create duplicate orders, comments, or payments. The Location header is mandatory. Unlike 302, the method change to GET is required by spec, not just convention. Every conforming client will issue a GET on the next request even if the original was POST or PUT. The body of the 303 response can include a hypertext explanation for clients that do not auto-follow. 303 should not be used as a generic redirect for GET requests. Use 302 or 307 instead, since 303 carries the specific semantic of "and switch to GET".

Common causes

How to fix it

Real-world examples

User submits a contact form via POST /contact.
Server saves the submission and returns 303 with Location: /contact/thanks. Browser issues GET /contact/thanks. Refreshing the thanks page does not resubmit the form.
User completes checkout via POST /checkout with their cart and payment details.
Server creates the order and returns 303 with Location: /orders/abc123/confirmation. Browser GETs the confirmation page. Refreshing the confirmation page does not double-charge.
API client kicks off a long-running export via POST /v1/exports.
Server creates a job and returns 303 with Location: /v1/exports/job-42. Client issues GET on that URL to poll status.
User submits a comment via POST /posts/123/comments.
Server appends the comment and returns 303 with Location: /posts/123#comment-456. Browser issues GET on the post page with the new comment visible.

How it differs from related codes

HTTP 302

302 is ambiguous about method handling. Most clients downgrade to GET but the spec does not require it. 303 explicitly mandates GET for the follow-up request.

HTTP 307

307 is the opposite of 303. It requires the client to preserve the original method and body. Use 303 to switch to GET, 307 to keep POST as POST.

HTTP 200

Returning 200 directly from a POST gives the client the result inline. 303 adds a round-trip but makes the browser refresh-safe. Pick 303 when refresh-resubmit is a real risk.

Related status codes

200 201 301 302 307 308

See HTTP 303 in your redirect chains?

Check your URLs with checkredirects.io