{"id":96,"library":"clerk-backend-api","title":"Clerk Python SDK","description":"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.","status":"active","version":"5.0.2","language":"python","source_language":"en","source_url":"https://github.com/clerk/clerk-sdk-python","tags":["clerk","authentication","jwt","identity","users","python","iam"],"install":[{"cmd":"pip install clerk-backend-api","lang":"bash","label":"Python (official)"}],"dependencies":[{"reason":"HTTP client. Auto-installed.","package":"httpx","optional":false},{"reason":"Response model validation. Auto-installed.","package":"pydantic","optional":false},{"reason":"JWT verification for authenticate_request(). Auto-installed.","package":"pyjwt","optional":false},{"reason":"Required for RS256 JWT signature verification. Auto-installed.","package":"cryptography","optional":false}],"imports":[{"note":"Package is clerk-backend-api, imports as clerk_backend_api. 'from clerk import Clerk' raises ModuleNotFoundError. The 'clerk' PyPI package was an early alpha name that no longer receives updates.","wrong":"from clerk import Clerk","symbol":"Clerk","correct":"from clerk_backend_api import Clerk"},{"note":"JWT/request auth helpers are in the jwks_helpers submodule, not the top-level package.","wrong":"from clerk_backend_api import AuthenticateRequestOptions","symbol":"AuthenticateRequestOptions","correct":"from clerk_backend_api.jwks_helpers import AuthenticateRequestOptions"}],"quickstart":{"code":"import os\nfrom clerk_backend_api import Clerk\n\n# Management API — use CLERK_SECRET_KEY (sk_live_... or sk_test_...)\nwith Clerk(bearer_auth=os.environ['CLERK_SECRET_KEY']) as clerk:\n    # List users\n    users = clerk.users.list(limit=10)\n    for user in users:\n        print(user.email_addresses)\n\n    # Get single user\n    user = clerk.users.get(user_id='user_abc123')\n    print(user.id)\n\n# Request authentication (verify JWT from frontend)\nimport httpx\nfrom clerk_backend_api.jwks_helpers import AuthenticateRequestOptions\n\ndef is_signed_in(request: httpx.Request) -> bool:\n    sdk = Clerk(bearer_auth=os.environ['CLERK_SECRET_KEY'])\n    state = sdk.authenticate_request(\n        request,\n        AuthenticateRequestOptions(\n            authorized_parties=['https://your-app.com']\n        )\n    )\n    return state.is_signed_in","lang":"python","description":"Management API user listing and request authentication using clerk-backend-api v5."},"warnings":[{"fix":"Always pip install clerk-backend-api (with dashes). Verify with: pip show clerk-backend-api","message":"'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.","severity":"breaking","affected_versions":"all"},{"fix":"Use sdk.authenticate_request() from clerk_backend_api for request auth instead of manual jwt.decode().","message":"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.","severity":"breaking","affected_versions":"all"},{"fix":"Pin: clerk-backend-api==5.0.2 in requirements.txt. Review changelog before upgrading.","message":"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.","severity":"breaking","affected_versions":"< 5.0"},{"fix":"Clerk(bearer_auth=os.environ['CLERK_SECRET_KEY']). Secret key starts with sk_, not pk_.","message":"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.","severity":"breaking","affected_versions":"all"},{"fix":"Use 'with Clerk(...) as clerk:' pattern. Or call clerk.close() explicitly.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"For FastAPI: construct httpx.Request from request.headers and URL. Or use community packages like fastapi-clerk-auth for framework integration.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Pin SDK version in production. Review Clerk API changelog at clerk.com/changelog before upgrading.","message":"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.","severity":"gotcha","affected_versions":"all"},{"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.","message":"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.","severity":"breaking","affected_versions":"all"},{"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.","message":"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`.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T08:03:29.210Z","next_check":"2026-06-17T00:00:00.000Z","problems":[{"fix":"Ensure 'clerk-backend-api' is installed (pip install clerk-backend-api) and import it correctly as 'from clerk_backend_api import Clerk'.","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.","error":"ModuleNotFoundError: No module named 'clerk' OR ModuleNotFoundError: No module named 'clerk_backend_api'"},{"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.","cause":"The CLERK_SECRET_KEY environment variable is not set, is incorrect, or does not match the Clerk application it's being used with.","error":"Error: Missing Clerk Secret Key OR Error: Clerk: Invalid 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.","cause":"The Authorization header in the request is missing, malformed, or contains an invalid or expired JWT/API key.","error":"401 Could not authenticate request. OR Invalid Authorization header format."},{"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)'.","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.","error":"request_body_invalid (often seen when using expires_in_seconds with create_session_token)"},{"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=...)'.","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.","error":"AttributeError: 'Clerk' object has no attribute 'users' (or similar for other resources like 'email_addresses', 'sessions')"}],"ecosystem":"pypi","meta_description":null,"install_score":95,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.9,"mem_mb":29.7,"disk_size":"53.7M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.96,"mem_mb":29.7,"disk_size":"53M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":4.02,"mem_mb":30.7,"disk_size":"58.4M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.35,"mem_mb":30.7,"disk_size":"58M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.17,"mem_mb":30.1,"disk_size":"49.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.38,"mem_mb":30.1,"disk_size":"49M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.13,"mem_mb":31.1,"disk_size":"49.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.16,"mem_mb":31.1,"disk_size":"49M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.42,"mem_mb":27.7,"disk_size":"52.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.1,"mem_mb":27.7,"disk_size":"52M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}