HTTP

Status Code

307 Temporary Redirect

Temporary redirect that preserves the HTTP method. Learn when to use 307 instead of 302 for method-sensitive redirects.

4 min read intermediate Try in Playground

TL;DR: 307 Temporary Redirect preserves your HTTP method. Unlike 302, POST stays POST when following this redirect.

A 307 Temporary Redirect status code means the resource is temporarily available at a different URL, and the client must use the exact same HTTP method when following the redirect. Think of it like a detour sign that says “road temporarily closed, take this exact route instead”—you can’t change your mode of transportation, just the path you take.

This is the method-preserving version of 302 Found, ensuring POST stays POST, PUT stays PUT, etc.

When Does This Happen?

You’ll see a 307 Temporary Redirect response in these common situations:

1. Server Maintenance with Form Preservation

POST /api/orders → POST /backup-server/api/orders
Form submission redirected without losing data

2. Load Balancing for API Calls

PUT /api/users/123 → PUT /server2.api.com/users/123
Preserving the update operation method

3. Temporary API Endpoint Changes

DELETE /v1/posts/456 → DELETE /v1-temp/posts/456
Maintaining the delete operation during migration

4. Geographic Routing

POST /upload → POST /us-east.example.com/upload
Redirecting file uploads to regional server

5. A/B Testing with Method Preservation

PATCH /settings → PATCH /settings-beta
Testing new endpoint while preserving update method

Example Responses

Form Submission Redirect:

HTTP/1.1 307 Temporary Redirect
Location: https://backup.example.com/api/submit
Cache-Control: no-cache
Retry-After: 300

<!DOCTYPE html>
<html>
<body>
<h1>Temporarily Redirected</h1>
<p>Your request is being redirected to a backup server.</p>
<p>Please wait while we redirect your form submission...</p>
</body>
</html>
```text

**API Load Balancing:**

```http
HTTP/1.1 307 Temporary Redirect
Location: https://api-2.example.com/users/123
Cache-Control: no-store
X-Redirect-Reason: load-balancing

<html><body>Redirecting to available server...</body></html>

File Upload Redirect:

HTTP/1.1 307 Temporary Redirect
Location: https://upload-server-2.example.com/files
Cache-Control: no-cache
Content-Type: text/html

<html><body>Redirecting upload to available server...</body></html>
```text

## Real-World Example

Imagine you're running a file upload service and need to redirect large uploads to a specialized server:

**Original Upload Request:**

```http
POST /upload HTTP/1.1
Host: app.example.com
Content-Type: multipart/form-data
Content-Length: 52428800

[large file data...]

307 Redirect Response:

HTTP/1.1 307 Temporary Redirect
Location: https://upload-server.example.com/upload
Cache-Control: no-cache, no-store
X-Upload-Server: us-east-1
Content-Type: text/html

<!DOCTYPE html>
<html>
<head><title>Upload Redirect</title></head>
<body>
<h1>Redirecting Upload</h1>
<p>Your file upload is being redirected to our specialized upload server.</p>
<p>This ensures optimal upload performance and reliability.</p>
</body>
</html>
```text

**Client Follows Redirect (Same Method):**

```http
POST /upload HTTP/1.1
Host: upload-server.example.com
Content-Type: multipart/form-data
Content-Length: 52428800

[same large file data...]

307 vs Other Redirect Codes

CodeMethod PreservationDurationUse Case
307✅ GuaranteedTemporaryWhen method must stay the same
302❓ Maybe (browser dependent)TemporaryGeneral temporary redirects
303❌ Always becomes GETOne-timeAfter POST to prevent resubmission
308✅ GuaranteedPermanentPermanent redirect keeping method

Method Preservation Examples

POST Request Preservation:

POST /api/create-user
→ 307 Temporary Redirect
→ POST /backup-api/create-user  ← Still POST
```text

**PUT Request Preservation:**

```http
PUT /api/users/123
→ 307 Temporary Redirect
→ PUT /api-v2/users/123  ← Still PUT

DELETE Request Preservation:

DELETE /posts/456
→ 307 Temporary Redirect
→ DELETE /archive-api/posts/456  ← Still DELETE
```text

## Common Mistakes

**❌ Using 307 when method can change**

```http
GET /page → should redirect to different content
HTTP/1.1 307 Temporary Redirect  ← 302 would be fine here

❌ Using 302 when method must be preserved

POST /api/orders → needs to stay POST
HTTP/1.1 302 Found  ← Might become GET in old browsers
Location: /backup-api/orders  ← Should use 307
```text

**❌ Caching 307 redirects**

```http
HTTP/1.1 307 Temporary Redirect
Cache-Control: max-age=3600  ← Don't cache temporary redirects

✅ Correct usage

POST /api/submit
HTTP/1.1 307 Temporary Redirect
Location: https://backup.example.com/api/submit
Cache-Control: no-cache
```text

## Best Practices

**Don't Cache Temporary Redirects:**

```http
HTTP/1.1 307 Temporary Redirect
Location: /temporary-endpoint
Cache-Control: no-cache, no-store

Provide Clear Redirect Reason:

HTTP/1.1 307 Temporary Redirect
Location: /backup-server/endpoint
X-Redirect-Reason: primary-server-maintenance
Retry-After: 1800
```text

**Use Absolute URLs:**

```http
HTTP/1.1 307 Temporary Redirect
Location: https://backup.example.com/api/endpoint  ✓
Location: /api/endpoint  ✗ (relative URLs discouraged)

Implementation Examples

Express.js:

app.post('/api/upload', (req, res) => {
  if (serverOverloaded()) {
    return res.redirect(307, 'https://backup-server.com/api/upload')
  }
  // Handle upload normally
})
```nginx

**Nginx Load Balancing:**

```nginx
upstream backend {
    server backend1.example.com;
    server backend2.example.com backup;
}

location /api/ {
    proxy_pass http://backend;
    proxy_next_upstream error timeout;
    # Nginx handles 307 redirects automatically for failed upstreams
}

Python Flask:

from flask import redirect, request

@app.route('/api/process', methods=['POST', 'PUT', 'DELETE'])
def process_request():
    if maintenance_mode:
        return redirect('/backup-api/process', code=307)
    # Handle request normally

Browser Behavior

Automatic Method Preservation:

  • Modern browsers always preserve the method with 307
  • Request body is resent exactly as originally sent
  • No user confirmation required (unlike some 302 cases)

Security Considerations:

  • Sensitive data in request body will be resent
  • Ensure redirect destination is trusted
  • Consider authentication implications

Try It Yourself

Visit our request builder and test method preservation:

  1. Set method to POST
  2. Set path to /temp-redirect-demo
  3. Add request body with JSON data
  4. Click Send request
  5. Watch the 307 redirect preserve the POST method

Frequently Asked Questions

What does 307 Temporary Redirect mean?

307 means the resource is temporarily at a different URL and the client must use the same HTTP method when following the redirect. Unlike 302, it guarantees POST stays POST and PUT stays PUT.

What is the difference between 307 and 302?

307 guarantees the HTTP method is preserved during redirect. 302 behavior varies by browser and may change POST to GET. Use 307 when method preservation is critical.

When should I use 307 vs 303?

Use 307 when you need to preserve the HTTP method (POST stays POST). Use 303 when you want the redirect to become GET, like after form submission to prevent resubmission.

Should I cache 307 redirects?

No, 307 is temporary so it should not be cached. Use Cache-Control: no-cache, no-store. For permanent method-preserving redirects, use 308 instead.

Keep Learning