Skip to main content

Header

Declare a header parameter for a path operation. Header parameters are extracted from HTTP request headers.
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}

Signature

def Header(
    default: Any = Undefined,
    *,
    convert_underscores: bool = True,
    alias: str | None = None,
    title: str | None = None,
    description: str | None = None,
    gt: float | None = None,
    ge: float | None = None,
    lt: float | None = None,
    le: float | None = None,
    min_length: int | None = None,
    max_length: int | None = None,
    pattern: str | None = None,
    examples: list[Any] | None = None,
    deprecated: bool | str | None = None,
    include_in_schema: bool = True,
    json_schema_extra: dict[str, Any] | None = None,
) -> Any

Parameters

default
Any
default:"Undefined"
Default value if the parameter field is not set.
convert_underscores
bool
default:"True"
Automatically convert underscores to hyphens in the parameter field name. For example, user_agent becomes user-agent.
alias
str | None
default:"None"
An alternative name for the parameter field. This will be used to extract the data and for the generated OpenAPI.
title
str | None
default:"None"
Human-readable title for the parameter.
description
str | None
default:"None"
Human-readable description for the parameter.
gt
float | None
default:"None"
Greater than validation. If set, the value must be greater than this. Only applicable to numbers.
ge
float | None
default:"None"
Greater than or equal validation. If set, the value must be greater than or equal to this. Only applicable to numbers.
lt
float | None
default:"None"
Less than validation. If set, the value must be less than this. Only applicable to numbers.
le
float | None
default:"None"
Less than or equal validation. If set, the value must be less than or equal to this. Only applicable to numbers.
min_length
int | None
default:"None"
Minimum length for strings.
max_length
int | None
default:"None"
Maximum length for strings.
pattern
str | None
default:"None"
RegEx pattern for strings.
discriminator
str | None
default:"None"
Parameter field name for discriminating the type in a tagged union.
strict
bool | None
default:"None"
If True, strict validation is applied to the field.
multiple_of
float | None
default:"None"
Value must be a multiple of this. Only applicable to numbers.
allow_inf_nan
bool | None
default:"None"
Allow inf, -inf, nan. Only applicable to numbers.
max_digits
int | None
default:"None"
Maximum number of allowed digits for numbers.
decimal_places
int | None
default:"None"
Maximum number of decimal places allowed for numbers.
examples
list[Any] | None
default:"None"
Example values for this field.
deprecated
bool | str | None
default:"None"
Mark this parameter field as deprecated. It will affect the generated OpenAPI (visible at /docs).
include_in_schema
bool
default:"True"
Whether to include this parameter field in the generated OpenAPI.
json_schema_extra
dict[str, Any] | None
default:"None"
Any additional JSON schema data.

Examples

Basic Header Parameter

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}
By default, user_agent will automatically be converted to User-Agent when reading from headers due to convert_underscores=True.

Disable Automatic Conversion

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

Required Header

@app.get("/items/")
async def read_items(
    x_token: Annotated[str, Header()]
):
    return {"X-Token": x_token}
A header parameter is required when there is no default value.

Multiple Header Values

@app.get("/items/")
async def read_items(
    x_token: Annotated[list[str] | None, Header()] = None
):
    return {"X-Token values": x_token}
This allows receiving multiple headers with the same name. For example, multiple X-Token headers.

Header with Validation

@app.get("/items/")
async def read_items(
    x_token: Annotated[str, Header(min_length=10, max_length=100)]
):
    return {"X-Token": x_token}

Custom Header Name with Alias

@app.get("/items/")
async def read_items(
    token: Annotated[str | None, Header(alias="X-API-Key")] = None
):
    return {"token": token}
Use alias when you want to use a different variable name in Python than the actual header name.

Common Use Cases

Authentication Token

@app.get("/users/me")
async def read_user(
    authorization: Annotated[str, Header()]
):
    return {"token": authorization}

Content Type

@app.post("/items/")
async def create_item(
    content_type: Annotated[str | None, Header()] = None
):
    return {"Content-Type": content_type}

Custom Headers

@app.get("/items/")
async def read_items(
    x_request_id: Annotated[str | None, Header()] = None,
    x_correlation_id: Annotated[str | None, Header()] = None
):
    return {
        "X-Request-ID": x_request_id,
        "X-Correlation-ID": x_correlation_id
    }
Header names are case-insensitive according to the HTTP specification, but FastAPI will convert them for consistency.

Build docs developers (and LLMs) love