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=True to prevent JavaScript from accessing them.

Leave a Comment

Your email address will not be published. Required fields are marked *