# 308 Permanent Redirect

> https://http-status.org/docs/308

**Family:** 3xx Redirection

## Rationale

Permanent redirect that preserves the original request method and body.

## In Plain Terms

This moved for good, and you should keep using the same kind of request when you switch to the new address.

## Description

The HTTP 308 Permanent Redirect status code indicates that the target resource now has a permanent new URI and that automatic redirects must preserve the original request method and body. It exists to provide the long-term redirect behavior of 301 without the historical method-rewrite ambiguity.

## Server Perspective

### Usage
- Return 308 for durable API or route migrations where non-GET requests must keep their semantics
- Prefer 308 over 301 when clients should permanently update their target URI without method ambiguity
- Permanent endpoint migrations where POST, PUT, PATCH, or DELETE semantics must be preserved
- Long-term API version or hostname changes that should keep the same request method
- Permanent route cleanup where non-GET clients should update to a new URI

### Implementation
- Include a Location header with the new permanent URI
- Keep the new target stable enough that clients can safely update stored endpoints

### Common Headers
- Location
- Cache-Control

### Body
- A body is optional, but the permanent target must be clear from Location

### Pitfalls
- Do not use 308 for temporary rerouting
- Do not choose 301 if preserving non-GET methods is part of the contract
- Temporary redirects; use 307
- Cases where method preservation is irrelevant and a simple 301 is sufficient
- Flows where the next step should be an indirect GET or HEAD retrieval; use 303

## Client Perspective

### Pitfalls
- Do not downgrade 308 handling to 301-style method rewriting

## Examples

### Permanent API migration

The client should update the endpoint and resend the same PUT to the new permanent URI.

**Request:**
```
PUT https://api.example.test/api/v1/users/123
```

**Response:**
```
308 Permanent Redirect
Location: https://api.example.test/api/v2/users/123
```

### Permanent webhook path change

The sender should keep POST semantics while moving permanently to the new route.

**Request:**
```
POST https://api.example.test/hooks/incoming
```

**Response:**
```
308 Permanent Redirect
Location: https://api.example.test/webhooks/incoming
```

## Related Codes

- [301 Moved Permanently](/docs/301.md)
- [307 Temporary Redirect](/docs/307.md)

