Skip to main content

Parameter Validation and Metadata

FastAPI uses the Param class and its subclasses to define how request parameters should be validated and documented in OpenAPI. By using these classes, you can enforce constraints like numeric ranges or string patterns while simultaneously providing metadata like descriptions and examples for your API documentation.

Defining Parameter Constraints

When you need to ensure that a parameter meets specific criteria—such as an ID being a positive integer or a search query having a minimum length—you use validation parameters. These are passed to the constructors of Query, Path, Header, or Cookie.

Numeric Validation

You can restrict numeric values using ge (greater than or equal), gt (greater than), le (less than or equal), and lt (less than).

from typing import Annotated
from fastapi import FastAPI, Path, Query

app = FastAPI()

@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
size: Annotated[float, Query(gt=0, lt=10.5)],
):
return {"item_id": item_id, "size": size}

In this example, FastAPI ensures that item_id is between 0 and 1000. If a user requests /items/2000, FastAPI returns a 422 Unprocessable Entity error. Internally, the Param class (defined in fastapi/params.py) passes these arguments to Pydantic's FieldInfo to handle the underlying validation logic.

String Validation and Patterns

For string parameters, you can use min_length, max_length, and pattern. The pattern parameter accepts a regular expression that the input must match.

from typing import Annotated
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
q: Annotated[
str | None, Query(min_length=3, max_length=50, pattern="^fixedquery$")
] = None,
):
return {"q": q}

[!IMPORTANT] The regex parameter is deprecated in FastAPI 0.100.0 and Pydantic v2. You should use pattern instead. The Param class in fastapi/params.py still supports regex for backward compatibility but will issue a FastAPIDeprecationWarning.

Adding OpenAPI Metadata

Beyond validation, Param allows you to enrich the generated OpenAPI schema with descriptive metadata. This information appears in the interactive documentation (Swagger UI).

Titles and Descriptions

Use title and description to explain the purpose of a parameter:

@app.get("/items/")
async def read_items(
q: Annotated[str | None, Query(title="Query string", description="Query string for the items to search in the database")] = None,
):
return {"q": q}

Examples

You can provide examples of valid data using the examples parameter. This helps API consumers understand the expected format.

@app.get("/query_examples/")
def query_examples(
data: str | None = Query(
default=None,
examples=[
"json_schema_query1",
"json_schema_query2",
],
openapi_examples={
"Query One": {
"summary": "Query One Summary",
"description": "Query One Description",
"value": "query1",
},
},
),
):
return data

As seen in fastapi/params.py, the example parameter is deprecated in favor of examples to align with OpenAPI 3.1.0. If you provide example, FastAPI will warn you and attempt to map it to the newer format.

Parameter Aliases

Sometimes you need to accept a parameter name that is not a valid Python variable name, such as a hyphenated string like item-query. You can use the alias parameter for this.

@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(alias="item-query")] = None):
return {"q": q}

When a request comes in as /items/?item-query=fixedquery, FastAPI maps the value to the q parameter in your function.

Internal Implementation and Subclasses

The Param class serves as the base for all request parameter types. It inherits from Pydantic's FieldInfo, which is why it shares many of the same validation keywords.

Path Parameters

The Path class (a subclass of Param) has a unique constraint: path parameters are always required. In fastapi/params.py, the Path constructor explicitly asserts that the default value must be ... (Ellipsis):

# From fastapi/params.py
class Path(Param):
def __init__(self, default: Any = ..., **kwargs):
assert default is ..., "Path parameters cannot have a default value"
super().__init__(default=default, **kwargs)

Header Parameters

The Header class includes a specific feature for HTTP headers: convert_underscores. By default, it is set to True, which means a parameter named user_agent will automatically look for the User-Agent HTTP header.

Cookie and Query are direct subclasses of Param that set the in_ attribute to ParamTypes.cookie and ParamTypes.query respectively, signaling to FastAPI's dependency resolver where to extract the data from the incoming request.