Complete DevOps Bootcamp: Master DevOps in 12 Weeks
FastAPIRouting and Parameters

Request Headers and Cookies

Introduction

Every HTTP request carries headers and sometimes cookies. Headers contain metadata about the request such as content type, authentication tokens, or client information. Cookies store small pieces of state sent by the browser with every request. FastAPI provides a clean way to read both.

Why This Matters

Reading headers is essential for authentication, content negotiation, and tracking clients. Cookies are used for session management. Understanding how to access these in FastAPI lets you build more complete APIs.

Reading Request Headers

Use the Header function from FastAPI to declare a header parameter:

from fastapi import FastAPI, Header
from typing import Optional

app = FastAPI()

@app.get("/info")
def get_info(user_agent: Optional[str] = Header(default=None)):
    return {"User-Agent": user_agent}

FastAPI maps user_agent to the User-Agent HTTP header automatically. Underscores in argument names are converted to hyphens to match the HTTP header format.

Header Name Conversion

HTTP headers use hyphens such as X-Request-ID, but Python variable names cannot contain hyphens. FastAPI automatically converts underscores to hyphens:

Function argumentHTTP header
user_agentUser-Agent
x_request_idX-Request-ID
accept_languageAccept-Language

Custom Headers

Reading a custom header such as an API key sent by the client:

from fastapi import FastAPI, Header, HTTPException
from typing import Optional

app = FastAPI()

@app.get("/secure")
def secure_endpoint(x_api_key: Optional[str] = Header(default=None)):
    if x_api_key != "expected-key":
        raise HTTPException(status_code=401, detail="Invalid API key")
    return {"status": "authorized"}

Multiple Header Values

Some headers can appear multiple times in a single request. Declare them as a list to receive all values:

from typing import List

@app.get("/items")
def get_items(x_token: List[str] = Header(default=[])):
    return {"tokens": x_token}

Reading All Headers

To access all headers without declaring them individually, use the Request object:

from fastapi import FastAPI, Request

app = FastAPI()

@app.get("/headers")
def read_headers(request: Request):
    return dict(request.headers)

Reading Cookies

Use the Cookie function to declare cookie parameters:

from fastapi import FastAPI, Cookie
from typing import Optional

app = FastAPI()

@app.get("/me")
def get_profile(session_id: Optional[str] = Cookie(default=None)):
    return {"session_id": session_id}

The argument name must match the cookie name sent by the client.

Setting Cookies in a Response

To set a cookie in the response, use the Response object:

from fastapi import FastAPI, Response

app = FastAPI()

@app.post("/login")
def login(response: Response):
    response.set_cookie(key="session_id", value="abc123", httponly=True)
    return {"message": "Logged in"}

Cookie options:

OptionPurpose
httponly=TruePrevents JavaScript from reading the cookie
secure=TrueCookie is only sent over HTTPS
max_ageHow long the cookie lasts in seconds
samesiteControls cross-site cookie sending

Deleting Cookies

@app.post("/logout")
def logout(response: Response):
    response.delete_cookie(key="session_id")
    return {"message": "Logged out"}

Headers vs Cookies vs Query Parameters

LocationBest for
HeadersAuthentication tokens, content type, metadata
CookiesSession data, persistent client state
Query parametersFilters, pagination, search

Common Mistakes

Expecting case-sensitive header matching

HTTP headers are case-insensitive. FastAPI normalizes them, so User-Agent and user-agent refer to the same header.

Forgetting that cookies are not automatically available for all clients

APIs consumed by mobile apps or server-to-server clients often send tokens in headers rather than cookies. Design based on your actual clients.

Storing sensitive data in cookies without proper flags

Always use httponly=True and secure=True for cookies that hold session or authentication data.

Summary

FastAPI reads request headers using the Header function and cookies using the Cookie function. Underscore-to-hyphen conversion handles the naming mismatch between Python and HTTP. Cookies can be set and deleted through the response object. Use httponly and secure flags for cookies that carry sensitive session data.

How is this guide?

Last updated on