303 See Other
3xx redirection
Fetch the result from another URL with GET — the standard answer after a form POST.
303 tells the client to fetch a different URL using GET, whatever the original method was. Its classic job is Post/Redirect/Get: after a form submission the server answers 303 pointing at a confirmation page, so refreshing reloads the confirmation instead of resubmitting the form.
| Class | 3xx Redirection |
|---|---|
| Retry? | Not applicable |
| Cacheable by default | No — only with explicit Cache-Control |
| Response body | Allowed |
| Defined in | RFC 9110 §15.4.4 — 303 See Other |
Example response
HTTP/1.1 303 See Other Location: /orders/1042
When you'll see it
- Form submissions following the Post/Redirect/Get pattern.
- Next.js
redirect()inside a Server Action responds with 303. - Async APIs pointing a finished job's status URL at its result.
How to use it well
- Use 303 rather than 302 after a POST when you want GET semantics explicitly.
- For job polling, return 303 with
Locationpointing at the finished resource.
Send a 303 from your server
Express
res.redirect(303, "/orders/1042");
Next.js route handler
return NextResponse.redirect(new URL("/orders/1042", request.url), 303);Flask
return redirect("/orders/1042", code=303)Go net/http
http.Redirect(w, r, "/orders/1042", http.StatusSeeOther)
nginx
return 303 /orders/1042;
Check what a URL returns
Print just the status line from the command line, or check a whole list of URLs at once, with their response headers, in the HTTP Status Checker.
curl -sI https://example.com/your-path | head -n 1
Frequently asked questions
Why use 303 instead of 302 after a POST?
Browsers already change POST to GET on a 302, but that's legacy behaviour. 303 states the intent in the spec, so every client — API libraries included — does the right thing.
Headers used with 303
Related status codes