OpenAPI and API Documentation

Introduction

FastAPI builds OpenAPI 3 metadata from your routes, type hints, and Pydantic models. Swagger UI and ReDoc ship for free—clients and frontend teams read the same spec. This chapter customizes docs, tags, responses, and production exposure policies.

Prerequisites

Default Documentation URLs

URLUI
/docsSwagger UI (interactive)
/redocReDoc (readable reference)
/openapi.jsonRaw OpenAPI schema

Available as soon as you create FastAPI() and add routes.

App Metadata

python
from fastapi import FastAPI
 
app = FastAPI(
    title="Hello Code Items API",
    description="Learning FastAPI with CRUD and JWT.",
    version="1.0.0",
    contact={
        "name": "API Support",
        "email": "support@example.com",
    },
    license_info={"name": "MIT"},
)

Shows on doc home pages and in openapi.json.

Route-Level Documentation

python
@app.get(
    "/items/{item_id}",
    response_model=ItemRead,
    summary="Get one item",
    description="Returns a single item by primary key.",
    response_description="The item record",
    tags=["items"],
)
def get_item(item_id: int):
    ...

tags group endpoints in Swagger sidebar—match APIRouter(tags=[...]).

Document Parameters

Pydantic Field(description=...) and FastAPI Query/Path descriptions appear in docs:

python
from fastapi import Query, Path
 
@app.get("/search")
def search(
    q: str = Query(..., min_length=1, description="Search keywords"),
    page: int = Query(1, ge=1, description="Page number"),
):
    return {"q": q, "page": page}

Document Responses

Improves generated schema for client generators.

Multiple Servers (OpenAPI)

python
app = FastAPI(
    servers=[
        {"url": "http://127.0.0.1:8000", "description": "Local dev"},
        {"url": "https://api.example.com", "description": "Production"},
    ],
)

Swagger UI server dropdown switches base URL.

Disable Docs in Production

python
settings = get_settings()
 
app = FastAPI(
    title="Private API",
    docs_url="/docs" if settings.debug else None,
    redoc_url="/redoc" if settings.debug else None,
    openapi_url="/openapi.json" if settings.debug else None,
)

Or protect /docs behind VPN or admin auth.

Tip

Publish Schema Intentionally

Many teams export openapi.json to CI artifacts for frontend codegen—do not rely on prod UI being public.

OAuth2 in Swagger

When using OAuth2PasswordBearer, /docs shows Authorize button linked to tokenUrl. Ensure login route matches:

python
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")

Test login flow from UI before sharing docs with partners.

Compare With Other Stacks

StackDocs tool
FastAPIBuilt-in OpenAPI
Spring BootSpringDoc / Swagger
Flaskflask-smorest, flasgger (add-on)

See Flask CORS/OpenAPI mention.

Export OpenAPI for Clients

bash
curl http://127.0.0.1:8000/openapi.json -o openapi.json

Generate TypeScript client with openapi-generator, orval, etc.—team workflow outside this track.

Custom OpenAPI Schema (Advanced)

Use sparingly—prefer declarative route metadata.

FAQ

/docs blank after deploy?

openapi_url disabled or static files blocked—check settings.

Schema missing model?

Ensure response_model set; return type annotation helps.

Duplicate operation IDs?

Set unique operation_id on routes for client generators.

Hide internal routes?

Use separate APIRouter with include_in_schema=False.

OpenAPI 2 vs 3?

FastAPI generates OpenAPI 3.x.

ReDoc vs Swagger?

Same schema—pick UI preference; Swagger allows try-it-out.