AuthKit is a user management platform that provides a set of user authentication and organization security features designed to provide a fast, scalable integration while handling all of the user management complexity that comes with advanced B2B customer needs.
To automatically respond to AuthKit activities, like authentication and changes related to the users, use the corresponding events.
Represents a user identity in your application. A user can sign up in your application directly with a method like password, or they can be JIT-provisioned through an organization’s SSO connection.
Users may belong to organizations as members.
See the events reference documentation for the user events.
const user = { object: 'user', id: 'user_01E4ZCR3C56J083X43JQXF3JK5', email: 'marcelina.davis@example.com', firstName: 'Marcelina', lastName: 'Davis', emailVerified: true, profilePictureUrl: 'https://workoscdn.com/images/v1/123abc', lastSignInAt: '2021-06-25T19:07:33.155Z', externalId: 'f1ffa2b2-c20b-4d39-be5c-212726e11222', metadata: { timezone: 'America/New_York', }, createdAt: '2021-06-25T19:07:33.155Z', updatedAt: '2021-06-25T19:07:33.155Z', };
interface UserGet the details of an existing user.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const user = await workos.userManagement.getUser( 'user_01E4ZCR3C56J083X43JQXF3JK5', );
Get the details of an existing user by an external identifier.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const user = await workos.userManagement.getUserByExternalId( 'f1ffa2b2-c20b-4d39-be5c-212726e11222', );
Get a list of all of your existing users matching the criteria specified.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const users = await workos.userManagement.listUsers(); console.log(users.data);
userManagement .listUsers()Parameters objectReturns objectCreate a new user in the current environment.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const user = await workos.userManagement.createUser({ email: 'marcelina@example.com', password: 'i8uv6g34kd490s', firstName: 'Marcelina', lastName: 'Davis', });
Updates properties of a user. The omitted properties will be left unchanged.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const user = await workos.userManagement.updateUser({ userId: 'user_01EHQ7ZGZ2CZVQJGZ5ZJZ1ZJGZ', firstName: 'Marcelina', lastName: 'Davis', emailVerified: true, externalId: '2fe01467-f7ea-4dd2-8b79-c2b4f56d0191', metadata: { timezone: 'America/New_York', }, });
Permanently deletes a user in the current environment. It cannot be undone.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); await workos.userManagement.deleteUser('user_01F3GZ5ZGZBZVQGZVHJFVXZJGZ');
userManagement .deleteUser()Parameters Represents User identities obtained from external identity providers.
When a user authenticates using an external provider like Google OAuth, information from that provider will be made available as one of the user’s Identities. You can read more about the process in our identity linking guide.
Applications should check the type before making assumptions about the shape of the identity. Currently only OAuth identities are supported, but more types may be added in the future.
{ "idp_id": "4F42ABDE-1E44-4B66-824A-5F733C037A6D", "type": "OAuth", "provider": "MicrosoftOAuth" }
identityGet a list of identities associated with the user. A user can have multiple associated identities after going through identity linking. Currently only OAuth identities are supported. More provider types may be added in the future.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const identities = await workos.userManagement.getUserIdentities( 'user_01E4ZCR3C56J083X43JQXF3JK5', );
userManagement .getUserIdentities()Parameters Returns Generates an OAuth 2.0 authorization URL to authenticate a user with AuthKit or SSO.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const authorizationUrl = workos.userManagement.getAuthorizationUrl({ connectionId: 'conn_01E4ZCR3C56J083X43JQXF3JK5', clientId: 'client_123456789', redirectUri: 'https://your-app.com/callback', state: 'dj1kUXc0dzlXZ1hjUQ==', });
userManagement .getAuthorizationUrl()Parameters objectReturns If you are using AuthKit, set the provider parameter to "authkit", which will generate an authorization URL for your AuthKit domain. AuthKit will take care of detecting the user’s authentication method, such as identifying whether they use Email + Password or Single Sign-On,and direct them to the corresponding login flow.
Otherwise, to generate an authorization URL for a WorkOS SSO connection, you’ll have to specify the user’s connection, organization, or OAuth provider as a parameter. These connection selectors are mutually exclusive, and exactly one must be provided. The generated URL automatically directs the user to their identity provider. Once the user authenticates with their identity provider, WorkOS then issues a redirect to your redirect URI to complete the sign-in flow.
In the OAuth 2.0 protocol, a redirect URI is the location that the user is redirected to once they have successfully authenticated with their identity provider.
When redirecting the user, WorkOS will generate an authorization code and pass it to your redirect URI as a code query parameter, your app will use this code to authenticate the user. Additionally, WorkOS can pass a state parameter back to your application that you may use to encode arbitrary information to restore your application state between the redirects.
https://your-app.com/callback?code=01E2RJ4C05B52KKZ8FSRDAP23J&state=dj1kUXc0dzlXZ1hjUQ==
You can use state to encode parameters like originating URL and query parameters. This is useful in a flow where unauthenticated users are automatically redirected to a login page. After successful sign in, users will be routed to your redirect URI callback route. From there you can extract the originating URL from state and redirect the user to their intended destination.
You’ll need to configure the allowed redirect URIs for your application via the Redirects page in the dashboard. Without a valid redirect URI, your users will be unable to sign in. Make sure that the redirect URI you use as a parameter to get the authorization URL matches one of the redirect URIs you have configured in the dashboard.
Redirect URIs follow stricter requirements in production environments:
HTTPS protocol is required in production environmentsHTTP and localhost are allowed in staging environmentshttp://127.0.0.1 in production environments to support native clients.WorkOS supports using wildcard characters in Redirect URIs. The * symbol can be used as a wildcard for subdomains; however, it must be used in accordance with the following rules in order to properly function.
http://*.com will not work.https://sub.*.example.com will not work.https://*.*.example.com will not work.https://prefix-*-suffix.example.com will work.https://*.example.com will not work with https://sub1.sub2.example.com.https://*.ngrok-free.app will not work.A through Z, and a through z ); digits (0 through 9), hyphens (-), and underscores (_). For example, https://user:secret@foo.example.com will not work with https://*.example.com.The Proof Key for Code Exchange (PKCE) flow is an extension to the OAuth 2.0 Authorization Code flow. It enables public clients, like native apps or single-page apps, to perform the authorization code flow securely. If you are developing a client that makes API calls in public, you’ll need to use this flow.
In this flow, your client generates a code verifier which is a high-entropy cryptographic random string. A code challenge is derived by hashing the code verifier. Instead of using a client secret, provide the code challenge when getting the authorization URL and the code verifier when authenticating a User.
If there is an issue generating an authorization URL, the API will return the original redirect URI with error and error_description query parameters. If provided, the state value will also be included.
https://your-app.com/callback?error=organization_invalid&error_description=No%20connection%20associated%20with%20organization&state=123456789
Possible error codes and the corresponding descriptions are listed below.
| Error code | Description |
|---|---|
access_denied | The identity provider denied user access to the client application or the user denied an OAuth authorization request at the identity provider. |
ambiguous_connection_selector | A connection could not be uniquely identified using the provided connection selector (e.g., organization). This can occur when there are multiple SSO connections under the same organization. If you need multiple SSO connections for an organization, use the connection parameter to identify which connection to use for SSO. |
connection_invalid | There is no connection for the provided ID. |
connection_strategy_invalid | The provider has multiple strategies associated per environment. |
connection_unlinked | The connection associated with the request is unlinked. |
invalid_connection_selector | A valid connection selector query parameter must be provided in order to correctly determine the proper connection to return an authorization URL for. Valid connection selectors are either connection, organization, or provider. |
organization_invalid | There is no organization matching the provided ID. |
oauth_failed | An OAuth authorization request failed for a user. |
server_error | The SSO authentication failed for the user. More detailed errors and steps to resolve are available in the Sessions tab on the connection page in the WorkOS Dashboard. |
Authenticates a user using AuthKit, OAuth or an organization’s SSO connection.
AuthKit handles all authentication methods, however it is conceptually similar to a social login experience. Like OAuth and SSO, AuthKit returns you a code that you can exchange for an authenticated user. See Integrating with AuthKit.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.authenticateWithCode({ clientId: 'client_123456789', code: '01E2RJ4C05B52KKZ8FSRDAP23J', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', });
userManagement .authenticateWithCode()Parameters objectReturns objectAuthenticates a user with email and password.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.authenticateWithPassword({ clientId: 'client_123456789', email: 'marcelina@example.com', password: 'i8uv6g34kd490s', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', });
userManagement .authenticateWithPassword()Parameters objectReturns objectAuthenticates a user by verifying the Magic Auth code sent to the user’s email.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.authenticateWithMagicAuth({ clientId: 'client_123456789', code: '123456', email: 'marcelina.davis@example.com', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', });
userManagement .authenticateWithMagicAuth()Parameters objectReturns objectUse this endpoint to exchange a refresh token for a new access token. Refresh tokens may be rotated after use, so a replacement refresh token is also provided.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_test_123'); const { refreshToken } = await workos.userManagement.authenticateWithRefreshToken({ clientId: 'client_123456789', refreshToken: 'Xw0NsCVXMBf7svAoIoKBmkpEK', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0', });
userManagement .authenticateWithRefreshToken()Parameters objectReturns objectAuthenticates a user with an unverified email and verifies their email address.
A user with an unverified email address won’t be able to authenticate right away. When they attempt to authenticate with their credentials, the API will return an email verification required error that contains a pending authentication token.
If the email setting for email verification is enabled, WorkOS will automatically send a one-time email verification code to the user’s email address. If the email setting is not enabled, retrieve the email verification code to send the email yourself. Use the pending authentication token from the error and the one-time code the user received to authenticate them and to complete the email verification process.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.authenticateWithEmailVerification({ clientId: 'client_123456789', code: '123456', pendingAuthenticationToken: 'ql1AJgNoLN1tb9llaQ8jyC2dn', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', });
userManagement .authenticateWithEmailVerification()Parameters objectReturns objectAuthenticates a user enrolled into MFA using time-based one-time password (TOTP).
Users enrolled into MFA are required to enter a TOTP each time they sign in. When they attempt to authenticate with their credentials, the API will return an MFA challenge error that contains a pending authentication token.
To continue with the authentication flow, challenge one of the factors returned by the MFA challenge error response and present a UI to the user to enter the TOTP code. Then, authenticate the user with the TOTP code, the challenge from the factor, and the pending authentication token from the MFA challenge error.
MFA can be enabled via the Authentication page in the WorkOS dashboard.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.authenticateWithTotp({ clientId: 'client_123456789', code: '123456', pendingAuthenticationToken: 'ql1AJgNoLN1tb9llaQ8jyC2dn', authenticationChallengeId: 'auth_challenge_01FVYZWQTZQ5VB6BC5MPG2EYC5', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', });
userManagement .authenticateWithTotp()Parameters Returns objectAuthenticates a user into an organization they are a member of.
When a user who is a member of multiple organizations attempts to authenticate with their credentials, the API will return an organization selection error that contains a pending authentication token. To continue with the authentication flow, your application should display the list of organizations for the user to choose.
Use the pending authentication token from the error and the organization the user selected in your UI to complete the authentication.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.authenticateWithOrganizationSelection({ clientId: 'client_123456789', organizationId: 'org_01H945H0YD4F97JN9MATX7BYAG', pendingAuthenticationToken: 'ql1AJgNoLN1tb9llaQ8jyC2dn', ipAddress: '192.0.2.1', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', });
userManagement .authenticateWithOrganizationSelection()Parameters Returns objectAuthenticates a user using an AuthKit session cookie. This method does not make a network call, but simply unseals an existing session cookie and decodes the JWT claims from the access token.
import { AuthenticateWithSessionCookieFailureReason, WorkOS, } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { // clientId is required to be passed in to use the authenticateWithSessionCookie method clientId: 'client_123456789', }); const { authenticated, ...restOfAuthenticationResponse } = await workos.userManagement.authenticateWithSessionCookie({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', }); if (authenticated) { // User is authenticated and session data can be utilized const { sessionId, organizationId, role, permissions } = restOfAuthenticationResponse; } else { const { reason } = restOfAuthenticationResponse; // Can use AuthenticateWithSessionCookieFailureReason to handle failure reasons if ( reason === AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED ) { // Redirect the user to the login page } }
userManagement .authenticateWithSessionCookie()Parameters objectReturns objectUnseals the provided session data from a user’s session cookie, authenticates with the existing refresh token, and returns the sealed data for the refreshed session.
import { RefreshAndSealSessionDataFailureReason, WorkOS, } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { // clientId is required to be passed in to use the refreshAndSealSessionData method clientId: 'client_123456789', }); const { authenticated, ...restOfRefreshResponse } = await workos.userManagement.refreshAndSealSessionData({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', }); if (authenticated) { const { sealedSession } = restOfRefreshResponse; // Set the sealed session in a cookie } else { const { reason } = restOfRefreshResponse; // Can use RefreshAndSealSessionDataFailureReason to handle failure reasons if ( reason === RefreshAndSealSessionDataFailureReason.NO_SESSION_COOKIE_PROVIDED ) { // Redirect the user to the login page } }
userManagement .refreshAndSealSessionData()Parameters objectReturns objectThis hosts the public key that is used for verifying access tokens.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_test_123'); const jwksUrl = workos.userManagement.getJwksUrl('client_123456789');
userManagement .getJwksUrl()Parameters Returns The access token that is returned in successful authentication responses is a JWT that can be used to verify that a user has an active session. The JWT is signed by a JWKS which can be retrieved from the WorkOS API.
{ "iss": "https://api.workos.com", "sub": "user_01HBEQKA6K4QJAS93VPE39W1JT", "act": { "sub": "admin@foocorp.com" }, "org_id": "org_01HRDMC6CM357W30QMHMQ96Q0S", "role": "member", "roles": ["member"], "permissions": ["posts:read", "posts:write"], "entitlements": ["audit-logs"], "sid": "session_01HQSXZGF8FHF7A9ZZFCW4387R", "jti": "01HQSXZXPPFPKMDD32RKTFY6PV", "exp": 1709193857, "iat": 1709193557 }
Access Token JWTThe refresh token can be used to obtain a new access token using the authenticate with refresh token endpoint. Refresh tokens may only be used once. Refreshes will succeed as long as the user’s session is still active.
Represents an authenticated user’s connection to your application. A session is created when a user signs in through AuthKit and contains information about the authentication method, device details, and session status.
{ "object": "session", "id": "session_01E4ZCR3C56J083X43JQXF3JK5", "user_id": "user_01E4ZCR3C56J083X43JQXF3JK5", "organization_id": "org_01E4ZCR3C56J083X43JQXF3JK5", "status": "active", "auth_method": "password", "ip_address": "192.168.1.1", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "expires_at": "2025-07-23T15:00:00.000Z", "ended_at": null, "created_at": "2025-07-23T14:00:00.000Z", "updated_at": "2025-07-23T14:00:00.000Z" }
Get a list of all active sessions for a specific user.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const sessions = await workos.userManagement.listSessions( 'user_01E4ZCR3C56J083X43JQXF3JK5', );
userManagement .listSessions()Parameters Returns objectRevoke a session.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); await workos.userManagement.revokeSession({ sessionId: 'session_01E4ZCR3C56J083X43JQXF3JK5', });
userManagement .revokeSession()Parameters objectAfter authenticating and storing the encrypted session as a cookie, retrieving and decrypting the session is made easy via the session helper methods.
Load the session by providing the sealed session and the cookie password.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { clientId: 'client_123456789', }); const session = await workos.userManagement.loadSealedSession({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', });
userManagement .loadSealedSession()Parameters objectReturns objectUnseals the session data and checks if the session is still valid.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { clientId: 'client_123456789', }); const session = await workos.userManagement.loadSealedSession({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', }); const authResponse = await session.authenticate(); if (authResponse.authenticated) { // User is authenticated and session data can be used const { sessionId, organizationId, role, permissions, user } = authResponse; } else { if (authResponse.reason === 'no_session_cookie_provided') { // Redirect the user to the login page } }
session .authenticate()Returns objectRefreshes the user’s session with the refresh token. Passing in a new organization ID will switch the user to that organization.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { clientId: 'client_123456789', }); const session = await workos.userManagement.loadSealedSession({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', }); const refreshResult = await session.refresh(); if (!refreshResult.authenticated) { // Redirect the user to the login page } const { session: userSession, sealedSession, user, organizationId, role, permissions, entitlements, impersonator, } = refreshResult; // Use claims and userSession for further business logic // Set the sealedSession in a cookie
session .refresh()Parameters objectReturns RefreshSessionResponseEnd a user’s session. The user’s browser should be redirected to this URL. Functionally similar to Get logout URL but extracts the session ID automatically from the session data.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { clientId: 'client_123456789', }); const session = await workos.userManagement.loadSealedSession({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', }); const logOutUrl = await session.getLogOutUrl(); // Redirect the user to the log out URL
session .getLogOutUrl()Returns Integrating the authentication API directly requires handling error responses for email verification, MFA challenges, identity linking, and organization selection. One or more of these responses may be returned for an authentication attempt with any authentication method.
Hosted AuthKit handles authentication errors for you and may be a good choice if you prefer a simpler integration.
This error indicates that a user with an unverified email address attempted to authenticate in an environment where email verification is required. It includes a pending authentication token that should be used to complete the authentication.
{ "code": "email_verification_required", "message": "Email ownership must be verified before authentication.", "pending_authentication_token": "YQyCkYfuVw2mI3tzSrk2C1Y7S", "email": "marcelina.davis@example.com", "email_verification_id": "email_verification_01HYGGEB6FYMWQNWF3XDZG7VV3" }
email_verification_requiredWhen this error occurs and the email setting for email verification is enabled, WorkOS will automatically send a one-time email verification code to the user’s email address and issue a pending authentication token. If the email setting is not enabled, retrieve the email verification code to send the email verification email yourself. To complete the authentication process, use the pending authentication token from the error and the one-time code the user received to authenticate them and to verify their email address.
The same applies when a user attempts to authenticate with OAuth or SSO, but there was already an account with a matching unverified email address.
This error indicates that a user who is not enrolled into MFA attempted to authenticate in an environment where MFA is required. It includes a pending authentication token that should be used to authenticate the user once they enroll into MFA.
{ "code": "mfa_enrollment", "message": "The user must enroll in MFA to finish authenticating.", "pending_authentication_token": "YQyCkYfuVw2mI3tzSrk2C1Y7S", "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", "email": "marcelina.davis@example.com", "first_name": "Marcelina", "last_name": "Davis", "email_verified": true, "profile_picture_url": "https://workoscdn.com/images/v1/123abc", "created_at": "2021-06-25T19: 07: 33.155Z", "updated_at": "2021-06-25T19: 07: 33.155Z" } }
mfa_enrollmentWhen this error occurs, you’ll need to present an MFA enrollment UI to the user. Once the user has enrolled, present an MFA challenge UI to the user and authenticate them with their TOTP code and the pending authentication token from this error.
MFA can be enabled via the Authentication page in the WorkOS dashboard.
This error indicates that a user enrolled into MFA attempted to authenticate in an environment where MFA is required. It includes a pending authentication token and a list of factors that the user is enrolled in that should be used to complete the authentication.
{ "code": "mfa_challenge", "message": "The user must complete an MFA challenge to finish authenticating.", "pending_authentication_token": "YQyCkYfuVw2mI3tzSrk2C1Y7S", "authentication_factors": [ { "id": "auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ", "type": "totp" } ], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", "email": "marcelina.davis@example.com", "first_name": "Marcelina", "last_name": "Davis", "email_verified": true, "profile_picture_url": "https://workoscdn.com/images/v1/123abc", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z" } }
mfa_challengeWhen this error occurs, you’ll need to present an MFA challenge UI to the user and authenticate them with their TOTP code, the pending authentication token from this error, and a challenge that corresponds to one of the authentication factors.
MFA can be enabled via the Authentication page in the WorkOS dashboard.
This error indicates that the user is a member of multiple organizations and must select which organization to sign in to. It includes a list of organizations the user is a member of and a pending authentication token that should be used to complete the authentication.
{ "code": "organization_selection_required", "message": "The user must choose an organization to finish their authentication.", "pending_authentication_token": "YQyCkYfuVw2mI3tzSrk2C1Y7S", "organizations": [ { "id": "org_01H93RZAP85YGYZJXYPAZ9QTXF", "name": "Foo Corp" }, { "id": "org_01H93S4E6GB5A8PFNKGTA4S42X", "name": "Bar Corp" } ], "user": { "object": "user", "id": "user_01E4ZCR3C56J083X43JQXF3JK5", "email": "marcelina.davis@example.com", "first_name": "Marcelina", "last_name": "Davis", "email_verified": true, "profile_picture_url": "https://workoscdn.com/images/v1/123abc", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z" } }
organization_selection_requiredWhen this error occurs, you’ll need to display the list of organizations that the user is a member of and authenticate them with the selected organization using the pending authentication token from the error.
This error indicates that a user attempted to authenticate into an organization that requires SSO using a different authentication method. It includes a list of SSO connections that may be used to complete the authentication.
{ "error": "sso_required", "error_description": "User must authenticate using one of the matching connections.", "connection_ids": ["conn_01DRF1T7JN6GXS8KHS0WYWX1YD"] }
sso_requiredWhen this error occurs, you’ll need to use one of the SSO connections from the error to get the authorization URL and redirect the user to that URL to complete the authentication with the organization’s identity provider.
This error indicates that a user attempted to authenticate with an authentication method that is not allowed by the organization that has a domain policy managing this user. It includes all the possible methods the user can use to authenticate.
{ "error": "organization_authentication_methods_required", "error_description": "User must authenticate using one of the methods allowed by the organization.", "sso_connection_ids": ["conn_01DRF1T7JN6GXS8KHS0WYWX1YD"], "auth_methods": { "apple_oauth": false, "github_oauth": false, "google_oauth": true, "magic_auth": false, "microsoft_oauth": false, "password": false } }
organization_authentication_methods_requiredWhen this error occurs, you’ll need to present the user with these options so they can choose which method to continue authentication.
Magic Auth is a passwordless authentication method that allows users to sign in or sign up via a unique, six digit one-time-use code sent to their email inbox. To verify the code, authenticate the user with Magic Auth.
const magicAuth = { object: 'magic_auth', id: 'magic_auth_01E4ZCR3C56J083X43JQXF3JK5', userId: 'user_01HWWYEH2NPT48X82ZT23K5AX4', email: 'marcelina.davis@example.com', expiresAt: '2021-07-01T19:07:33.155Z', code: '123456', createdAt: '2021-06-25T19:07:33.155Z', updatedAt: '2021-06-25T19:07:33.155Z', };
interface MagicAuthGet the details of an existing Magic Auth code that can be used to send an email to a user for authentication.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const magicAuth = await workos.userManagement.getMagicAuth( 'magic_auth_01E4ZCR3C56J083X43JQXF3JK5', );
Creates a one-time authentication code that can be sent to the user’s email address. The code expires in 10 minutes. To verify the code, authenticate the user with Magic Auth.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const magicAuth = await workos.userManagement.createMagicAuth({ email: 'marcelina@example.com', });
Enroll users in multi-factor authentication for an additional layer of security. MFA can be enabled via the Authentication page in the WorkOS dashboard.
Represents an authentication factor.
const factor = { object: 'authentication_factor', id: 'auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ', createdAt: '2022-02-15T15:14:19.392Z', updatedAt: '2022-02-15T15:14:19.392Z', type: 'totp', totp: { issuer: 'Foo Corp', user: 'alan.turing@example.com', qrCode: 'data:image/png;base64,{base64EncodedPng}', secret: 'NAGCCFS3EYRB422HNAKAKY3XDUORMSRF', uri: 'otpauth://totp/FooCorp:alan.turing@example.com?secret=NAGCCFS3EYRB422HNAKAKY3XDUORMSRF&issuer=FooCorp', }, userId: 'user_01FVYZ5QM8N98T9ME5BCB2BBMJ', };
interface FactorRepresents a challenge of an authentication factor.
const challenge = { object: 'authentication_challenge', id: 'auth_challenge_01FVYZWQTZQ5VB6BC5MPG2EYC5', createdAt: '2022-02-15T15:26:53.274Z', updatedAt: '2022-02-15T15:26:53.274Z', expiresAt: '2022-02-15T15:36:53.279Z', authenticationFactorId: 'auth_factor_01FVYZ5QM8N98T9ME5BCB2BBMJ', };
interface ChallengeEnrolls a user in a new authentication factor.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { authenticationFactor, authenticationChallenge } = await workos.userManagement.enrollAuthFactor({ userId: 'user_01E4ZCR3C56J083X43JQXF3JK5', type: 'totp', totpIssuer: 'WorkOS', totpUser: 'bob@example.com', });
userManagement .enrollAuthFactor()Parameters objectReturns objectLists the authentication factors for a user.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const authFactors = await workos.userManagement.listAuthFactors({ userId: 'user_01E4ZCR3C56J083X43JQXF3JK5', }); console.log(authFactors.data);
userManagement .listAuthFactors()Parameters Returns objectEmail verification is a security feature that requires users to verify their email address before they can sign in to your application. It is enabled by default.
Users signing in with Magic Auth, Google OAuth, Apple OAuth, or SSO are automatically verified. For other authentication methods, an email verification flow is required to confirm that the user’s email address belongs to them.
const emailVerification = { object: 'email_verification', id: 'email_verification_01HYGGEB6FYMWQNWF3XDZG7VV3', userId: 'user_01HWWYEH2NPT48X82ZT23K5AX4', email: 'marcelina.davis@example.com', expiresAt: '2021-07-01T19:07:33.155Z', code: '123456', createdAt: '2021-06-25T19:07:33.155Z', updatedAt: '2021-06-25T19:07:33.155Z', };
interface EmailVerificationGet the details of an existing email verification code that can be used to send an email to a user for verification.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const emailVerification = await workos.userManagement.getEmailVerification( 'email_verification_01HYGGEB6FYMWQNWF3XDZG7VV3', );
Create a password reset token for a user and reset the user’s password.
When a user’s password is reset, all of their active sessions are revoked.
const passwordReset = { object: 'password_reset', id: 'password_reset_01HYGDNK5G7FZ4YJFXYXPB5JRW', userId: 'user_01HWWYEH2NPT48X82ZT23K5AX4', email: 'marcelina.davis@example.com', passwordResetToken: 'Z1uX3RbwcIl5fIGJJJCXXisdI', passwordResetUrl: 'https://your-app.com/reset-password?token=Z1uX3RbwcIl5fIGJJJCXXisdI', expiresAt: '2025-07-14T18:00:54.578Z', createdAt: '2025-07-14T17:45:54.578Z', };
interface PasswordResetGet the details of an existing password reset token that can be used to reset a user’s password.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const passwordReset = await workos.userManagement.getPasswordReset( 'password_reset_01HYGDNK5G7FZ4YJFXYXPB5JRW', );
Creates a one-time token that can be used to reset a user’s password.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const passwordReset = await workos.userManagement.createPasswordReset({ email: 'marcelina@example.com', });
Sets a new password using the token query parameter from the link that the user received. Successfully resetting the password will verify a user’s email, if it hasn’t been verified yet.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const { user } = await workos.userManagement.resetPassword({ token: 'stpIJ48IFJt0HhSIqjf8eppe0', newPassword: 'i8uv6g34kd490s', });
userManagement .resetPassword()Parameters Returns objectAn organization membership is a top-level resource that represents a user’s relationship with an organization. A user may be a member of zero, one, or many organizations.
See the events reference documentation for the organization membership events.
const organizationMembership = { object: 'organization_membership', id: 'om_01E4ZCR3C56J083X43JQXF3JK5', userId: 'user_01E4ZCR3C5A4QZ2Z2JQXGKZJ9E', organizationId: 'org_01E4ZCR3C56J083X43JQXF3JK5', organizationName: 'Foo Corp', role: { slug: 'admin', }, roles: [ { slug: 'admin', }, ], status: 'active', createdAt: '2021-06-25T19:07:33.155Z', updatedAt: '2021-06-25T19:07:33.155Z', };
interface OrganizationMembershipGet the details of an existing organization membership.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const organizationMembership = await workos.userManagement.getOrganizationMembership( 'om_01E4ZCR3C56J083X43JQXF3JK5', );
Get a list of all organization memberships matching the criteria specified. At least one of user_id or organization_id must be provided. By default only active memberships are returned. Use the statuses parameter to filter by other statuses.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const organizationMemberships = await workos.userManagement.listOrganizationMemberships({ userId: 'user_01E4ZCR3C5A4QZ2Z2JQXGKZJ9E', }); console.log(organizationMemberships.data);
userManagement .listOrganizationMemberships()Parameters objectReturns objectCreates a new active organization membership for the given organization and user.
Calling this API with an organization and user that match an inactive organization membership will activate the membership with the specified role(s).
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const organizationMembership = await workos.userManagement.createOrganizationMembership({ organizationId: 'org_01E4ZCR3C56J083X43JQXF3JK5', userId: 'user_01E4ZCR3C5A4QZ2Z2JQXGKZJ9E', roleSlug: 'admin', });
Update the details of an existing organization membership.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const organizationMembership = await workos.userManagement.updateOrganizationMembership( 'om_01E4ZCR3C56J083X43JQXF3JK5', { roleSlug: 'admin', }, );
Permanently deletes an existing organization membership. It cannot be undone.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); await workos.userManagement.deleteOrganizationMembership( 'om_01E4ZCR3C56J083X43JQXF3JK5', );
userManagement .deleteOrganizationMembership()Parameters Deactivates an active organization membership. Emits an organization_membership.updated event upon successful deactivation.
inactive membership is a no-op and does not emit an event.pending membership returns an error. This membership should be deleted instead.See the membership management documentation for additional details.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const organizationMembership = await workos.userManagement.deactivateOrganizationMembership( 'om_01E4ZCR3C56J083X43JQXF3JK5', );
Reactivates an inactive organization membership, retaining the pre-existing role(s). Emits an organization_membership.updated event upon successful reactivation.
active membership is a no-op and does not emit an event.pending membership returns an error. The user needs to accept the invitation instead.See the membership management documentation for additional details.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const organizationMembership = await workos.userManagement.reactivateOrganizationMembership( 'om_01E4ZCR3C56J083X43JQXF3JK5', );
An email invitation allows the recipient to sign up for your app and join a specific organization. When an invitation is accepted, a user and a corresponding organization membership are created.
Users may be invited to your app without joining an organization, or they may be invited to join an organization if they already have an account. Invitations may be also issued on behalf of another user. In this case, the invitation email will mention the name of the user who invited the recipient.
const invitation = { object: 'invitation', id: 'invitation_01E4ZCR3C56J083X43JQXF3JK5', email: 'marcelina.davis@example.com', state: 'pending', acceptedAt: null, revokedAt: null, expiresAt: '2021-07-01T19:07:33.155Z', token: 'Z1uX3RbwcIl5fIGJJJCXXisdI', acceptInvitationUrl: 'https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI', organizationId: 'org_01E4ZCR3C56J083X43JQXF3JK5', inviterUserId: 'user_01HYGBX8ZGD19949T3BM4FW1C3', createdAt: '2021-06-25T19:07:33.155Z', updatedAt: '2021-06-25T19:07:33.155Z', };
interface InvitationGet the details of an existing invitation.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const invitation = await workos.userManagement.getInvitation( 'invitation_01EHZNVPK3SFK441A1RGBFSHRT', );
Retrieve an existing invitation using the token.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const invitation = await workos.userManagement.findInvitationByToken( 'Z1uX3RbwcIl5fIGJJJCXXisdI', );
Get a list of all of invitations matching the criteria specified.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const invitation = await workos.userManagement.listInvitations({ organizationId: 'org_123456789', }); console.log(invitation.data);
userManagement .listInvitations()Parameters Returns objectSends an invitation email to the recipient.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const invitation = await workos.userManagement.sendInvitation({ email: 'marcelina@example.com', });
Resends an invitation email to the recipient. The invitation must be in a pending state.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const invitation = await workos.userManagement.resendInvitation( 'invitation_01E4ZCR3C56J083X43JQXF3JK5', ); console.log(invitation.data);
Accepts an invitation and, if linked to an organization, activates the user’s membership in that organization.
In most cases, use existing authentication methods like authenticateWithCode, which also accept an invitation token. These methods offer the same functionality (invitation acceptance and membership activation) while also signing the user in.
This method is useful for apps requiring a highly customized invitation flow, as it focuses solely on handling invitations without authentication. It’s also helpful when users can be invited to multiple organizations and need a way to accept invitations after signing in.
Your application should verify that the invitation is intended for the user accepting it. For example, by fetching the invitation using the find-by-token endpoint and ensuring the email matches the email address of the accepting user.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789', { clientId: 'client_123456789', }); const invitation = await workos.userManagement.acceptInvitation( 'invitation_01E4ZCR3C56J083X43JQXF3JK5', );
Revokes an existing invitation.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const invitation = await workos.userManagement.revokeInvitation( 'invitation_01E4ZCR3C56J083X43JQXF3JK5', );
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_test_123'); const logoutUrl = workos.userManagement.getLogoutUrl({ sessionId: 'session_01HQAG1HENBZMAZD82YRXDFC0B', returnTo: 'https://your-app.com/signed-out', });
userManagement .getLogoutUrl()Parameters objectReturns Generates the logout URL by extracting the session ID from the session cookie. Use this over getLogoutUrl if you don’t have a saved reference to the session ID and you’d like the SDK to handle extracting the session ID from the cookie for you.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_test_123'); const logoutUrl = workos.userManagement.getLogoutUrlFromSessionCookie({ sessionData: 'sealed_session_cookie_data', cookiePassword: 'password_previously_used_to_seal_session_cookie', });
userManagement .getLogoutUrlFromSessionCookie()Parameters objectReturns CLI Auth enables command-line applications to authenticate users through the web using the OAuth 2.0 Device Authorization Flow.
The CLI Auth flow involves two main endpoints:
Read more about CLI Auth here.
Initiates the CLI Auth flow by requesting a device code and verification URLs. This endpoint implements the OAuth 2.0 Device Authorization Flow (RFC 8628) and is designed for command-line applications or other devices with limited input capabilities.
curl -X POST 'https://api.workos.com/user_management/authorize/device' \ -d client_id=client_123456789
POST/user_management /authorize /deviceParameters Returns Exchanges a device code for access and refresh tokens as part of the CLI Auth flow. This endpoint should be polled repeatedly until the user authorizes the request, declines it, or the device code expires.
curl -X POST 'https://api.workos.com/user_management/authenticate' \ -d 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \ -d 'device_code=ETaHpDNhfxu0HyLhp6b8HGSh26NzYJSKw3TT6aS7HKKBhTyTD0zAW6ApTTolug0b' \ -d 'client_id=client_123456789'
POST/user_management /authenticateParameters Returns When polling the device code endpoint, you may receive various error responses before the user completes authorization or if authorization fails. These errors help your application understand the current state and take appropriate action.
Possible error codes and the corresponding descriptions are listed below.
| Error code | Description |
|---|---|
authorization_pending | The authorization request is still pending as the user hasn’t yet completed the user interaction flow. Continue polling at the specified interval. |
slow_down | The client is polling too frequently and should slow down. Increase your polling interval by at least 5 seconds and continue polling. |
access_denied | The user declined the authorization request. Stop polling and inform the user that authorization was denied. |
expired_token | The device code has expired (typically after 5 minutes). Stop polling and restart the authorization flow if needed. |
invalid_request | The request is missing a required parameter or includes an invalid parameter value. Check that grant_type, device_code, and client_id are provided and correct. |
invalid_client | Client authentication failed (e.g., unknown client, client authentication not included, or unsupported authentication method). |
invalid_grant | The provided device code is invalid, malformed, or has already been used. |
unsupported_grant_type | The grant type is not supported. Ensure you’re using urn:ietf:params:oauth:grant-type:device_code. |
All error responses are returned with a 400 status code and follow the OAuth 2.0 error response format. For example:
{ "error": "authorization_pending", "error_description": "The authorization request is still pending as the user hasn't yet completed the user interaction flow." }
API keys provide a secure way for your application’s users to authenticate with your API. Organization admins create API keys through the API Keys Widget, and your application can validate these keys to authenticate API requests.
Read more about API keys in AuthKit.
{ "object": "api_key", "id": "api_key_01E4ZCR3C56J083X43JQXF3JK5", "owner": { "type": "organization", "id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY" }, "name": "Production API Key", "obfuscated_value": "sk_...3456", "permissions": ["posts:read", "posts:write"], "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "last_used_at": "2021-06-25T19:07:33.155Z" }
Validates an API key and returns its associated metadata if the key is valid. Your application’s API uses this endpoint to authenticate incoming requests that include an API key.
The endpoint returns the complete API key object when validation succeeds, allowing you to access the key’s permissions and owner information for authorization purposes. If the key is invalid, the endpoint returns null for the api_key field.
import { WorkOS } from '@workos-inc/node'; const workos = new WorkOS('sk_example_123456789'); const result = await workos.apiKeys.validateApiKey({ value: 'sk_abcdefghijklmnop123456', });