Skip to main content

Header and Cookie Parameters

To extract metadata from request headers or browser cookies, use the Header and Cookie parameters. These classes inherit from Param (and ultimately Pydantic's FieldInfo), allowing you to define validation, metadata, and automatic type conversion for request metadata.

Header Parameters

Declare header parameters by using Annotated with the Header function. FastAPI automatically converts underscores in your parameter names to hyphens by default (e.g., user_agent becomes User-Agent).

from typing import Annotated
from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/items/")
async def read_items(user_agent: Annotated[str | None, Header()] = None):
return {"User-Agent": user_agent}

Automatic Underscore Conversion

Most headers are hyphenated (e.g., X-Token), but Python variable names cannot contain hyphens. By default, Header converts underscores to hyphens. If you need to disable this behavior, set convert_underscores=False.

@app.get("/items-strict/")
async def read_items_strict(
x_custom_header: Annotated[str | None, Header(convert_underscores=False)] = None
):
# This will look for exactly "x_custom_header" instead of "X-Custom-Header"
return {"x_custom_header": x_custom_header}

Multiple Header Values

If a request contains multiple headers with the same name, you can receive them as a list.

from typing import Annotated
from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/items/")
async def read_items(x_token: Annotated[list[str] | None, Header()] = None):
return {"X-Token values": x_token}

Declare cookie parameters using the Cookie function. These work similarly to Header but extract data from the Cookie header.

from typing import Annotated
from fastapi import Cookie, FastAPI

app = FastAPI()

@app.get("/items/")
async def read_items(ads_id: Annotated[str | None, Cookie()] = None):
return {"ads_id": ads_id}

Validation and Metadata

Since Header and Cookie inherit from Param, they support all standard Pydantic validations and OpenAPI metadata.

from typing import Annotated
from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/items/")
async def read_items(
x_token: Annotated[
str,
Header(
min_length=10,
pattern="^fixedquery",
description="A special token for authentication",
examples=["fixedquery_secret_123"]
)
]
):
return {"token": x_token}

Note: The regex and example parameters are deprecated in favor of pattern and examples.

Grouping Parameters with Models

For complex requests with many headers or cookies, you can group them into a Pydantic model. FastAPI will extract the fields from the request metadata based on the model's field names.

from typing import Annotated
from fastapi import FastAPI, Header
from pydantic import BaseModel

app = FastAPI()

class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: str | None = None
traceparent: str | None = None
x_tag: list[str] = []

@app.get("/items/")
async def read_items(headers: Annotated[CommonHeaders, Header()]):
return headers

When using a model with Header(), the same underscore-to-hyphen conversion logic applies to the model's field names (e.g., save_data looks for the Save-Data header).

Troubleshooting

Underscore Conversion Issues

If your header actually contains underscores and you are not receiving it, ensure you have set convert_underscores=False. Most HTTP proxies and servers strip headers with underscores by default, which is why FastAPI defaults to hyphen conversion.

Duplicate Header Names

If you expect multiple values for a header but only receive the last one, ensure your parameter type is declared as a list (e.g., list[str]). If declared as a single str, FastAPI will only provide the last value found in the request.