308 Permanent Redirect
A permanent redirect that preserves the request method and body. This is 301 without the historical POST to GET rewrite.
At a glance
- Status code
- 308 Permanent Redirect
- Class
- 3xx, redirection, further action is needed to complete the request
- Defined in
- RFC 7538
- Cacheable by default
- yes
- Response body
- Optional.
In detail
308 makes the same permanent statement as 301 and adds the method guarantee of 307. For a permanent move of an API endpoint it is the only correct choice.
Use 308 for permanent moves where non-GET requests matter. 301 remains fine for pages that are only ever fetched with GET, and has broader support in very old clients.
Check the client. Some legacy HTTP libraries do not follow 308 at all, and will surface it as an unhandled status rather than following Location.
Examples
HTTP/1.1 308 Permanent Redirect
Location: https://api.example.com/v2/ordersThings that catch people out
- 308 is cached as aggressively as 301. Deploying one by mistake is expensive to undo.
- Search engines treat 301 and 308 equivalently for ranking, so there is no SEO reason to prefer one over the other. Choose on method preservation.
Try it: HTTP Request Builder
Build a request with any method, headers and body, send it, and read the status line the server returns.
HTTP Request Builder
LOCAL · Browser-OnlyBuild and test HTTP requests with custom headers and body
Authentication
Headers
Generate Code
curl -X GET 'https://api.example.com/endpoint' \
-H 'Content-Type: application/json'Showing a sample URL. Enter your endpoint above to update the snippet.
Related HTTP status codes
All http status codes →301 Moved Permanently
The resource has a new permanent URL, given in Location. Search engines transfer ranking signals to the target and clients may cache the redirect.
307 Temporary Redirect
Same as 302 but with a guarantee: the client must repeat the request with the original method and body, so a POST stays a POST.
302 Found
The resource is temporarily at a different URL. The original URL stays authoritative and should keep being used for future requests.
400 Bad Request
The server refused the request because it was malformed. The client must change something before retrying, because repeating the same bytes will fail.
401 Unauthorized
The request lacks valid credentials. Despite the name, this is about authentication (who you are), not authorisation (what you may do).
402 Payment Required
Reserved for future use in the original specification, and now used in practice by APIs to signal that a plan limit or unpaid invoice is blocking the request.
Tools for this
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL