FastAPI generates an OpenAPI schema for your API automatically. From it you get interactive documentation for free — and a machine-readable contract for codegen, tests and clients.
/openapi.json — the raw OpenAPI 3 schema./docs — Swagger UI: try endpoints from the browser ("Try it out")./redoc — ReDoc: cleaner read-only reference, good for sharing with consumers.from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI(
title="Inventory API",
description="API for managing warehouse inventory.\n\n**v1** endpoints only.",
version="1.0.0",
openapi_tags=[
{"name": "items", "description": "CRUD for items"},
{"name": "health", "description": "Service status"},
],
)
class Item(BaseModel):
name: str = Field(description="Human-readable name", examples=["Wrench"])
price: float = Field(gt=0, description="Unit price in USD")
@app.post("/items/", tags=["items"], summary="Create an item",
description="Creates an item and returns it with its generated id.",
response_description="The created item",
status_code=201)
def create_item(item: Item):
return {"id": 1, **item.model_dump()}
Every parameter accepts title, description, examples; models get Field(description=...); decorators get summary, description, tags. All of it flows into the schema.
from fastapi import FastAPI, status
from pydantic import BaseModel
class ErrorMessage(BaseModel):
detail: str
@app.get("/items/{item_id}",
responses={
404: {"model": ErrorMessage, "description": "Item not found"},
400: {"description": "Invalid id format"},
})
def read_item(item_id: int):
...
The responses parameter documents additional status codes so consumers know what errors to expect.
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
app = FastAPI(docs_url="/documentation", redoc_url=None, openapi_url="/schema.json")
@app.get("/internal/", include_in_schema=False)
def internal(): ...
include_in_schema=False: keep an endpoint out of the docs (health checks, internal routes).app.openapi = lambda: get_openapi(...) or generate clients from app.openapi().FastAPI(openapi_url=None) if your policy requires it.openapi-typescript, openapi-generator create typed TS/JS or Java clients from /openapi.json.A: Never by hand. FastAPI introspects your paths, parameters, Pydantic models and declared status codes, then builds the schema at startup. Your Python code is the single source of truth.
A: Use tags=["items"] on routers or endpoints. Tags declared in openapi_tags get descriptions and a fixed order in the docs.
A: Yes — the docs call the real server. For shared/team environments protect or disable docs (docs_url=None, or gate them behind auth) since "Try it out" executes real mutations.
Documentation is a byproduct of writing typed FastAPI code: enrich it with tags, summary, Field(description=...) and responses, then reuse the openapi.json for clients and testing. Well-described schemas are how teams consume your API without asking you questions.