- Home
- HTTP Status Codes
- 308 Permanent Redirect
Status Code
308 Permanent Redirect
Permanent redirect that preserves the HTTP method. Learn when to use 308 instead of 301 for method-sensitive permanent redirects.
What is 308 Permanent Redirect?
TL;DR: 308 Permanent Redirect is like 301 but preserves the HTTP method. Use for API migrations where POST must stay POST.
A 308 Permanent Redirect status code means the resource has permanently moved to a new URL, and clients must use the exact same HTTP method when accessing the new location. Think of it like a business that permanently moved to a new address but kept the same services—you still need to use the same type of request (POST for orders, PUT for updates) at the new location.
This is the method-preserving version of 301 Moved Permanently, ensuring API endpoints maintain their HTTP method semantics after migration.
When Does This Happen?
You’ll see a 308 Permanent Redirect response in these common situations:
1. API Endpoint Migration
Old: POST /v1/api/orders
New: POST /v2/api/orders
Permanent API version upgrade
2. Domain Migration for APIs
Old: PUT /api/users/123 on old-api.com
New: PUT /api/users/123 on new-api.com
Company domain change
3. Service Restructuring
Old: DELETE /admin/posts/456
New: DELETE /cms/posts/456
Permanent service reorganization
4. Protocol Upgrade with Method Preservation
Old: PATCH http://api.example.com/data
New: PATCH https://api.example.com/data
Permanent HTTPS-only policy
5. Microservice Extraction
Old: POST /monolith/payments
New: POST /payments-service/payments
Permanent service separation
Example Responses
API Version Migration:
HTTP/1.1 308 Permanent Redirect
Location: https://api.example.com/v2/orders
Cache-Control: max-age=31536000
Content-Type: text/html
<!DOCTYPE html>
<html>
<body>
<h1>API Endpoint Moved Permanently</h1>
<p>This endpoint has permanently moved to our v2 API.</p>
<p>Please update your code to use: <code>https://api.example.com/v2/orders</code></p>
</body>
</html>
```text
**Domain Migration:**
```http
HTTP/1.1 308 Permanent Redirect
Location: https://new-domain.com/api/users/123
Cache-Control: max-age=31536000
X-Migration-Notice: Please update your API base URL
<html><body>API has permanently moved to new-domain.com</body></html>
Service Extraction:
HTTP/1.1 308 Permanent Redirect
Location: https://payments.example.com/process
Cache-Control: max-age=31536000
X-Service-Migration: payments-microservice
<html><body>Payment processing moved to dedicated service</body></html>
```text
## Real-World Example
Imagine you're migrating an e-commerce API from v1 to v2 and need to preserve HTTP methods:
**Original API Request:**
```http
PUT /v1/api/products/12345 HTTP/1.1
Host: shop.example.com
Content-Type: application/json
Authorization: Bearer token123
{
"name": "Updated Product Name",
"price": 29.99,
"inventory": 150
}
308 Redirect Response:
HTTP/1.1 308 Permanent Redirect
Location: https://shop.example.com/v2/api/products/12345
Cache-Control: max-age=31536000
X-API-Migration: v1-to-v2
Content-Type: text/html
<!DOCTYPE html>
<html>
<head><title>API Migrated</title></head>
<body>
<h1>API Endpoint Permanently Moved</h1>
<p>Our v1 API has been permanently migrated to v2.</p>
<p>New endpoint: <code>https://shop.example.com/v2/api/products/12345</code></p>
<p>All HTTP methods and functionality remain the same.</p>
</body>
</html>
```text
**Client Follows Redirect (Same Method):**
```http
PUT /v2/api/products/12345 HTTP/1.1
Host: shop.example.com
Content-Type: application/json
Authorization: Bearer token123
{
"name": "Updated Product Name",
"price": 29.99,
"inventory": 150
}
308 vs Other Redirect Codes
| Code | Method Preservation | Duration | SEO Impact | Use Case |
|---|---|---|---|---|
| 308 | ✅ Guaranteed | Permanent | Transfers ranking | API migrations, method-critical redirects |
| 301 | ❓ Maybe (browser dependent) | Permanent | Transfers ranking | General permanent redirects |
| 307 | ✅ Guaranteed | Temporary | No transfer | Temporary method-preserving redirects |
| 302 | ❓ Maybe | Temporary | No transfer | General temporary redirects |
SEO and API Benefits
Search Engine Behavior:
- Transfers PageRank from old URL to new URL
- Preserves API endpoint rankings in developer searches
- Updates search results to show new URLs
API Client Benefits:
- Existing code continues to work without modification
- HTTP methods remain semantically correct
- Gradual migration without breaking changes
Common Mistakes
❌ Using 301 for API endpoints
PUT /v1/api/users/123
HTTP/1.1 301 Moved Permanently ← Might become GET
Location: /v2/api/users/123 ← Should use 308
```text
**❌ Using 308 when method can change**
```http
GET /old-page → should become different content type
HTTP/1.1 308 Permanent Redirect ← 301 would be fine
❌ Short cache times for permanent redirects
HTTP/1.1 308 Permanent Redirect
Cache-Control: max-age=300 ← Too short for permanent redirect
```text
**✅ Correct usage**
```http
POST /v1/api/orders
HTTP/1.1 308 Permanent Redirect
Location: https://api.example.com/v2/orders
Cache-Control: max-age=31536000
Best Practices
Use Long Cache Times:
HTTP/1.1 308 Permanent Redirect
Location: /new-permanent-endpoint
Cache-Control: max-age=31536000 ← 1 year
```http
**Provide Migration Information:**
```http
HTTP/1.1 308 Permanent Redirect
Location: /v2/api/endpoint
X-Migration-Guide: https://docs.example.com/v1-to-v2-migration
X-Deprecation-Date: 2026-06-01
Use Absolute URLs:
HTTP/1.1 308 Permanent Redirect
Location: https://new-api.example.com/endpoint ✓
Location: /endpoint ✗ (relative URLs discouraged)
```javascript
## Implementation Examples
**Express.js API Migration:**
```javascript
// Redirect all v1 API calls to v2
app.use('/v1/api/*', (req, res) => {
const newPath = req.path.replace('/v1/api', '/v2/api')
const newUrl = `https://api.example.com${newPath}`
res.redirect(308, newUrl)
})
Nginx Configuration:
# Permanent redirect preserving method
location /old-api/ {
return 308 https://new-api.example.com$request_uri;
}
```javascript
**Python Flask:**
```python
from flask import redirect, request
@app.route('/v1/api/<path:endpoint>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def redirect_v1_api(endpoint):
new_url = f'https://api.example.com/v2/api/{endpoint}'
return redirect(new_url, code=308)
Migration Strategy
Phase 1: Implement 308 Redirects
PUT /v1/users/123 → 308 → PUT /v2/users/123
```text
**Phase 2: Update Documentation**
```markdown
# API Migration Notice
v1 endpoints now redirect to v2
Update your base URL to avoid redirects
Phase 3: Monitor and Deprecate
HTTP/1.1 308 Permanent Redirect
X-Deprecation-Warning: v1 API will be removed on 2026-12-01
Browser and Client Behavior
Automatic Method Preservation:
- All modern HTTP clients preserve the method
- Request body is resent exactly as originally sent
- Authentication headers are maintained
Caching Behavior:
- Browsers cache 308 redirects aggressively
- Subsequent requests go directly to new URL
- Reduces server load from redirect processing
Try It Yourself
Visit our request builder and test permanent method preservation:
- Set method to PUT
- Set path to /v1/demo-endpoint
- Add JSON body with update data
- Click Send request
- Watch the 308 redirect preserve the PUT method
Related Status Codes
- 301 Moved Permanently - Permanent redirect (method may change)
- 307 Temporary Redirect - Temporary redirect preserving method
- 302 Found - Temporary redirect (method may change)
- 410 Gone - Resource permanently removed (no redirect)
Frequently Asked Questions
What does 308 Permanent Redirect mean?
308 means the resource has permanently moved to a new URL and the client must use the same HTTP method when accessing the new location. It is the method-preserving version of 301.
What is the difference between 308 and 301?
308 guarantees the HTTP method is preserved (POST stays POST). 301 may change POST to GET in some browsers. Use 308 for API migrations where method preservation is critical.
When should I use 308 vs 307?
Use 308 for permanent redirects where the method must be preserved. Use 307 for temporary redirects. Both preserve the HTTP method, but 308 can be cached long-term.
Does 308 transfer SEO value like 301?
Yes, 308 transfers PageRank and SEO value to the new URL just like 301. Search engines treat both as permanent redirects for ranking purposes.