Skip to main content

FastAPI Response Examples

When building APIs with FastAPI, providing clear documentation is essential for developers who will consume your API. One powerful feature that enhances documentation is the ability to include example responses. In this guide, we'll explore how to define and use response examples in FastAPI.

Introduction to Response Examples

Response examples show API users what data they can expect to receive from your endpoints. They appear in the auto-generated documentation (Swagger/OpenAPI UI) and help developers understand your API without having to make actual requests.

By providing examples, you can:

  • Improve your API documentation
  • Make it easier for others to integrate with your API
  • Demonstrate different response scenarios
  • Show the structure of complex response objects

Basic Response Examples

Using the example Parameter

The simplest way to provide a response example is by using the example parameter in your Pydantic model:

python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
id: int
name: str
email: str
is_active: bool

class Config:
schema_extra = {
"example": {
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"is_active": True
}
}

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
# Logic to fetch user from database
return {"id": user_id, "name": "John Doe", "email": "[email protected]", "is_active": True}

With this configuration, the Swagger UI documentation will show the example response for the /users/{user_id} endpoint.

Using Field Examples

You can also specify examples for individual fields using the Field function from Pydantic:

python
from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()

class User(BaseModel):
id: int = Field(..., example=123)
name: str = Field(..., example="John Doe")
email: str = Field(..., example="[email protected]")
is_active: bool = Field(..., example=True)

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
# Logic to fetch user from database
return {"id": user_id, "name": "John Doe", "email": "[email protected]", "is_active": True}

Multiple Response Examples

Sometimes you want to show multiple examples for a single endpoint. FastAPI allows you to define multiple examples using the examples parameter (note the plural):

python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
id: int
name: str
email: str
is_active: bool

class Config:
schema_extra = {
"examples": [
{
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"is_active": True,
"summary": "Active user example"
},
{
"id": 456,
"name": "Jane Smith",
"email": "[email protected]",
"is_active": False,
"summary": "Inactive user example"
}
]
}

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
# Logic to fetch user from database
return {"id": user_id, "name": "John Doe", "email": "[email protected]", "is_active": True}

Response Examples with JSON Schema

For more control over examples, you can use the OpenAPI responses parameter directly:

python
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi.responses import JSONResponse

app = FastAPI()

class User(BaseModel):
id: int
name: str
email: str
is_active: bool

@app.get(
"/users/{user_id}",
response_model=User,
responses={
200: {
"description": "Successful response",
"content": {
"application/json": {
"examples": {
"normal_user": {
"summary": "A normal user",
"value": {
"id": 123,
"name": "John Doe",
"email": "[email protected]",
"is_active": True
}
},
"admin_user": {
"summary": "An admin user",
"value": {
"id": 999,
"name": "Admin User",
"email": "[email protected]",
"is_active": True
}
}
}
}
}
},
404: {
"description": "User not found",
"content": {
"application/json": {
"example": {"detail": "User not found"}
}
}
}
}
)
async def get_user(user_id: int):
# Logic to fetch user from database
return {"id": user_id, "name": "John Doe", "email": "[email protected]", "is_active": True}

This approach allows you to define examples for different response status codes and multiple examples per status code.

Real-world Example: Product API

Let's create a more comprehensive example for a product API with different response scenarios:

python
from fastapi import FastAPI, HTTPException, Query
from pydantic import BaseModel, Field
from typing import List, Optional
from enum import Enum

app = FastAPI(title="Product API")

class ProductCategory(str, Enum):
ELECTRONICS = "electronics"
CLOTHING = "clothing"
BOOKS = "books"
HOME = "home"

class ProductResponse(BaseModel):
id: int = Field(..., example=1)
name: str = Field(..., example="Wireless Headphones")
price: float = Field(..., example=99.99)
category: ProductCategory = Field(..., example=ProductCategory.ELECTRONICS)
in_stock: bool = Field(..., example=True)
description: Optional[str] = Field(None, example="Noise-cancelling bluetooth headphones")

class Config:
schema_extra = {
"examples": {
"electronics": {
"summary": "Electronic product example",
"description": "A sample electronic product",
"value": {
"id": 1,
"name": "Wireless Headphones",
"price": 99.99,
"category": "electronics",
"in_stock": True,
"description": "Noise-cancelling bluetooth headphones"
}
},
"clothing": {
"summary": "Clothing product example",
"description": "A sample clothing product",
"value": {
"id": 2,
"name": "Cotton T-Shirt",
"price": 19.99,
"category": "clothing",
"in_stock": True,
"description": "100% organic cotton t-shirt"
}
},
"out_of_stock": {
"summary": "Out of stock product",
"description": "A product that is currently unavailable",
"value": {
"id": 3,
"name": "Bestselling Novel",
"price": 24.99,
"category": "books",
"in_stock": False,
"description": "The latest bestseller from a renowned author"
}
}
}
}

