A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The WorkOS API is how an app or AI agent works with a WorkOS environment: creating and reading users and organizations, authenticating people through single sign-on and magic codes, listing the users and groups in a synced directory, and recording audit events. Access is granted through one environment-level API key sent as a bearer token, and that key reaches everything in its environment because WorkOS has no per-endpoint scopes. WorkOS can also push events to a webhook URL when something changes, like a directory user being created.
How an app or AI agent connects to WorkOS determines what it can reach. The main route is the REST API, called with an environment-level API key, alongside webhooks that push events back to a registered URL.
The REST API answers over HTTPS at api.workos.com. It accepts and returns JSON, and every call is authorized by one environment-level secret API key sent as a bearer token.
Webhooks deliver chosen events to a receiver URL, such as a directory user being created or an SSO connection being activated. A signature header on each delivery confirms it came from WorkOS.
WorkOS publishes official server-side SDKs, including Node.js, Python, Ruby, Go, PHP, .NET, Java, Elixir, and Rust, that wrap the REST API and use the same environment API key.
A single secret API key, prefixed sk_ and tied to one environment, authorizes every server-side call as a bearer token. It carries no per-endpoint scopes, so one key reaches every method in its environment, read and write.
A public Client ID, prefixed client_, identifies the environment when building an SSO or hosted authentication URL. It is not secret and does not authorize API calls on its own; the secret API key does that.
The WorkOS API is split into areas an agent can act on: managing users and their sessions, organizations and their verified domains, single sign-on connections, synced directories of users and groups, and a stream of audit events. Each area has its own methods, and some change far more than others.
Create, read, list, update, and delete users, and authenticate them through password, code, magic auth, and MFA grants.
Create a one-time email authentication code and read its details.
Enroll an authentication factor, challenge it, and verify the challenge.
Create, read, list, update, and delete organizations, the hub that connections, directories, and audit events belong to.
Create an organization domain, read it, and verify ownership through a DNS record.
Build an SSO authorization URL, exchange the code for a profile, and list, read, or delete connections.
List and read synced directories, their users, and their groups.
Create an audit event, start an export of events, and read an export.
List the roles defined at the environment level and the custom roles for an organization.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
User ManagementCreate, read, list, update, and delete users, and authenticate them through password, code, magic auth, and MFA grants.6 | ||||||
| POST | /user_management/users | Create a user in the current environment. | write | — | Current | |
Authorized by the environment API key. WorkOS keys carry no per-endpoint scopes, so any valid key can create users. Acts onuser Permission (capability)None required VersionAvailable since the API’s base version Webhook event user.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /user_management/users/{id} | Get the details of an existing user. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onuser Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /user_management/users | List users, with optional filters for email, organization, and more. | read | — | Current | |
Returns every user in the environment that matches the filter. Authorized by the environment API key. Acts onuser Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /user_management/users/{id} | Update an existing user's attributes, such as name or email-verified status. | write | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onuser Permission (capability)None required VersionAvailable since the API’s base version Webhook event user.updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /user_management/users/{id} | Permanently delete a user. | write | — | Current | |
Deletion is irreversible. Authorized by the environment API key, which has no read-only or scoped variant. Acts onuser Permission (capability)None required VersionAvailable since the API’s base version Webhook event user.deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /user_management/authenticate | Authenticate a user. A grant_type selects the flow: authorization_code, password, refresh_token, magic auth, MFA TOTP, email verification, or organization selection. | write | — | Current | |
One endpoint serves every sign-in flow, distinguished by grant_type. Requires the API key plus the public Client ID. A successful call returns a sealed session and access and refresh tokens. Acts onsession Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Magic AuthCreate a one-time email authentication code and read its details.2 | ||||||
| POST | /user_management/magic_auth | Create a one-time authentication code to send to a user's email address. | write | — | Current | |
The code expires in 10 minutes. Limited to 3 requests per 60 seconds per email address. Authorized by the environment API key. Acts onmagic auth code Permission (capability)None required VersionAvailable since the API’s base version Webhook event magic_auth.createdRate limit3 requests / 60s per email SourceOfficial documentation ↗ | ||||||
| GET | /user_management/magic_auth/{id} | Get the details of an existing Magic Auth code. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onmagic auth code Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Multi-factor authenticationEnroll an authentication factor, challenge it, and verify the challenge.3 | ||||||
| POST | /auth/factors/enroll | Enroll a multi-factor authentication factor, either a time-based one-time password or an SMS factor. | write | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onfactor Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /auth/factors/{id}/challenge | Create a challenge for an enrolled factor, prompting the user to present the second factor. | write | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onchallenge Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /auth/challenges/{id}/verify | Verify a challenge against the code the user supplied. | write | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onchallenge Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
OrganizationsCreate, read, list, update, and delete organizations, the hub that connections, directories, and audit events belong to.5 | ||||||
| POST | /organizations | Create an organization. | write | — | Current | |
An organization is the hub that connections, directories, and audit events belong to. Authorized by the environment API key. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook event organization.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /organizations/{id} | Get the details of an existing organization. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /organizations | List organizations in the current environment. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /organizations/{id} | Update an existing organization. | write | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook event organization.updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /organizations/{id} | Permanently delete an organization. | write | — | Current | |
Deletion is irreversible and limited to 50 requests per 60 seconds per API key. Authorized by the environment API key, which has no read-only variant. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook event organization.deletedRate limit50 requests / 60s per API key SourceOfficial documentation ↗ | ||||||
Organization domainsCreate an organization domain, read it, and verify ownership through a DNS record.3 | ||||||
| POST | /organization_domains | Create an organization domain to be verified. | write | — | Current | |
Returns a verification token to set as a DNS TXT record. Authorized by the environment API key. Acts onorganization domain Permission (capability)None required VersionAvailable since the API’s base version Webhook event organization_domain.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /organization_domains/{id} | Get the details of an existing organization domain. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onorganization domain Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /organization_domains/{id}/verify | Start or re-check verification of an organization domain against its DNS TXT record. | write | — | Current | |
WorkOS periodically checks the TXT record until it is found. Authorized by the environment API key. Acts onorganization domain Permission (capability)None required VersionAvailable since the API’s base version Webhook event organization_domain.verifiedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Single sign-onBuild an SSO authorization URL, exchange the code for a profile, and list, read, or delete connections.5 | ||||||
| GET | /sso/authorize | Generate an OAuth 2.0 authorization URL to start an SSO sign-in. | read | — | Current | |
Built with the public Client ID rather than the secret key. Held to 1,000 requests per 60 seconds per connection. Acts onauthorization url Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limit1,000 requests / 60s per connection SourceOfficial documentation ↗ | ||||||
| POST | /sso/token | Exchange the authorization code returned from an SSO redirect for the user's profile and an access token. | read | — | Current | |
Completes the SSO flow and returns the authenticated user's profile. Authorized by the environment API key. Acts onprofile Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /connections | List SSO connections, with optional filters for organization and connection type. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onconnection Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /connections/{id} | Get the details of an existing SSO connection. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts onconnection Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /connections/{id} | Permanently delete an SSO connection. | write | — | Current | |
Deleting a connection stops single sign-on for that organization. Authorized by the environment API key, which has no read-only variant. Acts onconnection Permission (capability)None required VersionAvailable since the API’s base version Webhook event connection.deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Directory SyncList and read synced directories, their users, and their groups.7 | ||||||
| GET | /directories | List synced directories, with optional filters for organization. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts ondirectory Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /directories/{id} | Get the details of an existing directory. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts ondirectory Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /directories/{id} | Permanently delete a directory connection. | write | — | Current | |
Deleting a directory stops syncing for that organization. Authorized by the environment API key, which has no read-only variant. Acts ondirectory Permission (capability)None required VersionAvailable since the API’s base version Webhook event dsync.deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /directory_users | List the users in a synced directory, including their raw provider attributes. | read | — | Current | |
Returns people who may never have signed into the app. Held to 4 requests per second per directory. Authorized by the environment API key. Acts ondirectory user Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limit4 requests / second per directory SourceOfficial documentation ↗ | ||||||
| GET | /directory_users/{id} | Get the details of a directory user. | read | — | Current | |
Held to 4 requests per second per directory. Authorized by the environment API key. Acts ondirectory user Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limit4 requests / second per directory SourceOfficial documentation ↗ | ||||||
| GET | /directory_groups | List the groups in a synced directory, optionally filtered to a single user's memberships. | read | — | Current | |
The supported way to read group membership, since the groups field on a directory user is deprecated. Authorized by the environment API key. Acts ondirectory group Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /directory_groups/{id} | Get the details of a directory group. | read | — | Current | |
Authorized by the environment API key; no per-endpoint scope exists. Acts ondirectory group Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Audit LogsCreate an audit event, start an export of events, and read an export.3 | ||||||
| POST | /audit_logs/events | Create an audit log event for a notable action taken in the application. | write | — | Current | |
Events are recorded into an append-only trail and cannot be edited or deleted afterward. Authorized by the environment API key. Acts onaudit event Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /audit_logs/exports | Start an asynchronous export of audit log events for a time range. | write | — | Current | |
The export is generated in the background; its readiness is checked with the get export endpoint. Authorized by the environment API key. Acts onaudit export Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /audit_logs/exports/{id} | Get an audit log export, including its state and a download URL when ready. | read | — | Current | |
Returns a downloadable file once the export has finished generating. Authorized by the environment API key. Acts onaudit export Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
RolesList the roles defined at the environment level and the custom roles for an organization.2 | ||||||
| GET | /roles | List the roles defined at the environment level, which apply to all organizations. | read | — | Current | |
Environment roles apply across every organization. Authorized by the environment API key. Acts onrole Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /organizations/{id}/roles | List the roles for an organization, including custom roles defined just for it. | read | — | Current | |
Custom roles are scoped to the single organization. Authorized by the environment API key. Acts onrole Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
WorkOS can notify an app or AI agent when something happens, instead of the app repeatedly asking. WorkOS posts the event payload to a webhook URL that has been registered for the chosen events, such as a directory user being created or an SSO connection being activated.
| Event | What it signals | Triggered by |
|---|---|---|
user.created | Fires when a user is created in User Management. | /user_management/users |
user.updated | Fires when a user's attributes are updated. | /user_management/users/{id} |
user.deleted | Fires when a user is deleted. | /user_management/users/{id} |
magic_auth.created | Fires when a Magic Auth one-time code is created. | /user_management/magic_auth |
organization.created | Fires when an organization is created. | /organizations |
organization.updated | Fires when an organization is updated. | /organizations/{id} |
organization.deleted | Fires when an organization is deleted. | /organizations/{id} |
organization_domain.created | Fires when an organization domain is created. | /organization_domains |
organization_domain.verified | Fires when an organization domain passes verification. | /organization_domains/{id}/verify |
connection.activated | Fires when an SSO connection is activated and ready for sign-in. | In-app only |
connection.deactivated | Fires when an SSO connection is deactivated. | In-app only |
connection.deleted | Fires when an SSO connection is deleted. | /connections/{id} |
dsync.activated | Fires when a directory connection is activated and begins syncing. | In-app only |
dsync.deleted | Fires when a directory connection is deleted. | /directories/{id} |
dsync.user.created | Fires when a user is added to a synced directory. | In-app only |
dsync.user.updated | Fires when a directory user's attributes change. | In-app only |
dsync.user.deleted | Fires when a user is removed from a synced directory. | In-app only |
dsync.group.created | Fires when a group is created in a synced directory. | In-app only |
dsync.group.updated | Fires when a directory group changes. | In-app only |
dsync.group.deleted | Fires when a group is deleted from a synced directory. | In-app only |
authentication.sso_succeeded | Fires when a single sign-on authentication succeeds. | In-app only |
WorkOS limits how fast an app or AI agent can call. A general ceiling applies per IP address, and several areas carry their own tighter limits scoped per connection, per directory, per API key, or per email.
WorkOS applies a general ceiling of 6,000 requests per 60 seconds per IP address across all environments, and several areas carry their own tighter limits on top. SSO authorization is held to 1,000 requests per 60 seconds per connection, listing or reading directory users to 4 requests per second per directory, deleting an organization to 50 requests per 60 seconds per API key, and magic auth and email verification to 3 requests per 60 seconds per email. Going over a limit returns a 429 status. The rate-limits reference does not document response headers reporting the remaining quota or a retry time, so a caller should back off on a 429 rather than rely on a header.
List endpoints use cursor-based pagination. A response includes a list_metadata object with before and after cursors, and the next page is fetched by passing the after value to the before or after query parameter on the next call. A limit parameter sets the page size, defaulting to 10 and capped at 100. Following the returned cursor is the supported way to page, rather than building offsets by hand.
Requests and responses are JSON over HTTPS. Audit log exports are generated asynchronously and returned as a downloadable file rather than inline, and directory and SSO payloads can be large because they carry the full raw attributes a provider sent. Individual list pages are capped at 100 records through the limit parameter.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | unauthorized | Authentication failed. The API key is missing, malformed, or invalid for the environment being called. | Send a valid environment API key as 'Authorization: Bearer sk_...', and confirm it matches the environment, staging or production, the request targets. |
| 404 | not_found | The resource does not exist, or it belongs to a different environment than the API key. | Confirm the id is correct and that the key is for the same environment that holds the resource. |
| 422 | unprocessable_entity | Validation failed. The request was well-formed but a field is missing or invalid. The body holds a code, a message, and an errors array naming the fields. | Read the errors array, correct the named field, and resend. |
| 429 | rate_limit_exceeded | A rate limit was exceeded, either the general 6,000 per 60 seconds per IP or a tighter per-area limit. | Slow down and retry after a short pause. The rate-limits reference does not document a Retry-After header, so use a backoff rather than reading one. |
| 500 | internal_server_error | An unexpected error occurred on the WorkOS side. | Retry with backoff, and contact WorkOS support if it persists. |
WorkOS does not use a dated version number on its API. There is a single, continuously updated API, and notable changes ship through the public changelog rather than a pinned version.
WorkOS ships a single, continuously updated API with no dated version string or version header to pin. Changes are announced through the public changelog, so an integration tracks the changelog for new fields, new webhook events, and deprecations rather than opting into a dated release. Recent dated changes are listed below.
Roles can now be managed at the group level through group role assignments, so permissions can be granted to a whole directory group at once rather than user by user. Released 18 June 2026.
Audit logs can now be streamed to Snowflake, writing each event as a row alongside existing warehouse data. Released 17 June 2026.
IT admins can view and independently rotate the bearer tokens for their SCIM directories from the Admin Portal. Released 3 June 2026.
Additional staging or production environments can be created on demand without requesting setup. Released 27 May 2026.
A new official Rust SDK became available, expanding the set of supported server-side languages. Released 21 May 2026.
Because there is no version to pin, an integration tracks the changelog for changes rather than opting into dated releases.
WorkOS changelog ↗Bollard AI sits between a team's AI agents and WorkOS. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.