FastAPI Basics • Lesson 12

Header Parameters

Learn to read and validate HTTP headers using FastAPI's Header class. Handle common headers and custom X- headers.

🎯 What You'll Learn

  • Use FastAPI's Header class to read HTTP headers
  • Understand automatic hyphen-to-underscore conversion
  • Handle custom X- headers for API authentication
  • Work with optional headers and default values

Header Parameters

🎯 What You'll Learn

This lesson covers how to read and validate HTTP headers in your FastAPI endpoints using the Header class. Headers carry metadata about the request and are essential for authentication, content negotiation, and request tracking.

By the end of this lesson, you'll understand how to:

  • Read standard and custom HTTP headers in your endpoints
  • Use FastAPI's automatic hyphen-to-underscore conversion
  • Handle custom X- headers for API authentication and tracking
  • Work with optional and required header parameters

📚 Theory

What Are HTTP Headers?

HTTP headers are key-value pairs sent with every HTTP request and response. They carry metadata about the request, the client, and the desired response format. Common request headers include:

  • User-Agent - Identifies the client software making the request
  • Accept-Language - Preferred language for the response
  • Authorization - Credentials for authenticating the client
  • Content-Type - Media type of the request body
  • X-Request-Id - Custom header for tracking requests across services

FastAPI's Header Class

FastAPI provides a Header class that works like Query, Path, and Cookie, but reads values from HTTP request headers:

from fastapi import FastAPI, Header

app = FastAPI()

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

Without Header(), FastAPI would treat user_agent as a query parameter. The Header() default tells FastAPI to look in the request headers instead.

Automatic Hyphen-to-Underscore Conversion

HTTP headers traditionally use hyphens as separators (e.g., User-Agent, Accept-Language), but Python variable names cannot contain hyphens. FastAPI automatically converts between the two:

# Header name: "User-Agent" -> Python variable: user_agent
# Header name: "Accept-Language" -> Python variable: accept_language
# Header name: "X-Token" -> Python variable: x_token

@app.get("/info/")
def get_info(
    user_agent: str | None = Header(default=None),
    accept_language: str = Header(default="en"),
):
    return {"user_agent": user_agent, "language": accept_language}

If you need to disable this conversion (rare), you can set convert_underscores=False:

@app.get("/special/")
def get_special(
    x_custom: str = Header(convert_underscores=False),
):
    # This reads the literal header "x_custom" instead of "X-Custom"
    return {"value": x_custom}

🔧 Key Concepts

Required vs Optional Headers

Required headers have no default value. If missing, FastAPI returns a 422 error:

# Required - client must send this header
x_token: str = Header()

Optional headers provide a default value:

# Optional - defaults to None if not sent
user_agent: str | None = Header(default=None)

# Optional - defaults to "en" if not sent
accept_language: str = Header(default="en")

Custom X- Headers

The X- prefix is a convention for custom, non-standard headers. They are widely used for:

  • Authentication: X-Token, X-API-Key
  • Request tracking: X-Request-Id, X-Correlation-Id
  • Feature flags: X-Feature-Beta, X-Debug-Mode
@app.get("/secure/data/")
def get_secure_data(
    x_token: str = Header(),
    x_request_id: str | None = Header(default=None),
):
    return {
        "data": "secret",
        "token": x_token,
        "request_id": x_request_id,
    }

Header vs Query vs Path vs Cookie

All four classes share the same interface but read from different parts of the request:

ClassSourceExample
QueryURL query string?token=abc123
PathURL path/users/abc123
CookieCookie headerCookie: token=abc123
HeaderRequest headersX-Token: abc123

Practical Example

Calling GET /headers/info/ with headers User-Agent: MyApp/1.0 and Accept-Language: en-US returns:

{
    "user_agent": "MyApp/1.0",
    "accept_language": "en-US"
}

Calling GET /secure/data/ with headers X-Token: supersecrettoken and X-Request-Id: req-123 returns:

{
    "data": "secret",
    "token": "supersecrettoken",
    "request_id": "req-123"
}

🔗 What's Next?

In the next lesson, you'll learn about Response Model, where you'll discover how to define and validate the shape of your API responses using Pydantic models and FastAPI's response_model parameter.

📖 Additional Resources

💡 Hint

Import Header from fastapi. Note: header names with hyphens (like X-Token) automatically convert to underscores (x_token) in Python.

Ready to Practice?

Now that you understand the theory, let's put it into practice with hands-on coding!

Start Interactive Lesson