Clerk Python SDK
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.
Warnings
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
Install
-
pip install clerk-backend-api
Imports
- Clerk
from clerk_backend_api import Clerk
- AuthenticateRequestOptions
from clerk_backend_api.jwks_helpers import AuthenticateRequestOptions
Quickstart
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