> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/fastapi/fastapi/llms.txt
> Use this file to discover all available pages before exploring further.

# Response Status Code

> Learn how to set HTTP status codes in FastAPI using the status_code parameter and status module

HTTP status codes communicate the result of a request. FastAPI makes it easy to set appropriate status codes for your API responses.

## Setting Status Code

Use the `status_code` parameter in your path operation decorator:

```python theme={null}
from fastapi import FastAPI

app = FastAPI()

@app.post("/items/", status_code=201)
async def create_item(name: str):
    return {"name": name}
```

<Info>
  The `status_code` parameter:

  * Sets the HTTP status code in the response
  * Documents it in the OpenAPI schema
  * Validates that it's a valid HTTP status code
</Info>

## Using the status Module

Instead of memorizing numeric codes, use FastAPI's `status` module:

```python theme={null}
from fastapi import FastAPI, status

app = FastAPI()

@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
    return {"name": name}

@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
    return None

@app.get("/items/", status_code=status.HTTP_200_OK)
async def read_items():
    return [{"name": "Foo"}, {"name": "Bar"}]
```

<Tip>
  Using `status.HTTP_*` constants makes your code more readable and helps avoid typos.
</Tip>

## Common Status Codes

### Success Codes (2xx)

<CodeGroup>
  ```python 200 OK (Default) theme={null}
  @app.get("/items/", status_code=status.HTTP_200_OK)
  async def read_items():
      return [{"name": "Foo"}]
  # Default for GET, no need to specify
  ```

  ```python 201 Created theme={null}
  @app.post("/items/", status_code=status.HTTP_201_CREATED)
  async def create_item(name: str):
      return {"name": name}
  # Use for resource creation
  ```

  ```python 204 No Content theme={null}
  @app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
  async def delete_item(item_id: int):
      return None
  # No response body expected
  ```

  ```python 202 Accepted theme={null}
  @app.post("/tasks/", status_code=status.HTTP_202_ACCEPTED)
  async def create_task(task: str):
      # Task queued for processing
      return {"message": "Task accepted"}
  ```
</CodeGroup>

### Redirection Codes (3xx)

```python theme={null}
from fastapi import FastAPI, status
from fastapi.responses import RedirectResponse

app = FastAPI()

@app.get("/old-path", status_code=status.HTTP_301_MOVED_PERMANENTLY)
async def redirect_old_path():
    return RedirectResponse(url="/new-path")

@app.get("/temporary", status_code=status.HTTP_307_TEMPORARY_REDIRECT)
async def temporary_redirect():
    return RedirectResponse(url="/other-path")
```

### Client Error Codes (4xx)

```python theme={null}
from fastapi import FastAPI, HTTPException, status

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    if item_id not in items_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Item not found"
        )
    return items_db[item_id]

@app.post("/items/")
async def create_item(item: Item):
    if item.price < 0:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Price cannot be negative"
        )
    return item
```

### Server Error Codes (5xx)

```python theme={null}
from fastapi import FastAPI, HTTPException, status

app = FastAPI()

@app.get("/items/")
async def read_items():
    try:
        # Some database operation
        items = get_items_from_db()
        return items
    except DatabaseError:
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail="Database temporarily unavailable"
        )
```

## Status Code Reference

### 2xx Success

<Steps>
  <Step title="200 OK">
    Default success response (GET, PUT, PATCH)
  </Step>

  <Step title="201 Created">
    Resource successfully created (POST)
  </Step>

  <Step title="202 Accepted">
    Request accepted but processing not complete
  </Step>

  <Step title="204 No Content">
    Success with no response body (DELETE)
  </Step>
</Steps>

### 3xx Redirection

* **301 Moved Permanently**: Resource permanently moved
* **302 Found**: Temporary redirect (legacy)
* **307 Temporary Redirect**: Temporary redirect (preserves method)
* **308 Permanent Redirect**: Permanent redirect (preserves method)

### 4xx Client Errors

* **400 Bad Request**: Invalid request data
* **401 Unauthorized**: Authentication required
* **403 Forbidden**: Authenticated but not authorized
* **404 Not Found**: Resource doesn't exist
* **422 Unprocessable Entity**: Validation error
* **429 Too Many Requests**: Rate limit exceeded

### 5xx Server Errors

* **500 Internal Server Error**: Unexpected server error
* **502 Bad Gateway**: Invalid upstream response
* **503 Service Unavailable**: Service temporarily down
* **504 Gateway Timeout**: Upstream timeout

## Dynamic Status Codes

Change status codes dynamically using `Response`:

```python theme={null}
from fastapi import FastAPI, Response, status

app = FastAPI()

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, response: Response):
    if item_id in items_db:
        # Update existing item
        items_db[item_id] = item
        response.status_code = status.HTTP_200_OK
        return item
    else:
        # Create new item
        items_db[item_id] = item
        response.status_code = status.HTTP_201_CREATED
        return item
```

<Note>
  When using `Response` to set status codes dynamically, the code set in the decorator becomes the default shown in docs.
</Note>

## Status Codes with HTTPException

Raise exceptions with specific status codes:

```python theme={null}
from fastapi import FastAPI, HTTPException, status

app = FastAPI()

items_db = {"foo": "The Foo Item"}

@app.get("/items/{item_id}")
async def read_item(item_id: str):
    if item_id not in items_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item {item_id} not found",
            headers={"X-Error": "Item not found"},
        )
    return {"item": items_db[item_id]}

@app.post("/items/")
async def create_item(item: Item):
    if item.id in items_db:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Item {item.id} already exists"
        )
    items_db[item.id] = item
    return item
```

## Best Practices

<CodeGroup>
  ```python Good: Semantic Status Codes theme={null}
  @app.post("/items/", status_code=status.HTTP_201_CREATED)
  async def create_item(item: Item):
      return item

  @app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
  async def delete_item(item_id: int):
      return None
  ```

  ```python Bad: Wrong Status Codes theme={null}
  @app.post("/items/", status_code=200)  # Should be 201
  async def create_item(item: Item):
      return item

  @app.delete("/items/{item_id}")  # Should specify 204
  async def delete_item(item_id: int):
      return {"deleted": True}  # Should return None
  ```
</CodeGroup>

<Warning>
  Always use appropriate status codes:

  * **POST** for creation → 201 Created
  * **DELETE** with no body → 204 No Content
  * **GET/PUT** success → 200 OK
  * **Errors** → Appropriate 4xx or 5xx code
</Warning>

## Status Code Guidelines

| Method | Success Code | Typical Use          |
| ------ | ------------ | -------------------- |
| GET    | 200          | Resource retrieval   |
| POST   | 201          | Resource creation    |
| PUT    | 200          | Full update          |
| PATCH  | 200          | Partial update       |
| DELETE | 204          | Deletion (no body)   |
| DELETE | 200          | Deletion (with body) |

## Testing Status Codes

```python theme={null}
from fastapi.testclient import TestClient
from fastapi import status

def test_create_item():
    response = client.post("/items/", json={"name": "Foo"})
    assert response.status_code == status.HTTP_201_CREATED

def test_item_not_found():
    response = client.get("/items/999")
    assert response.status_code == status.HTTP_404_NOT_FOUND

def test_delete_item():
    response = client.delete("/items/1")
    assert response.status_code == status.HTTP_204_NO_CONTENT
```

## Related Topics

* [Response Model](/tutorial/response-model) - Define response schemas
* [Extra Models](/tutorial/extra-models) - Work with multiple models
* [Request Body](/tutorial/request-body) - Handle request data