class ProductListResponse(BaseModel):
count: int
products: List[ProductResponse]

class Config:
schema_extra = {
"example": {
"count": 2,
"products": [
{
"id": 1,
"name": "Wireless Headphones",
"price": 99.99,
"category": "electronics",
"in_stock": True,
"description": "Noise-cancelling bluetooth headphones"
},
{
"id": 2,
"name": "Cotton T-Shirt",
"price": 19.99,
"category": "clothing",
"in_stock": True,
"description": "100% organic cotton t-shirt"
}
]
}
}

@app.get(
"/products/{product_id}",
response_model=ProductResponse,
responses={
404: {
"description": "Product not found",
"content": {
"application/json": {
"example": {"detail": "Product with ID 123 not found"}
}
}
}
}
)
async def get_product(product_id: int):
"""
Get detailed information about a specific product by its ID.

- **product_id**: The unique identifier of the product
"""
# In a real app, this would fetch data from a database
if product_id > 1000:
raise HTTPException(status_code=404, detail=f"Product with ID {product_id} not found")

return {
"id": product_id,
"name": "Sample Product",
"price": 29.99,
"category": "electronics",
"in_stock": True,
"description": "This is a sample product"
}

@app.get(
"/products/",
response_model=ProductListResponse
)
async def list_products(
category: Optional[ProductCategory] = None,
min_price: Optional[float] = None,
max_price: Optional[float] = None,
in_stock: Optional[bool] = Query(None, description="Filter by availability")
):
"""
List all products with optional filtering.
"""
# In a real app, this would query a database with filters
products = [
{
"id": 1,
"name": "Wireless Headphones",
"price": 99.99,
"category": "electronics",
"in_stock": True,
"description": "Noise-cancelling bluetooth headphones"
},
{
"id": 2,
"name": "Cotton T-Shirt",
"price": 19.99,
"category": "clothing",
"in_stock": True,
"description": "100% organic cotton t-shirt"
}
]

return {"count": len(products), "products": products}

In this example, we've created a more comprehensive API with:

  • Multiple examples for different product categories
  • Response examples for error cases
  • Structured documentation that clearly shows what users should expect

Response Examples with Different Status Codes

FastAPI allows you to define examples for different HTTP status codes. This is particularly useful for error handling:

python
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
username: str
email: str
full_name: str

class ErrorResponse(BaseModel):
detail: str

@app.get(
"/users/{username}",
response_model=User,
responses={
200: {
"description": "User found",
"content": {
"application/json": {
"example": {
"username": "johndoe",
"email": "[email protected]",
"full_name": "John Doe"
}
}
}
},
404: {
"model": ErrorResponse,
"description": "User not found",
"content": {
"application/json": {
"example": {"detail": "User not found"}
}
}
},
401: {
"model": ErrorResponse,
"description": "Unauthorized access",
"content": {
"application/json": {
"example": {"detail": "Not authenticated"}
}
}
}
}
)
async def get_user(username: str):
if username != "johndoe":
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
return {"username": "johndoe", "email": "[email protected]", "full_name": "John Doe"}

Best Practices for Response Examples

  1. Make examples realistic - Use data that looks like what your API actually returns.
  2. Include examples for error responses - Not just successful ones.
  3. Show different variations - If your endpoint can return different structures, show examples of each.
  4. Keep examples concise - They should be comprehensive but not overwhelming.
  5. Update examples when your API changes - Outdated examples are worse than no examples.
  6. Use meaningful values - Avoid placeholder values like "foo" or "bar" when possible.
  7. Add descriptions to examples - Explain what scenario each example represents.

Summary

Response examples are a powerful way to enhance your FastAPI documentation. They help API consumers understand what to expect from your endpoints without having to make actual requests. By providing examples for different scenarios and status codes, you make your API more accessible and user-friendly.

FastAPI offers multiple ways to define response examples:

  • Using the example parameter for single examples
  • Using Field() for field-level examples
  • Using the examples parameter for multiple examples
  • Using the OpenAPI responses parameter for fine-grained control

With these tools, you can create comprehensive documentation that makes your API easier to understand and use.

Additional Resources

Exercises

  1. Create a FastAPI endpoint that returns a list of blog posts with at least three different example responses.
  2. Implement an API endpoint with multiple possible status codes (200, 400, 401, 404) and add appropriate examples for each.
  3. Build a nested response model (e.g., an order with line items) and provide examples that show different variations of the data.
  4. Practice updating your Swagger documentation with examples and test the "Try it out" functionality to see how examples appear in the documentation.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)