301 vs 302 vs 307/308: Choosing the Right Redirect
The difference between redirect status codes and how to pick the right one for SEO and method preservation.
A redirect is an HTTP response that tells browsers and search engines "this address has moved somewhere else." Every redirect status starts with 3xx and carries the new location in the Location header. They all look like "send the visitor elsewhere," but each code differs in three ways: (1) whether the move is permanent or temporary, (2) whether the original request method is preserved, and (3) whether the browser is allowed to cache it. Pick the wrong one and your SEO ranking signals may never reach the new URL, or a POST form submission silently turns into a GET and the data disappears.
This guide compares the five redirect codes (301, 302, 303, 307, 308) in a table, then covers 301 vs 302 for SEO, the method-preserving 307/308, and the most common mistake of all: using 302 for a permanent move. To see which code your server actually returns, run a request through the HTTP status code checker.
The five redirect codes at a glance
The key is the combination of "method preserved" and "permanent vs temporary." In the table below, codes marked No under "Method kept" may downgrade a non-GET request (typically POST) into a GET.
| Code | Meaning | Method kept | Cacheable by default | Main use (SEO) |
|---|---|---|---|---|
301 | Moved permanently | No (may become GET) | Yes | Permanent domain/URL change, passes ranking |
302 | Found (temporary) | No (may become GET) | No | Maintenance, A/B, temporary move (keep original) |
303 | See Other | No (always GET) | No | Result page after a POST (PRG pattern) |
307 | Temporary redirect | Yes (method & body kept) | No | Temporary move that must keep a POST |
308 | Permanent redirect | Yes (method & body kept) | Yes | Permanent move that must keep API/POST |
301 vs 302: what changes for SEO
This is the pair people confuse most. Both "send the visitor elsewhere," yet search engines interpret them in opposite ways.
- 301 (permanent): "This URL has moved for good." Search engines update the index to the new URL and forward the link equity and ranking signals the old page accumulated. Use 301 for domain changes,
http→https, consolidatingwww, and retiring old article URLs. - 302 (temporary): "The original still exists; I'm just diverting traffic for now." Search engines try to keep the original URL in the index. Good for maintenance pages, short-lived geo/language detours, and brief campaign landing pages.
The practical rule is simple: use 301/308 if you have no plans to revert, and 302/307 if you'll switch back soon. After moving, verify the status code and Location header come out as intended with the HTTP header checker.
Why 307 and 308 exist: method preservation
Historically many browsers, on receiving a 301 or 302, would rewrite a POST into a GET and drop the request body. A form or API call that hit a redirect would lose its data. 307 and 308 were introduced to remove that ambiguity.
- 307 = the method-preserving version of 302 (temporary). A
POSTstays aPOST, and the body is re-sent to the new URL unchanged. - 308 = the method-preserving version of 301 (permanent). Permanent move while keeping method and body. Especially safe for permanently relocating API endpoints.
- 303 does the opposite: it explicitly says "always switch to
GET." It powers the PRG (Post/Redirect/Get) pattern, where you process aPOSTand then show the result page overGETso a refresh doesn't resubmit.
Common mistakes and how to inspect them
- Using 302 for a permanent move: the classic blunder. Search engines keep indexing the old URL and don't pass ranking signals to the new one, so traffic stalls. For a permanent move, always use 301 (or 308).
- Redirect chains and loops: hopping through
A → B → Cdilutes signals and slows the page. PointingA → Aat itself creates an infinite loop. Always send users to the final destination in a single hop. - Method loss on http→https: if an API
POSTs to a plainhttpendpoint and you 301 it to https, some clients drop the body. Use 308 to stay safe.
To trace a chain, follow it one hop at a time, checking each response's code and Location. Use the HTTP status code checker for the final code and the HTTP header checker for the Location and cache headers, and any broken intent shows up immediately.
Worked example: a POST that breaks under 302 but survives 308
Say a payment API at //pay.example.com/charge has moved to //api.example.com/v2/charge. The client sends a POST with a body containing card details.
Moved with 302 (breaks):
- Client:
POST /charge+ body (card/amount) - Server:
302 Found,Location: //api.example.com/v2/charge - Client (many implementations): rewrites the method to
GETand drops the body →GET /v2/charge - New endpoint: receives a body-less
GET→400 Bad Requestor an empty charge. Data lost.
Moved with 308 (preserved):
- Client:
POST /charge+ body (card/amount) - Server:
308 Permanent Redirect,Location: //api.example.com/v2/charge - Client: keeps the method and body →
POST /v2/charge+ the same body - New endpoint: processes the charge normally →
200 OK. Data preserved.
The takeaway: for permanent moves of endpoints that accept non-GET requests use 308 (not 301), and for temporary detours use 307 (not 302). After deploying, confirm the live response really returns 308/307 with the HTTP status code checker.