Clerk Python SDK

raw JSON →
5.0.2 verified Tue May 12 auth: no python install: verified quickstart: verified

Official Clerk backend SDK for Python. Current version is 5.0.2 (Feb 2026). PyPI package is 'clerk-backend-api', imports as 'clerk_backend_api'. SDK was only released in beta Oct 2024 — most tutorials predate it and use manual JWT verification with PyJWT. Three confusable PyPI packages: 'clerk-backend-api' (official), 'clerk-sdk' (unrelated third-party), 'clerk-sdk-python' (single-release stub). Package was previously also distributed as 'clerk' during alpha.

pip install clerk-backend-api
error ModuleNotFoundError: No module named 'clerk' OR ModuleNotFoundError: No module named 'clerk_backend_api'
cause The official 'clerk-backend-api' package is imported as 'clerk_backend_api', but developers might try to import 'clerk' due to older tutorials or package name confusion (e.g., from the 'clerk-sdk-python' package or alpha versions). Alternatively, 'clerk-backend-api' might not be installed at all.
fix
Ensure 'clerk-backend-api' is installed (pip install clerk-backend-api) and import it correctly as 'from clerk_backend_api import Clerk'.
error Error: Missing Clerk Secret Key OR Error: Clerk: Invalid API key
cause The CLERK_SECRET_KEY environment variable is not set, is incorrect, or does not match the Clerk application it's being used with.
fix
Set CLERK_SECRET_KEY in your environment variables (e.g., in a .env file) to the Secret Key found in your Clerk Dashboard under API Keys.
error 401 Could not authenticate request. OR Invalid Authorization header format.
cause The Authorization header in the request is missing, malformed, or contains an invalid or expired JWT/API key.
fix
Ensure your backend is receiving a valid Bearer token from the frontend and is correctly passing your Clerk Secret Key or a valid session token in the 'Authorization: Bearer <token>' header when making requests to the Clerk API or when authenticating incoming requests.
error request_body_invalid (often seen when using expires_in_seconds with create_session_token)
cause When calling 'create_session_token', the 'expires_in_seconds' argument is being passed as a float, but the Clerk API expects an integer value.
fix
Cast the 'expires_in_seconds' argument to an integer before passing it to the 'create_session_token' method. Example: 'expires_in_seconds=int(some_float_value)'.
error AttributeError: 'Clerk' object has no attribute 'users' (or similar for other resources like 'email_addresses', 'sessions')
cause Attempting to access a sub-resource or method on the 'Clerk' client that either does not exist, is named differently, or is not available in the imported SDK version.
fix
Consult the official 'clerk-backend-api' documentation or the SDK source code to verify the correct attribute and method names for the desired API operation (e.g., 'clerk.users' vs 'clerk.users', 'list()' vs 'get_all()'). For example, to list users, use 'clerk.users.list()' or to get an email address, use 'clerk.email_addresses.get(email_address_id=...)'.
breaking 'pip install clerk-sdk' installs an unrelated third-party package (F-One's document management SDK, not Clerk auth). It has the same top-level Clerk class name but completely different API. Silent wrong-package installation.
fix Always pip install clerk-backend-api (with dashes). Verify with: pip show clerk-backend-api
breaking The official SDK was only released Oct 2024. All tutorials and LLM training data before that date use manual JWT verification with PyJWT + JWKS endpoint fetch — not the SDK. That pattern still works but is not the official approach.
fix Use sdk.authenticate_request() from clerk_backend_api for request auth instead of manual jwt.decode().
breaking SDK has had breaking changes between minor versions during beta/v4-v5 cycle. The docs warn: 'pin usage to a specific package version' to avoid silent breakage.
fix Pin: clerk-backend-api==5.0.2 in requirements.txt. Review changelog before upgrading.
breaking bearer_auth must be your Secret Key (sk_live_... or sk_test_...), NOT the Publishable Key (pk_live_... or pk_test_...). Passing a Publishable Key returns 401 with no clear error message.
fix Clerk(bearer_auth=os.environ['CLERK_SECRET_KEY']). Secret key starts with sk_, not pk_.
gotcha Clerk() must be used as a context manager (with Clerk(...) as clerk:) or explicitly closed to release HTTPX connection pool. Omitting causes ResourceWarning in long-lived processes.
fix Use 'with Clerk(...) as clerk:' pattern. Or call clerk.close() explicitly.
gotcha authenticate_request() requires an httpx.Request object, not a raw dict or string token. Framework-specific adapters are needed to convert Flask/Django/FastAPI request objects.
fix For FastAPI: construct httpx.Request from request.headers and URL. Or use community packages like fastapi-clerk-auth for framework integration.
gotcha Clerk API versioning: each SDK version pins to a specific API version. Upgrading the SDK may silently change API behavior (field renames, new required fields) not just the SDK interface.
fix Pin SDK version in production. Review Clerk API changelog at clerk.com/changelog before upgrading.
breaking The Clerk constructor expects the `CLERK_SECRET_KEY` environment variable to be set when accessing it via `os.environ['CLERK_SECRET_KEY']`. If this variable is not defined, a `KeyError` will occur, preventing the application from initializing.
fix Ensure the `CLERK_SECRET_KEY` environment variable is set in your environment before running the application. For example, `export CLERK_SECRET_KEY="sk_live_..."` or configure it in your deployment environment.
breaking The `CLERK_SECRET_KEY` environment variable must be set for the SDK to initialize. Accessing `os.environ['CLERK_SECRET_KEY']` when it's not set will raise a `KeyError`.
fix Ensure `CLERK_SECRET_KEY` is set in the environment before running the application. For example, `export CLERK_SECRET_KEY=sk_test_...` or pass it via Docker/CI configurations.
python os / libc status wheel install import disk
3.10 alpine (musl) - - 2.90s 53.7M
3.10 slim (glibc) - - 1.96s 53M
3.11 alpine (musl) - - 4.02s 58.4M
3.11 slim (glibc) - - 3.35s 58M
3.12 alpine (musl) - - 3.17s 49.6M
3.12 slim (glibc) - - 3.38s 49M
3.13 alpine (musl) - - 3.13s 49.3M
3.13 slim (glibc) - - 3.16s 49M
3.9 alpine (musl) - - 2.42s 52.7M
3.9 slim (glibc) - - 2.10s 52M

Management API user listing and request authentication using clerk-backend-api v5.

import os
from clerk_backend_api import Clerk

# Management API — use CLERK_SECRET_KEY (sk_live_... or sk_test_...)
with Clerk(bearer_auth=os.environ['CLERK_SECRET_KEY']) as clerk:
    # List users
    users = clerk.users.list(limit=10)
    for user in users:
        print(user.email_addresses)

    # Get single user
    user = clerk.users.get(user_id='user_abc123')
    print(user.id)

# Request authentication (verify JWT from frontend)
import httpx
from clerk_backend_api.jwks_helpers import AuthenticateRequestOptions

def is_signed_in(request: httpx.Request) -> bool:
    sdk = Clerk(bearer_auth=os.environ['CLERK_SECRET_KEY'])
    state = sdk.authenticate_request(
        request,
        AuthenticateRequestOptions(
            authorized_parties=['https://your-app.com']
        )
    )
    return state.is_signed_in