Skip to main content
This guide shows how to add API key verification to your Python applications using the official Unkey Python SDK (v2).

Prerequisites

  • Python 3.9 or higher
  • An Unkey account (free at unkey.com)

1. Install the SDK

pip install unkey-py

2. Set up your Unkey credentials

  1. Create an API in the Unkey Dashboard
  2. Create a root key at Settings → Root Keys
Set your root key as an environment variable:
export UNKEY_ROOT_KEY="unkey_xxxx"

3. FastAPI Integration

Here’s how to protect your FastAPI endpoints using the v2 SDK:
from fastapi import FastAPI, Header, HTTPException
from unkey_py import Unkey
import os

app = FastAPI()

@app.get("/api/protected")
async def protected_route(x_api_key: str = Header(..., alias="X-API-Key")):
    with Unkey(bearer_auth=os.environ["UNKEY_ROOT_KEY"]) as unkey:
        res = unkey.keys.verify_key(request={"key": x_api_key})
        result = res.data

    if not result.valid:
        raise HTTPException(
            status_code=401 if result.code == "NOT_FOUND" else 403,
            detail=f"Unauthorized: {result.code}"
        )

    return {
        "message": "Access granted",
        "key_id": result.key_id,
        "remaining_credits": result.remaining
    }
Run your FastAPI app:
uvicorn main:app --reload
Test with a valid API key:
curl -H "X-API-Key: YOUR_API_KEY" http://localhost:8000/api/protected

4. Flask Integration

For Flask applications using the v2 SDK:
from flask import Flask, request, jsonify
from unkey_py import Unkey
import os

app = Flask(__name__)

@app.route("/api/protected")
def protected_route():
    api_key = request.headers.get("X-API-Key")

    if not api_key:
        return jsonify({"error": "Missing API key"}), 401

    with Unkey(bearer_auth=os.environ["UNKEY_ROOT_KEY"]) as unkey:
        res = unkey.keys.verify_key(request={"key": api_key})
        result = res.data

    if not result.valid:
        return jsonify({"error": result.code}), 401

    return jsonify({
        "message": "Access granted",
        "key_id": result.key_id,
        "meta": result.meta
    })

if __name__ == "__main__":
    app.run(debug=True)

5. Django Integration

For Django, create a custom middleware using the v2 SDK:
# middleware/unkey_auth.py
from django.http import JsonResponse
from django.conf import settings
from unkey_py import Unkey

class UnkeyAuthMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Skip auth for unprotected paths
        if request.path.startswith('/admin/'):
            return self.get_response(request)

        api_key = request.headers.get('X-API-Key')

        if not api_key:
            return JsonResponse({'error': 'Missing API key'}, status=401)

        with Unkey(bearer_auth=settings.UNKEY_ROOT_KEY) as unkey:
            res = unkey.keys.verify_key(request={'key': api_key})
            result = res.data

        if not result.valid:
            return JsonResponse({'error': result.code}, status=401)

        # Attach key info to request
        request.unkey_key_id = result.key_id
        request.unkey_meta = result.meta

        return self.get_response(request)

# settings.py
import os

MIDDLEWARE = [
    # ... other middleware
    'myapp.middleware.unkey_auth.UnkeyAuthMiddleware',
]

UNKEY_ROOT_KEY = os.environ.get("UNKEY_ROOT_KEY")
Then in your views:
from django.http import JsonResponse

def protected_view(request):
    return JsonResponse({
        "message": "Access granted",
        "key_id": request.unkey_key_id,
    })

Creating and Managing Keys

Here’s how to create API keys programmatically using the v2 SDK:
from datetime import datetime, timedelta
from unkey_py import Unkey
import os

with Unkey(bearer_auth=os.environ["UNKEY_ROOT_KEY"]) as unkey:
    # Create a new API key
    res = unkey.keys.create_key(request={
        "api_id": "api_...",
        "prefix": "sk_live",
        "external_id": "user_123",  # Link to your user
        "name": "Production key",
        "expires": int((datetime.now() + timedelta(days=30)).timestamp() * 1000),
        "remaining": 1000,
        "refill": {
            "amount": 1000,
            "interval": "monthly",
        },
        "ratelimits": [{
            "name": "requests",
            "limit": 100,
            "duration": 60000,  # 100 per minute
            "auto_apply": True,
        }],
        "meta": {
            "plan": "pro",
            "customer_id": "cust_123",
        },
    })
    result = res.data

    print(f"Created key: {result.key}")  # Only time you'll see it!
    print(f"Key ID: {result.key_id}")
The full API key is only returned once at creation. Store it securely and never show it again.

Error Handling

Always handle Unkey errors gracefully:
from unkey_py import Unkey
import os

with Unkey(bearer_auth=os.environ["UNKEY_ROOT_KEY"]) as unkey:
    try:
        res = unkey.keys.create_key(request={
            "api_id": "api_...",
            "name": "My Key"
        })
        result = res.data
        print(f"Created: {result.key}")

    except Exception as e:
        print(f"API Error: {e}")
        # Handle specific errors based on exception type

What’s next?

Add rate limiting

Protect your endpoints from abuse

Python SDK Reference

Complete Python SDK documentation

Authorization

Add roles and permissions

Cookbook

More Python recipes and examples
Last modified on February 23, 2026