FastAPI Headers and Cookies
Headers and cookies are two ways to pass extra information alongside a request. Headers carry metadata like authentication tokens or content format preferences. Cookies store small pieces of data in the user's browser and are sent automatically with every request to the same domain.
What Headers Look Like in a Request
HTTP Request ──────────────────────────────── GET /dashboard HTTP/1.1 Host: example.com Authorization: Bearer eyJhbGc... Accept-Language: en-US X-Request-ID: abc-123 ──────────────────────────────── (no body for GET)
Each line after the request line is a header. Your FastAPI route can read any of them.
Reading a Header in FastAPI
from fastapi import FastAPI, Header
app = FastAPI()
@app.get("/dashboard")
def get_dashboard(authorization: str = Header()):
return {"auth_header_received": authorization}
FastAPI maps the function argument name to the header name. It converts underscores to hyphens automatically, so authorization reads the Authorization header.
Header Name Conversion
Function argument Header it reads ──────────────────────────────────────── authorization → Authorization accept_language → Accept-Language x_request_id → X-Request-Id user_agent → User-Agent
Optional Headers with a Default
from typing import Optional
@app.get("/items")
def get_items(x_api_version: Optional[str] = Header(default="v1")):
return {"api_version": x_api_version}
If the client does not send the X-Api-Version header, the value defaults to "v1".
Reading Multiple Values from One Header
Some headers (like Accept) can appear multiple times in one request. Use a list to capture all values:
from typing import List
@app.get("/formats")
def get_formats(accept: List[str] = Header(default=[])):
return {"accepted_formats": accept}
What Cookies Look Like
Browser stores: session_id = "xyz987abc" theme = "dark" Every request to the same domain automatically includes: Cookie: session_id=xyz987abc; theme=dark
Cookies travel in a single Cookie header. FastAPI parses them individually by name.
Reading a Cookie in FastAPI
from fastapi import FastAPI, Cookie
@app.get("/profile")
def get_profile(session_id: Optional[str] = Cookie(default=None)):
if session_id is None:
return {"error": "No session cookie found"}
return {"session": session_id}
Setting a Cookie in a Response
To send a cookie back to the client, use a Response object:
from fastapi import Response
@app.post("/login")
def login(response: Response):
response.set_cookie(
key="session_id",
value="xyz987abc",
httponly=True, ← JS cannot read this cookie
max_age=3600 ← expires in 1 hour (seconds)
)
return {"message": "Logged in"}
Server response includes: Set-Cookie: session_id=xyz987abc; HttpOnly; Max-Age=3600 Browser stores the cookie. Next request sends it back automatically.
Deleting a Cookie
@app.post("/logout")
def logout(response: Response):
response.delete_cookie(key="session_id")
return {"message": "Logged out"}
Headers vs Cookies — When to Use Which
Use Headers for: Use Cookies for: API tokens (Bearer ...) Session IDs Content negotiation User preferences Custom request metadata Remember-me tokens Server-to-server calls Browser-based auth
Key Points
- Read request headers using
Header()as a function default. - FastAPI converts underscores in argument names to hyphens to match real header names.
- Read cookies using
Cookie()as a function default. - Set cookies in the response using
response.set_cookie(). - Mark cookies as
httponly=Trueto prevent JavaScript from accessing them.
