Skip to main content
Outcome: a route adds Depends(require_key()) or Depends(require_key("reports.read")), and the dependency the key, rejects bad requests with the right status, gives the handler the verification data, and adds X-RateLimit-* headers.
Create a root key with the permissions listed on this page under Root Keys in the dashboard sidebar. CLI commands can instead use a session from unkey login with the required permissions. See Permission reference for every permission.
The root key needs unkey:v1:<workspace_id>:projects/<project_id>/keyspaces/<keyspace_id>/keys/*#verify for the keyspace. See Root key permissions. Install with pip install unkey.py fastapi uvicorn.

The dependency

require_key takes an optional permission query, so each route can ask for its own. FastAPI’s HTTPBearer reads the header and returns 401 if it’s missing. Catch httpx.HTTPError as well as errors.UnkeyError. A timeout or connection failure raises an httpx error, and without catching it an outage becomes a 500 instead of a 503.
app/auth.py

Routes

app/main.py
Headers set on the injected Response reach the client when the request succeeds. When the dependency raises an HTTPException, such as a 429, those headers are dropped, so pass them in the exception’s headers argument if you need them on rejections too.

Async

For an async application, use async with Unkey(...) in the lifespan and await unkey.keys.verify_key_async(...) in an async def dependency. The rest of the code is unchanged.
Last modified on November 11, 2026