> ## 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.

# Additional Status Codes

> Learn how to return additional status codes and document multiple possible responses in FastAPI

## Overview

Your API endpoints often need to return different HTTP status codes based on different scenarios. FastAPI makes it easy to handle multiple status codes and document them in your OpenAPI schema.

## The Responses Parameter

Use the `responses` parameter to document additional status codes that your endpoint might return:

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

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

class Message(BaseModel):
    message: str

@app.get(
    "/items/{item_id}",
    responses={
        404: {"model": Message, "description": "Item not found"},
        200: {"model": Item, "description": "Successful response"},
    }
)
async def read_item(item_id: str):
    if item_id not in items:
        return JSONResponse(
            status_code=404,
            content={"message": "Item not found"}
        )
    return items[item_id]
```

<Info>
  The `responses` parameter is primarily for OpenAPI documentation. It tells consumers of your API what responses to expect.
</Info>

## Returning Different Status Codes

There are several ways to return different status codes in FastAPI:

### Using JSONResponse

Return a `JSONResponse` object with a specific status code:

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

app = FastAPI()

items = {
    "foo": {"name": "Fighters", "size": 6},
    "bar": {"name": "Tenders", "size": 3}
}

@app.put("/items/{item_id}")
async def upsert_item(
    item_id: str,
    name: str | None = Body(default=None),
    size: int | None = Body(default=None),
):
    if item_id in items:
        item = items[item_id]
        item["name"] = name
        item["size"] = size
        return item
    else:
        item = {"name": name, "size": size}
        items[item_id] = item
        return JSONResponse(
            status_code=status.HTTP_201_CREATED,
            content=item
        )
```

### Using Response Parameter

Inject a `Response` parameter and modify its status code:

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

app = FastAPI()

tasks = {"foo": "Listen to the Bar Fighters"}

@app.put("/get-or-create-task/{task_id}", status_code=200)
def get_or_create_task(task_id: str, response: Response):
    if task_id not in tasks:
        tasks[task_id] = "This didn't exist before"
        response.status_code = status.HTTP_201_CREATED
    return tasks[task_id]
```

<Note>
  This approach is cleaner when you want to return the same data structure but with different status codes.
</Note>

## Common Status Codes

FastAPI provides common status codes through the `status` module:

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

# Success codes
status.HTTP_200_OK
status.HTTP_201_CREATED
status.HTTP_204_NO_CONTENT

# Client error codes
status.HTTP_400_BAD_REQUEST
status.HTTP_401_UNAUTHORIZED
status.HTTP_403_FORBIDDEN
status.HTTP_404_NOT_FOUND
status.HTTP_409_CONFLICT
status.HTTP_422_UNPROCESSABLE_ENTITY

# Server error codes
status.HTTP_500_INTERNAL_SERVER_ERROR
status.HTTP_503_SERVICE_UNAVAILABLE
```

<Tip>
  Using `status.HTTP_*` constants makes your code more readable and less error-prone than using numeric codes.
</Tip>

## Documenting Multiple Responses

Provide comprehensive documentation for all possible responses:

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

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

class ErrorMessage(BaseModel):
    detail: str

@app.get(
    "/items/{item_id}",
    responses={
        200: {
            "model": Item,
            "description": "Successful Response",
            "content": {
                "application/json": {
                    "example": {"name": "Foo", "price": 35.4}
                }
            },
        },
        404: {
            "model": ErrorMessage,
            "description": "Item not found",
            "content": {
                "application/json": {
                    "example": {"detail": "Item not found"}
                }
            },
        },
        400: {
            "model": ErrorMessage,
            "description": "Bad Request",
        },
    },
)
async def read_item(item_id: str):
    if item_id not in items:
        raise HTTPException(status_code=404, detail="Item not found")
    return items[item_id]
```

## Response Models with Different Status Codes

Define different response models for different status codes:

```python theme={null}
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class SuccessResponse(BaseModel):
    status: str
    data: dict

class ErrorResponse(BaseModel):
    status: str
    error: str

@app.get(
    "/items/{item_id}",
    responses={
        200: {"model": SuccessResponse},
        404: {"model": ErrorResponse},
    },
)
async def read_item(item_id: str) -> Union[SuccessResponse, ErrorResponse]:
    if item_id in items:
        return SuccessResponse(
            status="success",
            data=items[item_id]
        )
    return JSONResponse(
        status_code=404,
        content=ErrorResponse(
            status="error",
            error="Item not found"
        ).dict()
    )
```

<Warning>
  When using the `responses` parameter, make sure your actual endpoint code can return all documented status codes. The documentation won't automatically validate this.
</Warning>

## Combining with HTTPException

Use `HTTPException` for error responses while documenting them:

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

app = FastAPI()

class Item(BaseModel):
    name: str

@app.get(
    "/items/{item_id}",
    responses={
        404: {"description": "Item not found"},
        500: {"description": "Internal server error"},
    },
)
async def read_item(item_id: str):
    if item_id == "error":
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Something went wrong"
        )
    if item_id not in items:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Item not found"
        )
    return items[item_id]
```

## Best Practices

1. **Document all status codes**: Include all possible status codes your endpoint might return in the `responses` parameter
2. **Use meaningful descriptions**: Provide clear descriptions for each status code
3. **Include examples**: Add example responses to help API consumers understand the structure
4. **Be consistent**: Use the same error response format across your API
5. **Use status constants**: Prefer `status.HTTP_*` over numeric codes for better readability
