Skip to course content
Free FastAPI backend course

FastAPI for AI Backend Development

Unit 06.03: Documenting what the endpoint actually promises

The errors an endpoint can return belong in its published contract.

Declared responses

An endpoint declaring its 422 and 503 shapes alongside its success model.

The code prints the resulting documented responses.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()


class Error(BaseModel):
    error: str
    detail: str


class Out(BaseModel):
    category: str


@app.post("/classify", response_model=Out,
          responses={422: {"model": Error, "description": "validation failed"},
                     503: {"model": Error, "description": "model unavailable"}})
def classify() -> Out:
    return Out(category="billing")


schema = app.openapi()["paths"]["/classify"]["post"]["responses"]
for code in sorted(schema):
    print(f"{code}: {schema[code].get('description')}")

print("""
Declaring the error responses puts them in the published contract, so a caller
can see every status they must handle without reading your source or
discovering them in production.
""")

A caller can now see every status they must handle without reading your source or discovering them in production. That is what lets them write correct retry and error-display logic before they ever call you.

It also forces you to decide. Writing the list surfaces statuses you return by accident - a 500 from an unhandled boundary failure that should have been a 503.

The mistake this prevents

The mistake is documenting only the success case because the errors feel like implementation detail. To the caller they are the interesting part: the success path needs no logic, and every error does.

Takeaway

Declare the error responses in the contract. It tells callers what to handle and forces you to notice statuses you return unintentionally.