{"id":1789,"library":"workos","title":"WorkOS Python Client","description":"WorkOS Python Client provides a comprehensive SDK to interact with the WorkOS API for enterprise-ready features like Single Sign-On (SSO), Directory Sync (SCIM), Multi-Factor Authentication (MFA), Admin Portal, and Audit Logs. It simplifies integration with various identity providers and directory services. The library is actively maintained with frequent updates, often on a weekly or bi-weekly cadence. The current version is 5.46.0.","status":"active","version":"5.46.0","language":"en","source_language":"en","source_url":"https://github.com/WorkOS/workos-python","tags":["auth","sso","directory_sync","mfa","webhooks","user_management","enterprise_readiness"],"install":[{"cmd":"pip install workos","lang":"bash","label":"Install WorkOS"}],"dependencies":[],"imports":[{"note":"This is the primary way to configure and interact with the WorkOS API by setting global configuration variables (e.g., `workos.api_key`, `workos.client_id`) and accessing sub-modules (e.g., `workos.sso`).","symbol":"workos","correct":"import workos"},{"note":"Use `WorkOSClient` to instantiate an explicit client object, which is useful for multi-tenant applications or when managing multiple WorkOS configurations within a single application.","symbol":"WorkOSClient","correct":"from workos import WorkOSClient"},{"note":"Specific error class for handling webhook signature verification failures.","symbol":"WebhookSignatureError","correct":"from workos.errors import WebhookSignatureError"}],"quickstart":{"code":"import os\nimport workos\nfrom pprint import pprint\n\n# Configure WorkOS using environment variables\n# For local testing, replace with actual test keys if env vars are not set\nworkos.api_key = os.environ.get(\"WORKOS_API_KEY\", \"sk_test_YOUR_API_KEY\")\nworkos.client_id = os.environ.get(\"WORKOS_CLIENT_ID\", \"client_test_YOUR_CLIENT_ID\")\n\n# Optional: Set the API base URL for custom environments (e.g., local development)\n# workos.base_api_url = \"http://localhost:8000/\"\n\n# Example 1: List organizations\ntry:\n    print(\"\\n--- Listing Organizations ---\")\n    organizations = workos.organizations.list_organizations(limit=5)\n    if organizations.data:\n        for org in organizations.data:\n            pprint(org.to_dict())\n    else:\n        print(\"No organizations found.\")\nexcept Exception as e:\n    print(f\"Error listing organizations: {e}\")\n\n# Example 2: Generate an SSO authorization URL\ntry:\n    print(\"\\n--- Generating SSO Authorization URL ---\")\n    authorization_url = workos.sso.get_authorization_url(\n        domain=\"example.com\", # Replace with a domain configured in WorkOS\n        redirect_uri=\"http://localhost:8000/callback\", # Must be a valid redirect URI configured in WorkOS\n        state=\"some-secure-random-state\"\n    )\n    print(f\"SSO Authorization URL for example.com: {authorization_url}\")\nexcept Exception as e:\n    print(f\"Error generating SSO URL: {e}\")\n\n# Example 3: Verify a webhook event (simulated payload)\ntry:\n    print(\"\\n--- Simulating Webhook Verification ---\")\n    # In a real scenario, payload and signature_header come from the HTTP request\n    webhook_payload = '{\"id\": \"wh_01G827B6V8F1PZ1D7E40P5940X\", \"event\": \"directory_sync.user.created\", \"data\": {}}'\n    webhook_signature = \"t=1678886400,v1=signature_hash\"\n    webhook_secret = os.environ.get(\"WORKOS_WEBHOOK_SECRET\", \"webhook_secret_YOUR_WEBHOOK_SECRET\")\n\n    # This will likely fail with a dummy signature, but demonstrates the call\n    print(\"Attempting to verify webhook (will likely fail with dummy data)...\")\n    event = workos.webhooks.verify_event(\n        payload=webhook_payload,\n        signature_header=webhook_signature,\n        secret=webhook_secret\n    )\n    print(f\"Webhook event verified: {event['event']}\")\nexcept workos.errors.WebhookSignatureError as e:\n    print(f\"Webhook signature verification failed: {e}\")\nexcept Exception as e:\n    print(f\"Error during webhook verification simulation: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to configure the WorkOS Python Client using environment variables for API keys and client IDs. It then shows examples of listing organizations, generating an SSO authorization URL, and verifying a webhook event. Remember to replace placeholder API keys, client IDs, domains, and redirect URIs with your actual WorkOS credentials and configurations. Webhook verification is critical and requires a valid signature and secret."},"warnings":[{"fix":"Consult the official WorkOS Python SDK v2.0.0 migration guide. Update import paths, module access patterns, and parameter names according to the new API structure.","message":"Major breaking changes were introduced in version `2.0.0`. This included significant renames (e.g., `WorkOS` class methods moved to top-level `workos` module), changes in error handling (e.g., `workos.exceptions` moved to `workos.errors`), and parameter name updates across various API methods. Upgrading from `1.x.x` to `2.x.x` requires code modifications.","severity":"breaking","affected_versions":"<2.0.0 to 2.x.x+"},{"fix":"Ensure that every incoming webhook payload is passed to `workos.webhooks.verify_event()` along with the `WorkOS-Signature` header and your webhook secret. Catch `workos.errors.WebhookSignatureError` to handle invalid signatures gracefully.","message":"Webhook events must always be cryptographically verified using `workos.webhooks.verify_event()`. Failure to do so exposes your webhook endpoints to spoofing and unauthorized access, posing a significant security risk.","severity":"gotcha","affected_versions":"All"},{"fix":"When fetching lists of resources, check the `list_response.list_metadata.after` field. If present, make subsequent calls with `after=list_response.list_metadata.after` until `after` is `None`.","message":"Many WorkOS list endpoints (e.g., `list_organizations`, `list_users`) are paginated. If you don't explicitly handle pagination by iterating through `organizations.list_organizations(limit=N, after='cursor')` or similar patterns, you will only receive the first page of results, leading to incomplete data.","severity":"gotcha","affected_versions":"All"},{"fix":"For explicit control over client instances and their configurations, use `from workos import WorkOSClient` and instantiate client objects: `client = WorkOSClient(api_key=\"...\", client_id=\"...\")`. Pass this `client` object around or create new ones as needed.","message":"The global configuration pattern (`import workos; workos.api_key = ...`) can lead to issues in complex applications (e.g., multi-tenant services, tests) where different WorkOS configurations are needed simultaneously. All requests will use the globally set credentials.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}