B2B API Reference

Explore the details of the Stytch B2B API. Our B2B authentication API is organized around REST principles and has resource-oriented URLs, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

All B2B API resources are scoped to the Project of the API keys you provide.


Organization object


Fields


organization_id string

organization_slug string

organization_logo_url string

organization_name string

trusted_metadata object

email_invites string

email_jit_provisioning string

email_allowed_domains array[strings]

sso_default_connection_id string

sso_jit_provisioning string

sso_active_connections array[objects]

sso_jit_provisioning_allowed_connections array[strings]

auth_methods string

allowed_auth_methods array[strings]

OBJECT

200
{
  "organization": {
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "organization_name": "Example Org Inc.",
    "organization_slug": "example-org",
    "organization_logo_url": "",
    "email_allowed_domains": ["stytch.com"],
    "email_invites": "ALL_ALLOWED",
    "email_jit_provisioning": "RESTRICTED",
    "sso_default_connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
    "sso_jit_provisioning": "ALL_ALLOWED",
    "sso_jit_provisioning_allowed_connections": ["saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9"],
    "sso_active_connections": [
      {
        "connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
        "display_name": "SSO test connection with IdP"
      }
    ],
    "auth_methods": "ALL_ALLOWED",
    "allowed_auth_methods": [],
    "trusted_metadata": {
      "address": {
        "street": "1 Telegraph Hill Blvd",
        "city": "San Francisco",
        "state": "CA",
        "zip_code": "94133"
      },
      "billing_tier": "free"
    }
  }
}

Create organization

POSThttps://test.stytch.com/v1/b2b/organizations

Creates an Organization. An organization_name and a unique organization_slug are required.

By default, email_invites and sso_jit_provisioning will be set to ALL_ALLOWED if no Organization authentication settings are explicitly defined in the request.

*See the Organization authentication settings resource to learn more about fields like email_jit_provisioning, email_invites, sso_jit_provisioning, etc., and their behaviors.


Body parameters


organization_name* string

organization_slug* string

organization_logo_url string

trusted_metadata object

email_jit_provisioning string

email_invites string

email_allowed_domains array[strings]

sso_jit_provisioning string

auth_methods string

allowed_auth_methods array[strings]

Response fields


request_id string

status_code int

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/organizations \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"organization_name": "Example Org Inc.",
		"organization_slug": "example-org"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "organization": {
	"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
	"organization_logo_url": "",
	"organization_name": "Example Org Inc.",
	"organization_slug": "example-org",
	"email_allowed_domains": [],
	"email_invites": "ALL_ALLOWED",
	"email_jit_provisioning": "NOT_ALLOWED",
	"sso_default_connection_id": null,
	"sso_jit_provisioning": "NOT_ALLOWED",
	"sso_jit_provisioning_allowed_connections": [],
	"sso_active_connections": [],
	"trusted_metadata": {},
	"auth_methods": "ALL_ALLOWED",
	"allowed_auth_methods": []
  }
}

Get an Organization

GEThttps://test.stytch.com/v1/b2b/organizations/{organization_id}

Returns an Organization specified by organization_id.


Path parameters


organization_id* string

Response fields


request_id string

status_code int

organization object

REQUEST

Node
curl --request GET \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "organization": {
	"email_allowed_domains": [],
	"email_invites": "ALL_ALLOWED",
	"email_jit_provisioning": "NOT_ALLOWED",
	"organization_id": "organization-test-staging-12345",
	"organization_logo_url": "",
	"organization_name": "Example Org Inc",
	"organization_slug": "exampleorg",
	"sso_default_connection_id": null,
	"sso_jit_provisioning": "NOT_ALLOWED",
	"sso_jit_provisioning_allowed_connections": [],
	"sso_active_connections": [],
	"trusted_metadata": {}
  }
}

Update an Organization

PUThttps://test.stytch.com/v1/b2b/organizations/{organization_id}

Updates an Organization specified by organization_id. An Organization must always have at least one auth setting set to either RESTRICTED or ALL_ALLOWED in order to provision new Members. test

*See the Organization authentication settings resource to learn more about fields like email_jit_provisioning, email_invites, sso_jit_provisioning, etc., and their behaviors.


Path parameters


organization_id* string

Body parameters


organization_name string

organization_slug string

organization_logo_url string

trusted_metadata object

email_jit_provisioning string

email_invites string

email_allowed_domains array[strings]

sso_default_connection_id string

sso_jit_provisioning string

sso_jit_provisioning_allowed_connections array[strings]

auth_methods string

allowed_auth_methods array[strings]

Response fields


request_id string

status_code int

organization object

REQUEST

Node
curl --request PUT \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"organization_name": "Example Org Inc.",
		"email_jit_provisioning": "ALL_ALLOWED"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "organization": {
	"email_allowed_domains": [],
	"email_invites": "ALL_ALLOWED",
	"email_jit_provisioning": "ALL_ALLOWED",
	"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
	"organization_logo_url": "",
	"organization_name": "Example Org Inc.",
	"organization_slug": "example-org",
	"sso_default_connection_id": null,
	"sso_jit_provisioning": "ALL_ALLOWED",
	"sso_jit_provisioning_allowed_connections": [],
	"sso_active_connections": [],
	"trusted_metadata": {},
	"auth_methods": "ALL_ALLOWED",
    "allowed_auth_methods": []
  }
}

Search for Organizations

POSThttps://test.stytch.com/v1/b2b/organizations/search

Search for Organizations. If you send a request with no body params, no filtering will be applied and the endpoint will return all Organizations. All fuzzy search filters require a minimum of three characters.


Body parameters


cursor string

limit int

query object

Response fields


request_id string

status_code int

results_metadata object

organization_objects array[objects]

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/organizations/search \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"limit": 200,
		"query": {
			"operator": "OR",
			"operands": [
				{
					"filter_name": "allowed_domains",
					"filter_value": ["stytch.com"]
				},
				{
					"filter_name": "organization_name_fuzzy",
					"filter_value": "example org"
				}
			]
		}
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "results_metadata": {
		"next_cursor": null,
		"total": 5
	},
  "organizations": [
		...
  ]
}

Delete an Organization

DELETEhttps://test.stytch.com/v1/b2b/organizations/{organization_id}

Deletes an Organization specified by organization_id. All Members of the Organization will also be deleted.


Path parameters


organization_id* string

Response fields


request_id string

status_code int

organization_id string

REQUEST

Node
curl --request DELETE \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931"
}

Member object


Fields


organization_id string

member_id string

email_address string

status string

name string

trusted_metadata object

untrusted_metadata object

sso_registrations array[objects]

member_password_id string

is_breakglass boolean

OBJECT

200
{
  "member": {
    "email_address": "sandbox@stytch.com",
    "member_password_id": "member-password-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
    "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
    "name": "Test Member",
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "status": "active",
    "is_breakglass": false,
    "trusted_metadata": {
      "role": "admin",
      "teams": ["tech", "support"]
    },
    "untrusted_metadata": {
      "job_title": "Business Analyst",
      "preferred_locales": ["en", "es"]
    },
    "sso_registrations": [{
      "connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
      "external_id": "sandbox@stytch.com",
      "registration_id": "saml-member-registration-test-9a6d293d-d8b3-42e8-abb4-220cc2060e93"
      "sso_attributes": {
        "email": ["sandbox@stytch.com"],
        "first_name": ["Test"],
        "last_name": ["Member"]
      }
    }],
  }
}

Create a Member

POSThttps://test.stytch.com/v1/b2b/organizations/{organization_id}/members

Creates a Member. An organization_id and email_address are required.


Path parameters


organization_id* string

Body parameters


email_address* string

name string

trusted_metadata object

untrusted_metadata object

create_member_as_pending boolean

is_breakglass boolean

Response fields


status_code int

request_id string

member_id string

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/members \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"email_address": "sandbox@stytch.com",
		"name": "Carla Philips",
		"trusted_metadata": {
			"role": "admin"
		},
		"untrusted_metadata": {
			"nickname": "Carly",
			"preferred_locales": ["en", "es"]
		}
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member": {...},
  "organization": {...}
}

Get a Member

GEThttps://test.stytch.com/v1/b2b/organizations/{organization_id}/member

Get a Member by member_id or email_address.


Path parameters


organization_id* string

Query parameters


member_id string

email_address string

Response fields


request_id string

status_code int

member_id string

organization object

member object

REQUEST

Node
curl --request GET \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/member?member_id=member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member": {...},
  "organization": {...}
}

Update a Member

PUThttps://test.stytch.com/v1/b2b/organizations/{organization_id}/members/{member_id}

Updates a Member specified by organization_id and member_id.


Path parameters


organization_id* string

member_id* string

Body parameters


name string

trusted_metadata object

untrusted_metadata object

is_breakglass boolean

Response fields


status_code int

request_id string

member_id string

member object

organization object

REQUEST

Node
curl --request PUT \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/members/member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"name": "Carla Philips",
		"trusted_metadata": {
			"role": "reader"
		},
		"untrusted_metadata": {
			"nickname": "Carly",
			"preferred_locales": ["en", "pt-br"]
		}
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member": {...},
  "organization": {...}
}

Search for Members

POSThttps://test.stytch.com/v1/b2b/organizations/members/search

Search for Members within specified Organizations. An array with at least one organization_id is required. Submitting an empty query returns all Members within the specified Organizations.

*All fuzzy search filters require a minimum of three characters.


Body parameters


organization_ids* array[strings]

cursor string

limit int

query object

Response fields


request_id string

status_code int

results_metadata object

members array[objects]

organizations map<string, object>

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/organizations/members/search \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"organization_ids": ["organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931"],
		"limit": 200,
		"query": {
			"operator": "OR",
			"operands": [
				{
					"filter_name": "member_emails",
					"filter_value": ["testmember@stytch.com"]
				},
				{
					"filter_name": "status",
					"filter_value": "active"
				}
			]
		}
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "results_metadata": {
		"next_cursor": null,
		"total": 5
	},
  "members": [
    ...
  ]
  "organizations": <
    ...
  >
}

Delete a Member

DELETEhttps://test.stytch.com/v1/b2b/organizations/{organization_id}/members/{member_id}

Deletes a Member specified by organization_id and member_id.


Path parameters


organization_id* string

member_id* string

Response fields


request_id string

status_code int

member_id string

REQUEST

Node
curl --request DELETE \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/members/member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f"
}

Send login or signup email

POSThttps://test.stytch.com/v1/b2b/magic_links/email/login_or_signup

Send either a login or signup magic link to a Member. A new, pending, or invited Member will receive a signup Email Magic Link. Members will have a pending status until they successfully authenticate. An active Member will receive a login Email Magic Link.


Body parameters


organization_id* string

email_address* string

login_redirect_url string

signup_redirect_url string

pkce_code_challenge string

login_template_id string

signup_template_id string

locale string

Response fields


request_id string

status_code int

member_id string

member_created boolean

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/magic_links/email/login_or_signup \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"email_address": "sandbox@stytch.com"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member_created": true,
  "member": {...},
  "organization": {...}
}

Send invite email

POSThttps://test.stytch.com/v1/b2b/magic_links/email/invite

Send an invite email to a new Member to join an Organization. The Member will be created with an invited status until they successfully authenticate. Sending invites to pending Members will update their status to invited. Sending invites to already active Members will return an error.


Body parameters


organization_id* string

email_address* string

invite_redirect_url string

invite_template_id string

invited_by_member_id string

name string

trusted_metadata object

untrusted_metadata object

locale string

Response fields


request_id string

status_code int

member_id string

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/magic_links/email/invite \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"email_address": "sandbox@stytch.com"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f"
  "member": {...},
  "organization": {...}
}

Send Discovery Email

POSThttps://test.stytch.com/v1/b2b/magic_links/email/discovery/send

Send a discovery magic link to an email address.


Body parameters


email_address* string

discovery_redirect_url string

pkce_code_challenge string

login_template_id string

locale string

Response fields


request_id string

status_code int

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/magic_links/email/discovery/send \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"email_address": "sandbox@stytch.com"
	}'

RESPONSE

200
{
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200
}

OAuth Overview (coming soon)

OAuth is a popular authentication framework that delegates authentication to an external identity provider (often shortened to IdP) like Google or Microsoft. A user relies on their membership from that provider to sign in instead of creating another password, and developers can enrich their users' experiences with the information shared by the providers. While OAuth has many benefits, developers need to understand the OAuth framework well to implement it securely. Stytch's OAuth product simplifies the process by abstracting the implementation details of OAuth for developers. The steps for an OAuth flow are simple:

  1. Add the required client ID and client secret from the IdP to the Stytch developer dashboard.
  2. Embed the client side OAuth URL (i.e Google) for that IdP that the user will click.
  3. Add an endpoint in the backend that calls Authenticate OAuth to finish the flow.

Start Google OAuth flow (coming soon)

GEThttps://test.stytch.com/v1/b2b/public/oauth/google/start

A client-side endpoint (which can only be queried from the user's browser) that starts the Google OAuth flow. This endpoint generates the Google OAuth URL with all required fields and redirects the user to that URL. The user authenticates with Google before getting redirected back to Stytch. After verifying the request, Stytch redirects the user back to the login_redirect_url or signup_redirect_url URL provided.

One of organization_id or organization_slug is required to specify which organization the user is trying to access. If the organization that the user is trying to access is not yet known, use the Google OAuth Discovery endpoint instead.

Scopes

By default our Google OAuth integration requests the open_id, email, and profile scopes. You may add any additional Google API scopes (see here for a complete list) as a space separated list in the custom_scopes query parameter.

Next steps

Once the user successfully authenticates with Google, they'll be redirected to the redirect URL that you provided at the start of the OAuth flow with a Stytch OAuth token. Collect the token from the URL query parameters, and call Authenticate OAuth Token to complete authentication.


Query parameters


public_token* string

organization_id string

organization_slug string

login_redirect_url string

signup_redirect_url string

custom_scopes string

pkce_code_challenge string

Response fields


status_code int

request_id string

redirect_url string

REQUEST

Node
curl --request GET \
    --url 'https://test.stytch.com/v1/b2b/public/oauth/google/start?public_token=PUBLIC_TOKEN&organization_id=organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931'

RESPONSE

302
{
    "status_code": 302,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "redirect_url": "https://accounts.google.com/o/oauth2/v2/auth/identifier?client_id=example-client-id&redirect_uri=https%3A%2F%2Fstytch.com%2Fv1%2Foauth%2Foauth-callback-test-d868b16b-3ecd-49ac-7fc6-e3d1051c5d65&response_type=code&scope=openid%20email%20profile&access_type=offline&state=example-state",
}

Start Microsoft OAuth flow (coming soon)

GEThttps://test.stytch.com/v1/b2b/public/oauth/microsoft/start

A client-side endpoint (which can only be queried from the user's browser) that starts the Microsoft OAuth flow. This endpoint generates the Microsoft OAuth URL with all required fields and redirects the user to that URL. The user authenticates with Microsoft Account before getting redirected back to Stytch. After verifying the request, Stytch redirects the user back to the login_redirect_url or signup_redirect_url URL provided.

One of organization_id or organization_slug is required to specify which organization the user is trying to access. If the organization that the user is trying to access is not yet known, use the Microsoft OAuth Discovery endpoint instead.

NOTE: The Stytch B2B product limits access to only verified Azure Active Directory accounts. Personal accounts, including personal Xbox Live, Skype, or Outlook accounts, are not allowed. Accounts managed by Azure Active Directory B2C are not allowed. By default, Stytch will deduplicate users by treating their UserPrincipalName as an email address. Reach out to support@stytch.com if you would like finer control over this behavior.

Scopes

By default our Microsoft OAuth integration includes open_id, email, User.Read, and profile scopes. You may add any additional Microsoft API scopes (see here for a complete list) as a space separated list in the custom_scopes query parameter of /oauth/microsoft/start.

Next steps

Once the user successfully authenticates with Microsoft, they'll be redirected to the redirect URL that you provided at the start of the OAuth flow with a Stytch OAuth token. Collect the token from the URL query parameters, and call Authenticate OAuth Token to complete authentication.


Query parameters


public_token* string

organization_id string

organization_slug string

login_redirect_url string

signup_redirect_url string

custom_scopes string

pkce_code_challenge string

Response fields


status_code int

request_id string

redirect_url string

REQUEST

Node
curl --request GET \
    --url 'https://test.stytch.com/v1/b2b/public/oauth/microsoft/start?public_token=PUBLIC_TOKEN&organization_id=organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931'

RESPONSE

302
{
    "status_code": 302,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "redirect_url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?access_type=offline&client_id=example-client-id&redirect_uri=https%3A%2F%2Fstytch.com%2Fv1%2Foauth%2Foauth-callback-test-d868b16b-3ecd-49ac-7fc6-e3d1051c5d65&response_type=code&scope=openid+email+profile&state=example-state",
}

Authenticate OAuth (coming soon)

POSThttps://test.stytch.com/v1/b2b/oauth/authenticate

Authenticate a Member given a token. This endpoint verifies that the member completed the OAuth flow by verifying that the token is valid and hasn't expired.


Body parameters


oauth_token* string

session_custom_claims map<string, any>

session_duration_minutes int

session_jwt string

session_token string

pkce_code_verifier string

Response fields


status_code int

request_id string

member_id string

member object

organization_id string

organization object

provider_values object

member_session object

session_token string

session_jwt string

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/oauth/authenticate \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
    "oauth_token": "hdPVZHHX0UoRa7hJTuuPHi1vlddffSnoweRbVFf5-H8g",
    "session_duration_minutes": 60
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
  "session_jwt": "example_jwt",
  "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
  "member_session": {...},
  "member": {...},
  "organization": {...},
  "provider_values": {
    "access_token": "example-access-token",
    "refresh_token": "example-refresh-token",
    "id_token": "example-id-token",
    "scopes": ["example scope"]
  },
}

Start Google Discovery OAuth flow (coming soon)

GEThttps://test.stytch.com/v1/b2b/public/discovery/oauth/google/start

A client-side endpoint (can only be queried from the user's browser) that starts the Google OAuth flow. This endpoint generates the Google OAuth URL with all required fields and redirects the user to that URL. The user authenticates with Google before getting redirected back to Stytch. After verifying the request, Stytch redirects the user back to the discovery_redirect_url provided.

Scopes

By default our Google OAuth integration requests the open_id, email, and profile scopes. You may add any additional Google API scopes (see here for a complete list) as a space separated list in the custom_scopes query parameter.

Next steps

Once the user successfully authenticates with Google, they'll be redirected to the redirect URL that you provided at the start of the OAuth flow with a Stytch OAuth token. Collect the token from the URL query parameters, and call Authenticate Discovery OAuth to exchange it for an Intermediate Session Token. Intermediate Session Tokens can be used for various Discovery login flows and are valid for 10 minutes.


Query parameters


public_token* string

discovery_redirect_url string

custom_scopes string

pkce_code_challenge string

Response fields


status_code int

request_id string

redirect_url string

REQUEST

Node
curl --request GET \
    --url 'https://test.stytch.com/v1/b2b/public/discovery/oauth/google/start?public_token=PUBLIC_TOKEN'

RESPONSE

302
{
    "status_code": 302,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "redirect_url": "https://accounts.google.com/o/oauth2/v2/auth/identifier?client_id=example-client-id&redirect_uri=https%3A%2F%2Fstytch.com%2Fv1%2Foauth%2Foauth-callback-test-d868b16b-3ecd-49ac-7fc6-e3d1051c5d65&response_type=code&scope=openid%20email%20profile&access_type=offline&state=example-state",
}

Start Microsoft Discovery OAuth flow (coming soon)

GEThttps://test.stytch.com/v1/b2b/public/discovery/oauth/microsoft/start

A client-side endpoint (can only be queried from the user's browser) that starts the Microsoft OAuth flow. This endpoint generates the Microsoft OAuth URL with all required fields and redirects the user to that URL. The user authenticates with Microsoft before getting redirected back to Stytch. After verifying the request, Stytch redirects the user back to the discovery_redirect_url provided.

Scopes

By default our Microsoft OAuth integration includes open_id, email, User.Read, and profile scopes. You may add any additional Microsoft API scopes (see here for a complete list) as a space separated list in the custom_scopes query parameter of /oauth/microsoft/start.

Next steps

Once the user successfully authenticates with Microsoft, they'll be redirected to the redirect URL that you provided at the start of the OAuth flow with a Stytch OAuth token. Collect the token from the URL query parameters, and call Authenticate Discovery OAuth to exchange it for an Intermediate Session Token. Intermediate Session Tokens can be used for various Discovery login flows and are valid for 10 minutes.


Query parameters


public_token* string

discovery_redirect_url string

custom_scopes string

pkce_code_challenge string

Response fields


status_code int

request_id string

redirect_url string

REQUEST

Node
curl --request GET \
    --url 'https://test.stytch.com/v1/b2b/public/discovery/oauth/microsoft/start?public_token=PUBLIC_TOKEN'

RESPONSE

302
{
    "status_code": 302,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "redirect_url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?access_type=offline&client_id=example-client-id&redirect_uri=https%3A%2F%2Fstytch.com%2Fv1%2Foauth%2Foauth-callback-test-d868b16b-3ecd-49ac-7fc6-e3d1051c5d65&response_type=code&scope=openid+email+profile+User.Read&state=example-state",
}

Authenticate Discovery OAuth (coming soon)

POSThttps://test.stytch.com/v1/b2b/oauth/discovery/authenticate

Authenticates the discovery OAuth token and exchanges it for an Intermediate Session Token. Intermediate Session Tokens can be used for various Discovery login flows and are valid for 10 minutes.


Body parameters


discovery_oauth_token* string

pkce_code_verifier string

Response fields


request_id string

status_code int

intermediate_session_token string

email_address string

discovered_organizations array

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/oauth/discovery/authenticate \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
    "discovery_oauth_token": "hdPVZHHX0UoRa7hJTuuPHi1vlddffSnoweRbVFf5-H8g",
    "session_duration_minutes": 60
	}'

RESPONSE

200
{
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200,
	"intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
	"email_address": "sandbox@stytch.com",
	"discovered_organizations": [{...}, {...}]
}

Session Management overview

Stytch Member Sessions are identified by a session_token or session_jwt that should be stored client-side (usually a browser cookie) and authenticated on each request. To start a session, call one of the authenticate endpoints (e.g. Email Magic Links or SSO) and add the session_duration_minutes parameter to set the lifetime of the session. If the session_duration_minutes parameter is not specified, a Stytch session will be created with a 60 minute duration. Look for session_token and session_jwt in the response.

Session object


Fields


member_session_id string

member_id string

started_at timestamp

last_accessed_at timestamp

expires_at timestamp

authentication_factors array[objects]

custom_claims array[objects]

OBJECT

200
{
  "member_session": {
    "member_session_id": "session-test-fe6c042b-6286-479f-8a4f-b046a6c46509",
    "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
    "started_at": "2023-01-09T07:41:52Z",
    "last_accessed_at": "2023-01-09T07:41:52Z",
    "expires_at": "2021-08-10T07:41:52Z",
    "authentication_factors": [
      {
        "delivery_method": "email",
        "email_factor": {
          "email_address": "sandbox@stytch.com",
          "email_id": "email-test-81bf03a8-86e1-4d95-bd44-bb3495224953"
        },
        "last_authenticated_at": "2023-01-09T07:41:52Z",
        "type": "magic_link"
      }
    ],
    "custom_claims": {
      "claim1": "value1",
      "claim2": "value2",
    },
  }
}

Get JWKS

GEThttps://test.stytch.com/v1/b2b/sessions/jwks/{project_id}

Get the JSON Web Key Set (JWKS) for a project.


Path parameters


project_id* string

Response fields


request_id string

status_code int

keys object

REQUEST

Node
curl --request GET \
      --url https://test.stytch.com/v1/sessions/jwks/PROJECT_ID

RESPONSE

200
{
    "status_code": 200,
    "keys": [
        {
            "alg": "RS256",
            "e": "example-e",
            "key_ops": ["verify"],
            "kid": "example-key-id",
            "kty": "RSA",
            "n": "example-n",
            "use": "sig",
            "x5c": ["example-x5c"],
            "x5tS256": "example-x5tS256",
        },
    ],
}

Get Session

GEThttps://test.stytch.com/v1/b2b/sessions

Retrieves all active Sessions for a Member.


Query parameters


organization_name* string

member_id* string

Response fields


request_id string

status_code int

member_sessions array[objects]

REQUEST

Node
curl --request GET \
	--url https://test.stytch.com/v1/b2b/sessions?organization_id=organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931&member_id=member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \

RESPONSE

200
{
	"status_code": 200,
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"member_sessions": [...]
}

Authenticate Session

POSThttps://test.stytch.com/v1/b2b/sessions/authenticate

Authenticates a Session and updates its lifetime by the specified session_duration_minutes. If the session_duration_minutes is not specified, a Session will not be extended. This endpoint requires either a session_jwt or session_token be included in the request. It will return an error if both are present.

You may provide a JWT that needs to be refreshed and is expired according to its exp claim. A new JWT will be returned if both the signature and the underlying Session are still valid.


Body parameters


session_token string

session_jwt string

session_duration_minutes int

session_custom_claims map<string, any>

Response fields


request_id string

status_code int

member_session object

session_token string

session_jwt string

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/sessions/authenticate \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
	}'

RESPONSE

200
{
	"status_code": 200,
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"member_session": {...},
	"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
	"session_jwt": "",
	"member": {...},
	"organization": {...}
}

Exchange Session

POSThttps://test.stytch.com/v1/b2b/sessions/exchange

Use this endpoint to exchange a Member's existing session for another session in a different Organization. This can be used to accept an invite, but not to create a new member via domain matching.

To create a new member via domain matching, use the Exchange Intermediate Session flow instead.


Body parameters


organization_id* string

session_token string

session_jwt string

session_duration_minutes int

session_custom_claims map<string, any>

Response fields


request_id string

status_code int

member_id string

session_token string

session_jwt string

member_session object

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/sessions/exchange \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
	}'

RESPONSE

200
{
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200,
	"member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
	"session_jwt": "example_jwt",
	"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
	"member_session": {...},
	"member": {...},
	"organization": {...}
}

Revoke Session

POSThttps://test.stytch.com/v1/b2b/sessions/revoke

Revoke a Session and immediately invalidate all its tokens. To revoke a specific Session, pass either the member_session_id, session_token, or session_jwt. To revoke all Sessions for a Member, pass the member_id.


Body parameters


member_session_id string

session_token string

session_jwt string

member_id string

Response fields


request_id string

status_code int

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/sessions/revoke \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141"
}

SSO Overview

Single-Sign On (SSO) refers to the ability for a user to use a single identity to authenticate and gain access to multiple apps and service. In the case of B2B, it generally refers for the ability to use a workplace identity managed by their company. Read our blog post for more information about SSO.

Stytch supports the following SSO protocols:

  • SAML
  • OIDC

In order to set up SSO for your app, you'll need to take the following steps:

  1. An IT Admin of an organization creates a SSO connection for a specific protocol.
  2. The IT Admin updates the connection with information from their identity provider, and updates their identity provider with information from the connection.
    • The details of what information needs to be exchanged differ from protocol to protocol, so be sure to check out our Guides! (coming soon)
    • When all the information for a connection is filled out, the connection status is promoted to active and can be used to authenticate members of that organization.
  3. Embed the Start SSO Login Flow link in your application. Users will click on this link to be redirected to their IDP.
  4. After users are validated by their IDP, they are redirected back to a callback URL registered by your application.
  5. At the callback URL, call SSO Authenticate to finish the flow and validate the login.

SAML Connection object


Fields


organization_id string

connection_id string

display_name string

acs_url string

audience_uri string

attribute_mapping object

idp_entity_id string

idp_sso_url string

signing_certificates array

verification_certificates array

status string

OBJECT

200
{
  "connection": {
		"acs_url": "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"attribute_mapping": {
			"email": "email",
			"full_name": "name"
		},
		"audience_uri":  "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"display_name": "Example SAML Connection",
		"idp_entity_id": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9",
		"idp_sso_url": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9/sso/saml",
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"signing_certificates": [
			{
				"certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE",
				"created_at": "2023-01-01T00:00:00Z",
				"expires_at": "2033-01-01T00:00:00Z",
				"id": "",
				"issuer": "Stytch"
			}
		],
		"status": "active",
		"verification_certificates": [
			{
				"certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE",
				"created_at": "2023-01-01T00:00:00Z",
				"expires_at": "2033-01-01T00:00:00Z",
				"id": "saml-verification-key-test-5ccbc642-9373-42b8-928f-c1646c868701",
				"issuer": ""
			}
		]
	},
}

OIDC Connection object


Fields


organization_id string

connection_id string

display_name string

redirect_url string

status string

issuer string

client_id string

client_secret string

authorization_url string

token_url string

userinfo_url string

jwks_url string

OBJECT

200
{
  "connection": {
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "connection_id": "oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff",
    "display_name": "Example OIDC Connection",
    "redirect_url": "https://test.stytch.com/v1/b2b/sso/callback/oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff"
    "status": "active",
    "issuer": "https://idp.example.com/",
    "client_id": "s6BhdRkqt3",
    "client_secret": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
    "authorization_url": "https://idp.example.com/authorize"
    "token_url": "https://idp.example.com/oauth2/token"
    "userinfo_url": "https://idp.example.com/userinfo"
    "jwks_url": "https://idp.example.com/oauth2/jwks"
  }
}

Create SAML Connection

POSThttps://test.stytch.com/v1/b2b/sso/saml/{organization_id}

Create a new SAML Connection.


Path parameters


organization_id string

Body parameters


display_name string

Response fields


status_code int

request_id string

connection object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/sso/saml/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "display_name": "Example SAML Connection"
	}'

RESPONSE

200
{
	"connection": {
		"acs_url":  "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"attribute_mapping": {
			"email": "email",
			"full_name": "name",
		},
		"audience_uri":  "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"display_name": "",
		"idp": "",
		"idp_entity_id": "",
		"idp_sso_url": "",
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"signing_certificates": [
			{
				"certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE",
				"id": "",
				"created_at": "2023-01-01T00:00:00Z",
				"expires_at": "2033-01-01T00:00:00Z",
				"issuer": "Stytch"
			}
		],
		"status": "pending",
		"verification_certificates": []
	},
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200
}

Update SAML Connection

PUThttps://test.stytch.com/v1/b2b/sso/saml/{organization_id}/connections/{connection_id}

Updates an existing SAML connection.

Note that a newly created connection will not become active until all of the following are provided:

  • idp_sso_url
  • attribute_mapping
  • idp_entity_id
  • x509_certificate

Path parameters


organization_id string

connection_id string

Body parameters


idp_entity_id string

display_name string

attribute_mapping object

idp_sso_url* string

x509_certificate* string

Response fields


status_code int

request_id string

connection object

REQUEST

Node
curl --request PUT \
	--url https://test.stytch.com/v1/b2b/sso/saml/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/connections/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"entity_id": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9",
		"display_name": "Example SAML Connection",
		"attribute_mapping": {
		  "email": "NameID",
		  "first_name": "firstName",
		  "last_name": "lastName"
		},
		"idp_sso_url": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9/sso/saml",
		"x509_certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE"
	}'

RESPONSE

200
{
  "connection": {
		"acs_url": "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"attribute_mapping": {
			"email": "email",
			"full_name": "name"
		},
		"audience_uri":  "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"display_name": "Example SAML Connection",
		"idp_entity_id": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9",
		"idp_sso_url": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9/sso/saml",
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"signing_certificates": [
			{
				"certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE",
				"created_at": "2023-01-01T00:00:00Z",
				"expires_at": "2033-01-01T00:00:00Z",
				"id": "",
				"issuer": "Stytch"
			}
		],
		"status": "active",
		"verification_certificates": [
			{
				"certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE",
				"created_at": "2023-01-01T00:00:00Z",
				"expires_at": "2033-01-01T00:00:00Z",
				"id": "saml-verification-key-test-5ccbc642-9373-42b8-928f-c1646c868701",
				"issuer": ""
			}
		]
	},
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200
}

Create OIDC Connection

POSThttps://test.stytch.com/v1/b2b/sso/oidc/{organization_id}

Create a new OIDC Connection.


Path parameters


organization_id string

Body parameters


display_name string

Response fields


status_code int

request_id string

connection object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/sso/oidc/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "display_name": "Example OIDC Connection"
	}'

RESPONSE

200
{
  "connection": {
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "connection_id": "oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff",
    "display_name": "Example OIDC Connection",
    "redirect_url": "https://test.stytch.com/v1/b2b/sso/callback/oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff"
    "status": "active",
    "issuer": "https://idp.example.com/",
    "client_id": "s6BhdRkqt3",
    "client_secret": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
    "authorization_url": "https://idp.example.com/authorize"
    "token_url": "https://idp.example.com/oauth2/token"
    "userinfo_url": "https://idp.example.com/userinfo"
    "jwks_url": "https://idp.example.com/oauth2/jwks"
    },
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "status_code": 200
}

Update OIDC Connection

PUThttps://test.stytch.com/v1/b2b/sso/oidc/{organization_id}/connections/{connection_id}

Updates an existing OIDC connection.

When the value of issuer changes, Stytch will attempt to retrieve the OpenID Provider Metadata document found at ${issuer}/.well-known/openid-configuration. If the metadata document can be retrieved successfully, Stytch will use it to infer the values of authorization_url, token_url, jwks_url, and userinfo_url. The client_id and client_secret values cannot be inferred from the metadata document, and must be passed in explicitly.

If the metadata document cannot be retrieved, Stytch will still update the connection using values from the request body.

If the metadata document can be retrieved, and values are passed in the request body, the explicit values passed in from the request body will take precedence over the values inferred from the metadata document.

Note that a newly created connection will not become active until all of the following fields are provided:

  • issuer
  • client_id
  • client_secret
  • authorization_url
  • token_url
  • userinfo_url
  • jwks_url

Path parameters


organization_id string

connection_id string

Body parameters


display_name string

issuer string

client_id string

client_secret string

authorization_url string

token_url string

userinfo_url string

jwks_url string

Response fields


request_id string

status_code int

connection object

REQUEST

Node
curl --request PUT \
	--url https://test.stytch.com/v1/b2b/sso/oidc/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/connections/oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"display_name": "Example SAML Connection",
		"issuer": "https://idp.example.com/",
		"client_id": "s6BhdRkqt3",
		"client_secret": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
		"authorization_url": "https://idp.example.com/authorize"
	}'

RESPONSE

200
{
  "connection": {
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "connection_id": "oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff",
    "display_name": "Example OIDC Connection",
    "redirect_url": "https://test.stytch.com/v1/b2b/sso/callback/oidc-connection-test-b6c714c2-7413-4b92-a0f1-97aa1085aeff"
    "status": "active",
    "issuer": "https://idp.example.com/",
    "client_id": "s6BhdRkqt3",
    "client_secret": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
    "authorization_url": "https://idp.example.com/authorize"
    "token_url": "https://idp.example.com/oauth2/token"
    "userinfo_url": "https://idp.example.com/userinfo"
    "jwks_url": "https://idp.example.com/oauth2/jwks"
    },
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "status_code": 200
}

Get SSO Connections

GEThttps://test.stytch.com/v1/b2b/sso/{organization_id}

Get all SSO Connections owned by the organization.


Path parameters


organization_id string

Response fields


status_code int

request_id string

saml_connections array[Object]

oidc_connections array[Object]

REQUEST

Node
curl --request GET \
	--url https://test.stytch.com/v1/b2b/sso/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json'

RESPONSE

200
{
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "status_code": 200,
    "saml_connections": [{...}, {...}],
    "oidc_connections": [{...}, {...}]
}

Delete SSO Connection

DELETEhttps://test.stytch.com/v1/b2b/sso/{organization_id}/connections/{connection_id}

Delete an existing SSO connection.


Query parameters


organization_id* string

connection_id* string

Response fields


status_code int

request_id string

connection_id string

REQUEST

Node
curl --request DELETE \
	--url https://test.stytch.com/v1/b2b/sso/{organization_id}/connections/{connection_id} \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json'

RESPONSE

200
{
  "connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "status_code": 200
}

Start SSO Login Flow

GEThttps://test.stytch.com/v1/public/sso/start?connection_id={connection_id}&public_token={public_token}

A client-side endpoint (can only be queried from the user's browser) that starts the SSO Authentication flow. This endpoint redirects the User to the IdP with all of the information required to complete the SSO Authentication flow. From there, the user signs into their IdP before getting redirected back to Stytch. After verifying the request, Stytch immediately redirects the user back to the redirect_url configured in the dashboard.


Query parameters


connection_id* string

public_token* string

pkce_code_challenge string

login_redirect_url string

signup_redirect_url string

Response fields


status_code int

request_id string

redirect_url string

REQUEST

Node
curl --url https://test.stytch.com/v1/public/sso/start?connection_id=saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9&public_token=PUBLIC_TOKEN

RESPONSE

302
{
  "status_code": 302,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "redirect_url": "https://idp.example.com/51861cbc-d3b9-428b-9761-227f5fb12be9/sso/saml"
}

Authenticate SSO Login

POSThttps://test.stytch.com/v1/b2b/sso/authenticate

Authenticate a user given a token. This endpoint verifies that the user completed the SSO Authentication flow by verifying that the token is valid and hasn't expired. To initiate a Stytch session for the user while authenticating their SSO token, include the session_duration_minutes param. To link this authentication event to an existing Stytch session, include either the session_token or session_jwt param.


Body parameters


sso_token* string

session_custom_claims map<string, any>

session_duration_minutes int

session_jwt string

session_token string

pkce_code_verifier string

Response fields


status_code int

request_id string

member_id string

organization_id string

member object

organization object

session_token string

session_jwt string

member_session object

reset_sessions boolean

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/sso/authenticate \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4="
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
  "member": {...},
  "organization": {...},
  "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
  "session_jwt": "eyJ...",
  "member_session": {...},
}

Delete Verification Certificate

DELETEhttps://test.stytch.com/v1/b2b/sso/saml/{organization_id}/connections/{connection_id}/verification_certificates/{certificate_id}

Delete a SAML verification certificate.

You may need to do this when rotating certificates from your IdP, since Stytch allows a maximum of 5 certificates per connection. There must always be at least one certificate per active connection.


Path parameters


organization_id* string

connection_id* string

certificate_id* string

Response fields


status_code int

request_id string

certificate_id string

REQUEST

Node
curl --request DELETE \
	--url https://test.stytch.com/v1/b2b/sso/saml/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/connections/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9/verification_certificates/saml-verification-key-test-5ccbc642-9373-42b8-928f-c1646c868701 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "certificate_id": "saml-verification-key-test-5ccbc642-9373-42b8-928f-c1646c868701",
}

Discovery Overview

The Discovery product lets End Users discover and log in to Organizations they are a Member of, invited to, or eligible to join.

Unlike our other B2B products, Discovery allows End Users to authenticate without specifying an Organization in advance. This is done via a Discovery Magic Link flow. After an End User is authenticated, an Intermediate Session is returned along with a list of associated Organizations.

The End User can then authenticate to the desired Organization by passing the Intermediate Session and organization_id. End users can even create a new Organization instead of joining or logging in to an existing one.

Discovered Organization object


Fields


organization object

member object

member_authenticated boolean

OBJECT

Existing Member
{
  "organization": {
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "organization_name": "Example Org Inc.",
    "organization_slug": "example-org",
    ...
  },
  "membership": {
    "type": "active_member",
    "member": {
      "email_address": "sandbox@stytch.com",
      "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
      "name": "Test Member",
      "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
      "status": "active",
      ...
    },
    "details": null
  },
  "member_authenticated": true
}

List Discovered Organizations

POSThttps://test.stytch.com/v1/b2b/discovery/organizations

List all possible organization relationships connected to a Member Session or Intermediate Session.

When a Member Session is passed in, relationships with a type of active_member, pending_member, or invited_member will be returned, and any membership can be assumed by calling the Exchange Session endpoint.

When an Intermediate Session is passed in, all relationship types - active_member, pending_member, invited_member, and eligible_to_join_by_email_domain - will be returned, and any membership can be assumed by calling the Exchange Intermediate Session endpoint.

This endpoint requires either an intermediate_session_token, session_jwt or session_token be included in the request. It will return an error if multiple are present.

This operation does not consume the Intermediate Session or Session Token passed in.


Body parameters


intermediate_session_token string

session_token string

session_jwt string

Response fields


request_id string

status_code int

email_address string

discovered_organizations array

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/discovery/organizations \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4="
	}'

RESPONSE

200
{
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200,
	"email_address": "sandbox@stytch.com",
	"discovered_organizations": [{...}, {...}]
}

Create Organization via Discovery

POSThttps://test.stytch.com/v1/b2b/discovery/organizations/create

If an end user does not want to join any already-existing organization, or has no possible organizations to join, this endpoint can be used to create a new Organization and Member.

This operation consumes the Intermediate Session.

This endpoint can also be used to start an initial session for the newly created member and organization.


Body parameters


intermediate_session_token* string

session_duration_minutes int

session_custom_claims map<string, any>

organization_name string

organization_slug string

organization_logo_url string

trusted_metadata object

email_jit_provisioning string

email_invites string

email_allowed_domains array[strings]

sso_jit_provisioning string

auth_methods string

allowed_auth_methods array[strings]

Response fields


request_id string

status_code int

member_id string

session_token string

session_jwt string

member_session object

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/discovery/organizations \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
		"session_duration_minutes": 60,
		"organization_name": "Example Org Inc.",
		"organization_slug": "example-org"
	}'

RESPONSE

200
{
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200,
	"member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
	"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
	"session_jwt": "eyJ...",
    "member_session": {...},
    "member": {...},
    "organization": {...}
}

Exchange Intermediate Session

POSThttps://test.stytch.com/v1/b2b/discovery/intermediate_sessions/exchange

Exchange an Intermediate Session for a fully realized Member Session in a desired Organization. This operation consumes the Intermediate Session.

This endpoint can be used to accept invites and create new members via domain matching.


Body parameters


intermediate_session_token* string

organization_id* string

session_duration_minutes int

session_custom_claims map<string, any>

Response fields


request_id string

status_code int

member_id string

session_token string

session_jwt string

member_session object

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/discovery/intermediate_sessions/exchange \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
		"intermediate_session_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"session_duration_minutes": 60
	}'

RESPONSE

200
{
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200,
	"member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
	"session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
	"session_jwt": "eyJ...",
    "member_session": {...},
    "member": {...},
    "organization": {...}
}

Passwords Overview

Stytch Passwords support creating, storing, and authenticating password-based Members, as well as account recovery (password reset) and account deduplication with passwordless login methods.

For migrating existing password based members into Stytch, we support importing bcrypt, scrypt, argon2, MD-5, and SHA-1 password hashes from common auth providers like Cognito, Auth0, and Firebase.

Our implementation of passwords has built-in breach detection powered by HaveIBeenPwned on both sign-up and login, to prevent the use of compromised credentials and uses Dropbox’s zxcvbn strength requirements to guide members towards creating passwords that are easy for humans to remember but difficult for computers to crack.

Authenticate

POSThttps://test.stytch.com/v1/b2b/passwords/authenticate

Authenticate a member with their email address and password. This endpoint verifies that the member has a password currently set, and that the entered password is correct. There are two instances where the endpoint will return a reset_password error even if they enter their previous password:

  • The member’s credentials appeared in the HaveIBeenPwned dataset.
    • We force a password reset to ensure that the member is the legitimate owner of the email address, and not a malicious actor abusing the compromised credentials.
  • A member that has previously authenticated with email/password uses a passwordless authentication method tied to the same email address (e.g. Magic Links) for the first time. Any subsequent email/password authentication attempt will result in this error.
    • We force a password reset in this instance in order to safely deduplicate the account by email address, without introducing the risk of a pre-hijack account takeover attack.
    • Imagine a bad actor creates many accounts using passwords and the known email addresses of their victims. If a victim comes to the site and logs in for the first time with an email-based passwordless authentication method then both the victim and the bad actor have credentials to access to the same account. To prevent this, any further email/password login attempts first require a password reset which can only be accomplished by someone with access to the underlying email address.

Body parameters


organization_id* string

email_address* string

password* string

session_token string

session_jwt string

session_duration_minutes int

session_custom_claims map<string, any>

Response fields


request_id string

status_code int

member_id string

organization_id string

member object

organization object

session_token string

session_jwt string

member_session object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/authenticate \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
	  "email_address": "sandbox@stytch.com",
	  "password": "tVrSmyTeNrn20tCn",
	  "session_duration_minutes": 30
	}'

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "session_jwt": "example_jwt",
    "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
    "member_session": {...},
    "member": {...},
    "organization": {...}
}

Email reset start

POSThttps://test.stytch.com/v1/b2b/passwords/email/reset/start

Initiates a password reset for the email address provided. This will trigger an email to be sent to the address, containing a magic link that will allow them to set a new password and authenticate.

This endpoint adapts to your Project's password strength configuration. If you're using zxcvbn, the default, your passwords are considered valid if the strength score is >= 3. If you're using LUDS, your passwords are considered valid if they meet the requirements that you've set with Stytch. Reach out to support@stytch.com if you'd like to change your password strength configuration.


Body parameters


organization_id* string

email_address* string

reset_password_redirect_url string

login_redirect_url string

reset_password_template_id string

locale string

reset_password_expiration_minutes string

code_challenge string

Response fields


request_id string

status_code int

member_id string

member_email_id string

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/email/reset/start \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
	  "email_address": "sandbox@stytch.com",
	  "reset_password_redirect_url": "https://someexample.com",
    "login_redirect_url": "https://someexample.com",
    "reset_password_expiration_minutes": 10
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member_email_id": "member-email-test-1dd089b3-8904-47ef-b943-987968e549d4",
  "member": {...}
}

Email reset

POSThttps://test.stytch.com/v1/b2b/passwords/email/reset

Reset the member's password and authenticate them. This endpoint checks that the password reset token is valid, hasn’t expired, or already been used.

The provided password needs to meet our password strength requirements, which can be checked in advance with the password strength endpoint. If the token and password are accepted, the password is securely stored for future authentication and the user is authenticated.


Body parameters


password_reset_token* string

password* string

session_token string

session_jwt string

session_duration_minutes int

session_custom_claims map<string, any>

code_verifier string

Response fields


request_id string

status_code int

member_id string

member_session object

session_token string

session_jwt string

organization_id string

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/email/reset \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "password_reset_token": "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
	  "password": "tVrSmyTeNrn20tCn"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member_email_id": "member-email-test-1dd089b3-8904-47ef-b943-987968e549d4",
  "member": {...}
}

Existing reset

POSThttps://test.stytch.com/v1/b2b/passwords/existing_password/reset

Reset the member’s password using their existing password.

This endpoint adapts to your Project's password strength configuration. If you're using zxcvbn, the default, your passwords are considered valid if the strength score is >= 3. If you're using LUDS, your passwords are considered valid if they meet the requirements that you've set with Stytch. Reach out to support@stytch.com if you'd like to change your password strength configuration.


Body parameters


organization_id* string

email_address* string

existing_password* string

new_password* string

session_token string

session_jwt string

session_duration_minutes int

session_custom_claims map<string, any>

Response fields


request_id string

status_code int

member object

member_id string

member_session object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/existing_password/reset \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
	  "email_address": "sandbox@stytch.com",
	  "existing_password": "old_password",
	  "new_password": "tVrSmyTeNrn20tCn"
	}'

RESPONSE

200
{
    "member": {...},
    "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
    "member_session": {...},
    "organization": {...}
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "session_jwt": "example_jwt",
    "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q",
    "status_code": 200
}

Session reset

POSThttps://test.stytch.com/v1/b2b/passwords/session/reset

Reset the Member's password using their existing session. The endpoint will error if the session does not an authentication factor that has been issued within the last 5 minutes.


Body parameters


organization_id* string

password* string

session_token string

session_jwt string

Response fields


request_id string

status_code int

member_session object

member_id string

member object

organization object

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/session/reset \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
	  "password": "tVrSmyTeNrn20tCn"
	  "session_token": "mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q"
	}'

RESPONSE

200
{
  "status_code": 200,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
  "member_session": {...},
  "member": {...},
}

Delete Member password

DELETEhttps://test.stytch.com/v1/b2b/organizations/{organization_id}/members/passwords/{member_password_id}

Delete a Member's password.


Path parameters


organization_id* string

member_password_id* string

Response fields


member_id string

member object

organization object

status_code int

request_id string

REQUEST

Node
curl --request DELETE \
	--url https://test.stytch.com/v1/b2b/organizations/organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931/members/passwords/member-password-test-51861cbc-d3b9-428b-9761-227f5fb12be9 \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json'

RESPONSE

200
{
    "member": {...},
    "member_id": "member-test-32fc5024-9c09-4da3-bd2e-c9ce4da9375f",
    "organization": {...}
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "status_code": 200
}

Strength check

POSThttps://test.stytch.com/v1/b2b/passwords/strength_check

This API allows you to check whether the user’s provided password is valid, and to provide feedback to the user on how to increase the strength of their password.

This endpoint adapts to your Project's password strength configuration. If you're using zxcvbn, the default, your passwords are considered valid if the strength score is >= 3. If you're using LUDS, your passwords are considered valid if they meet the requirements that you've set with Stytch. Reach out to support@stytch.com if you'd like to change your password strength configuration.

Password feedback

The zxcvbn_feedback and luds_feedback objects contains relevant fields for you to relay feedback to users that failed to create a strong enough password.

If you're using zxcvbn, the feedback object will contain warning and suggestions for any password that does not meet the zxcvbn strength requirements. You can return these strings directly to the user to help them craft a strong password.

If you're using LUDS, the feedback object will contain a collection of fields that the user failed or passed. You'll want to prompt the user to create a password that meets all requirements that they failed.


Body parameters


password* string

email_address string

Response fields


status_code int

request_id string

breach_detection_on_create boolean

breached_password boolean

luds_feedback object

zxcvbn_feedback object

score int

strength_policy string

valid_password boolean

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/strength_check \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
	  "password": "tVrSmyTeNrn20tCn"
	}'

RESPONSE

200
{
    "breach_detection_on_create": true,
    "breached_password": false,
    "luds_feedback": {},
    "request_id": "request-id-test-f3aca0eb-e38f-4e0a-b5cc-e6e52ad88c71",
    "score": 0,
    "status_code": 200,
    "strength_policy": "zxcvbn",
    "valid_password": false,
    "zxcvbn_feedback": {
        "suggestions": [
            "Add another word or two. Uncommon words are better."
        ],
        "warning": ""
    }
}

Migrate

POSThttps://test.stytch.com/v1/b2b/passwords/migrate

Adds an existing password to a member's email that doesn't have a password yet. We support migrating members from passwords stored with bcrypt, scrypt, argon2, MD-5, and SHA-1. This endpoint has a rate limit of 10 requests per second.


Body parameters


organization_id* string

email_address* string

name string

trusted_metadata object

untrusted_metadata object

hash* string

hash_type* string

scrypt_config object

argon_2_config object

md_5_config object

sha_1_config object

Response fields


member_id string

member object

organization object

status_code int

request_id string

REQUEST

Node
curl --request POST \
	--url https://test.stytch.com/v1/b2b/passwords/migrate \
	-u 'PROJECT_ID:SECRET' \
	-H 'Content-Type: application/json' \
	-d '{
    "organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
    "email_address": "sandbox@stytch.com",
    "hash": "$2b$04$oa70000TFDu3icElr2qML7Le",
    "hash_type": "bcrypt"
  }'

RESPONSE

200
{
	"connection": {
		"acs_url":  "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"attribute_mapping": {
			"email": "email",
			"full_name": "name",
		},
		"audience_uri":  "https://test.stytch.com/v1/b2b/sso/callback/saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"connection_id": "saml-connection-test-51861cbc-d3b9-428b-9761-227f5fb12be9",
		"display_name": "",
		"idp": "",
		"idp_entity_id": "",
		"idp_sso_url": "",
		"organization_id": "organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931",
		"signing_certificates": [
			{
				"certificate": "-----BEGIN CERTIFICATE-----\n...base64 blob...\n-----END CERTIFICATE",
				"id": "",
				"created_at": "2023-01-01T00:00:00Z",
				"expires_at": "2033-01-01T00:00:00Z",
				"issuer": "Stytch"
			}
		],
		"status": "pending",
		"verification_certificates": []
	},
	"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
	"status_code": 200
}

Resources Overview

Learn more about Stytch concepts, data models, and general B2B API concerns.

Basic Authentication

The Stytch API uses basic authentication for all API requests. The username will be your project_id and the password will be your secret. You can retrieve both your test and live API keys from the Dashboard.

Organization authentication settings

Every Organization has a set of fields that control the authentication and provisioning of its Members. These controls have admin-like capabilities and should be updated deliberately.

The Organization auth settings are grouped by type of auth factor. The auth setting field names are prepended with an auth factor like email or sso or oauth. For example, all Organization fields that begin with email_* are settings that specifically affect provisioning and auth flows via Email Magic Links.

An Organization must always have at least one auth setting that allows new Members to be created and join. As a result, sso_jit_provisioning, email_jit_provisioning, email_invites cannot all be simultaneously set to NOT_ALLOWED.

Here is an example Organization object with its auth settings fully shown.

{
    "organization_name": "Example Org",
    "organization_slug": "example-org",
   
    // Auth settings for Email Magic Links
    "email_invites": "NOT_ALLOWED" | "RESTRICTED" | "ALL_ALLOWED",    
    "email_jit_provisioning": "NOT_ALLOWED" | "RESTRICTED",
    "email_allowed_domains": ["stytch.com"],

    // Auth settings for Single Sign On
    "sso_jit_provisioning": "NOT_ALLOWED" | "RESTRICTED" | "ALL_ALLOWED",
    "sso_default_connection_id": "...",
    "sso_jit_provisioning_allowed_connections": [
        "saml-connection-live-7111f7b1-9896-4ce3-a658-9e0707fc5192",
    ],
    "sso_active_connections": [
        { "connection_id": … },
        { "connection_id": … }      
    ]

    …
}

Auth settings for Email Magic Links:

  • If email_allowed_domains is empty
    • then email_invites cannot be set to RESTRICTED.
    • then email_jit_provisioning cannot be set to RESTRICTED.
  • If email_allowed_domains is not empty
    • and email_invites is set to RESTRICTED, then all new Members must have an email address that complies with email_allowed_domains in order to be invited by email.
    • and email_invites is set to ALL_ALLOWED, then any new Member can be invited to email.
    • and email_invites is set to NOT_ALLOWED, then email invites are disabled.
  • If email_allowed_domains is not empty
    • and email_jit_provisioning is set to RESTRICTED, then all new Members must have an email address that complies with email_allowed_domains in order to be provisioned via Email Magic Links.
    • and email_jit_provisioning is set to ALL_ALLOWED, then any new Member can be provisioned via Email Magic Links.
    • and email_jit_provisioning is set to NOT_ALLOWED, then JIT provisioning via Email Magic Links is disabled.
  • If email_allowed_domains is updated
    • then the entire list will be overwritten by the new value.
    • then all Members will remain active even if their email_address no longer complies with email_allowed_domains.
    • and either email_invites or email_jit_provisioning is set to RESTRICTED, then email_allowed_domains cannot be set to an empty array.

Auth settings for Single Sign On:

  • If sso_jit_provisioning_allowed_connections is empty
    • then sso_jit_provisioning cannot be set to RESTRICTED.
  • If sso_jit_provisioning_allowed_connections is not empty
    • and sso_jit_provisioning is set to RESTRICTED, then all new Members must have an SSO login that complies with sso_jit_provisioning_allowed_connections in order to be provisioned via SSO.
    • and sso_jit_provisioning is set to ALL_ALLOWED, then all new Members will be automatically provisioned via any of the Organization's sso_active_connections.
    • and sso_jit_provisioning is set to NOT_ALLOWED, then JIT provisioning via SSO is disabled.
  • If sso_jit_provisioning_allowed_connections is updated
    • then the entire list will be overwritten by the new value.
    • then all currently active Members will remain active even if their sso_registrations no longer complies with sso_jit_provisioning_allowed_connections.
    • and sso_jit_provisioning is set to RESTRICTED, then sso_jit_provisioning_allowed_connections cannot be set to an empty array.

Common email domains

An Organization cannot have a certain set of common email domains added to email_allowed_domains. The following email domains are not allowed:

gmail, aol, yahoo, icloud, hotmail, msn, comcast, live, outlook, att, earthlink, me, mac, sbcglobal, verizon, ig, mail, hey, laposte, wanadoo, googlemail, orange, rediffmail, uol, bol, free, gmx, yandex, ymail, libero

Member states

A Member's state impacts how they are treated within Stytch, in particular which email template they are sent. Members within Stytch can be in four different states: pending, invited, active, or deleted.

active: Members become active after successfully authenticating at least once via Stytch. When the SendLoginOrSignup endpoint is called on an active Member, they will receive a login email template. The Email Magic Link will route them to the login_redirect_url provided in the request.

pending: Stytch Members are created as pending when created by the SendLoginOrSignup endpoint or when they are created by the CreateMember endpoint with the create_member_as_pending parameter set to true. If the SendInviteEmail endpoint is called on a pending Member, their status will change to invited. Once a Member successfully authenticates a Magic Link from either an invite or signup email, they will be marked as active.

invited: Stytch Members are created as invited when created by the SendInviteEmail endpoint. The invited Member will receive an email that uses the invite email template. If the SendLoginOrSignup endpoint is called on an already invited member, their status will stay invited. Once a Member successfully authenticates a Magic Link from either an invite or signup email, they will be marked as active.

deleted: Stytch Members are marked as deleted after calling the DeleteMember or DeleteOrganization endpoint. Once a Member is deleted, any emails or auth factors tied to that Member are also deleted. The SearchMember endpoint will not return deleted Members.

Environments

There are two environments, TEST and LIVE, each with unique API keys and URLs, test.stytch.com and api.stytch.com. Additionally, the resources created in each environment are tied to the environment they were created in. The ids used for objects include the environment they are tied to, for example member-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6 belongs to the test environment.

Email templates

Email templates control the subject line and body of the email a Member receives. For Magic Link endpoints that send emails, there are three possible email templates a Member can receive: login, signup or invite. Which email template a Member receives is based on a combination of the Member's state in the Stytch backend and the endpoint used.

Metadata

Stytch Members may contain metadata - arbitrary JSON objects for recording application-specific information.

Metadata restrictions

  • Metadata objects may contain a maximum of 20 top-level keys.
  • Metadata objects cannot exceed 4KB in size

Metadata permissions

Stytch Members contain two types of metadata - trusted_metadata and untrusted_metadata.

Direct API integrations can read and write to both trusted_metadata and untrusted_metadata.

Frontend SDK integrations can read and write to untrusted_metadata, but only read trusted_metadata.

Secure fields, such as a Member's role, billing_status, or stripe_customer_id should only be stored in trusted_metadata by using a direct API integration. Fields that a Member can be allowed to edit directly - such as display_theme or preferred_locale may be stored in untrusted_metadata.

Do not store any sensitive information (passport numbers, credit card details, etc.) as metadata.

Metadata update behavior

Metadata update payloads will be merged with the existing metadata at the top level only. Send a top-level value of null to delete an existing field. To delete all metadata from an object, send a top-level value of null for every existing field. Stytch will not merge deeply nested objects or arrays. To add a field to a deeply nested object, or update an array, replace the entire top-level key.

Example: adding a new field

Initial:

{
  "trusted_metadata": {
    "key1": "value1"
  }
}

Update:

{
  "trusted_metadata": {
    "key2": "value2"
  }
}

Result:

{
  "trusted_metadata": {
    "key1": "value1",
    "key2": "value2"
  }
}

Example: replacing an existing field

Initial:

{
  "untrusted_metadata": {
    "key1": "value1"
  }
}

Update:

{
  "untrusted_metadata": {
    "key1": "value2"
  }
}

Result:

{
  "untrusted_metadata": {
    "key1": "value2"
  }
}

Example: updating a deeply nested field

Initial:

{
  "trusted_metadata": {
    "key1": [{"deep": "value1"}],
    "other_key": "other_value"
  }
}

Update:

{
  "trusted_metadata": {
    "key1": [{"deep": "value1"}, {"deep": "value2"}]
  }
}

Result:

{
  "trusted_metadata": {
    "key1": [{"deep": "value1"}, {"deep": "value2"}],
    "other_key": "other_value"
  }
}

Example: deleting a field

Initial:

{
  "untrusted_metadata": {
    "key1": [{"deep": "value1"}],
    "other_key": "other_value"
  }
}

Update:

{
  "untrusted_metadata": {
    "key1": null
  }
}

Result:

{
  "untrusted_metadata": {
    "other_key": "other_value"
  }
}

Example: deleting all fields

Initial:

{
  "trusted_metadata": {
    "key1": [{"deep": "value1"}],
    "other_key": "other_value"
  }
}

Update:

{
  "trusted_metadata": {
    "key1": null,
    "other_key": null
  }
}

Result:

{
  "trusted_metadata": {}
}

URL validation

To ensure your Members are always routed to the correct place, Stytch verifies any redirect URLs provided in requests against redirect URLs that are configured in the developer Dashboard.

For each redirect URL type (login, signup, invite, discovery, or password reset), a developer can specify one or more URLs for each type.

Each project also has separate redirect URLs for the test and live environments. When verifying the redirect URL from the request against the predefined URLs for the project, Stytch looks for an exact match, including any subdirectories and query parameters. Please visit the Dashboard to set redirect URLs for your project.

By default, all redirect URLs are set to http://localhost:3000 for the Test environment.


SAML SSO Overview

Stytch allows your organizations to use SAML SSO as an authentication method. Stytch will act as the Service Provider (SP) in front of your organizations, and interface with the Identity Provider (IdP), which will provide authentication assertions.

Attribute mappings:

Stytch requires any identity provider to specify the email and name of the member attempting to log in. It parses these from the attributes sent in the IdP's assertion to Stytch. To recognize which attributes correspond to which fields, Stytch allows your connection to define an attribute_mapping.

An example attribute_mapping looks like this:

	"attribute_mapping": {
		"email": "email",
		"full_name": "name"
	},

Stytch requires either the full_name key to be present, or both the first_name and last_name keys. Additionally, Stytch requires an email key to be present if the NameID format sent by the IdP is not an email.

The attribute mapping can be set in the Update SAML Connection endpoint.

Single sign-on URLs:

Some IdPs may ask for a single sign-on URL. This is listed as the acs_url in the SAML connection object. Note that for Stytch's purposes, the acs_url and audience_uri are the same value.

Signing and Verification Certificates

Signing Certificates

When sending an authentication request to the IdP, Stytch sends a signature along with the request, indicating that the request came from Stytch. This signature can be verified using the Signing Certificate provided by Stytch, in the form of an X.509 certificate. This certificate is present on all SAML connection objects.

Some IdPs may call this a "signed request" or "Signature Validation", or have WantAuthnRequestsSigned="true" in their SAML configuration settings. This certificate should be uploaded to the IdP in order to make use of this optional feature.

Verification Certificates

When receiving an authentication response from the IdP, Stytch will verify that the response actually originates from the IdP.

Stytch will only accept an authentication response from the IdP if the signature of the response is correctly validated with the connection's stored Verification Certificate, which comes from the IdP. This X.509 certificate is uploaded to Stytch and stored with the specific SAML connection. In the API, you can provide the certificate on a SAML update request.

There is a limit of 5 verification certificates per SAML connection. You can delete a connection's certificate by calling the Delete Verification Certificate. endpoint.

When uploading a certificate to an IdP or passing a certificate to Stytch, you may encounter the certificate in the form of a PEM file. If you are manually taking a certificate from Stytch's Create SAML Connection endpoint, you can save it as a PEM file as so:

echo "-----BEGIN CERTIFICATE-----\nMIIFIjCCAwoCCQC8brjOdUXVjTANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJV\nUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEX\n...more base64 here...\n9A7Yts1LcBX0kX91G2I++0JRMM0E5OwnG6MXtPJfmsLmPM3WkJHGf2PUY6k6xR+y\nokXHOYlhkarZ3SKPVUWE5rpK4GtpYEOaLIrDAxRm2qm4NvDN7zuz51RhHh9DcP4v\nQWz1JJ4v5Q63z2Mz8sIxDoWzxw9wl9wVq0u5QN2jP2cxGvdTG4rGTpZW5AT3LBWa\nvgej5xjwiYfaoboTEHQE8iP+EPwtCA==\n-----END CERTIFICATE-----\n" > stytch_signing_certificate.pem

Note that the API returns the signing certificate as a raw string (with newlines).

OBJECT

x509
-----BEGIN CERTIFICATE-----
MIIFIjCCAwoCCQC8brjOdUXVjTANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJV
UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEX
MBUGA1UECgwOU3R5dGNoIEVYQU1QTEUwHhcNMjMwMjA5MjMwMjA0WhcNMjQwMjA5
MjMwMjA0WjBTMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
A1UEBwwNU2FuIEZyYW5jaXNjbzEXMBUGA1UECgwOU3R5dGNoIEVYQU1QTEUwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDIRzEMPwjJgflImAYjSIfDMXCC
IBFhuhxY8/mnidMiMauGR+dEMP4Jlg8oOZSNMx8wfPH7aqRIM8dkj8BhJ3QUjQmA
XLSgYsBUSSMaELHCurPSdz+rHfUMfD/cag5GeyPM2KtBD3I/Du545SNeURwKaiB5
fwlfYblMGNFvB70KRpl/YkvBYL7knKTGe1K6NG56IyGhRguEpaksxBJ4RTXcNiWr
ENcrw88LUpJd+7cDTlLB+6N+hPWUS/91R5kbQw/GX23C6uUDxTtGimWvA+riV6OF
IjWf5oDWioZj9wUFXElw+mMmTYye/cIHtXlwia845dWD5Gn9o5hpXoPBzV9tNPce
FgUcaczFkyRpnPU6HwMNFkfGPYWyn8w1mW6DKCNwe6gG9PYejoTMsvIrsoB4e5mT
Y56ZbYZRCglzBOgQZZejxZfvhg5m027lNrAdr5keBF3QVZ6+LIoHbHIRhskYTg6N
oY+B7c2u8/wUux4r1CwjgE5I/NCFd4UsUIfyNNPiqMEHtiTKi1++/d8oFeGOrobK
9dCE9pQ7WFtHYgM0q7ygkXdfw4mspdhwjVKbPAjf6pGkMr/NvWKF23MZ4PU84NXn
nUZlUyPGXcB/IuGzIykBTLrvr9dyZXcF39LM9B2zoSknbvwv1yyvOjASEQeN9678
bBNHVCDFZ2F3xnyYtwIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCSSpID/WriYgPD
vLRgETj6RWhKRaqga5endmFNE6/s5r7iJr/OPMNUUCqga1A2gtoP1jT4VX6qHMAL
zyiEoMYg3NosUZE78VqK25GLjwJ21w9KeocTNFFzir0uB+gDwnpY+er0OojwabMk
12AWFqRoSy6wHICYIcS6SCI0Sg7BWLV4bprSJ+zsV/pkDKJ3iwFcGNhTnOrPdpI6
zbyqG3MXnK5G2xVNbg/67oNQfd3Jis2Hlb7GYMnIEtU4j3Lw12yBvMIi0eJX0cim
/F7GJZKFEd5OuHF0rhHo36RYvrwxmjHu4pCqIO7vlW8NdSd86xL2mpRyQiqRcm3L
ZCAMdi+ykuOdW3FcKPDxB/GripTwzmtuK68hPwrl1QIsGl1toyXgLClRjete0EB2
bye4jWI0QHHJ/JA6xkD8O/3/q8aVcD0LgeBhEXYkQGZgbiVg1X9KXPdadKT+4GlD
9A7Yts1LcBX0kX91G2I++0JRMM0E5OwnG6MXtPJfmsLmPM3WkJHGf2PUY6k6xR+y
okXHOYlhkarZ3SKPVUWE5rpK4GtpYEOaLIrDAxRm2qm4NvDN7zuz51RhHh9DcP4v
QWz1JJ4v5Q63z2Mz8sIxDoWzxw9wl9wVq0u5QN2jP2cxGvdTG4rGTpZW5AT3LBWa
vgej5xjwiYfaoboTEHQE8iP+EPwtCA==
-----END CERTIFICATE-----

Errors overview

Stytch uses HTTP response status codes to indicate the success or failure of your API requests. For failures, Stytch returns an error using the appropriate status code. There are three categories for status codes:

  • 2xx success status codes confirm that your request worked as expected.
  • 4xx error status codes indicate an error because of the information provided (e.g., a required parameter was omitted).
  • 5xx error status codes are rare and indicate an error with Stytch’s servers.

4xx errors generally require some action to be taken to resolve them. Below is a list of possible error codes that can be returned, along with additional information about how to resolve them. These types of errors also include the url attribute with a direct link to the specific error code it corresponds to.


Error object


Fields


status_code int

request_id string

error_type string

error_message string

error_url  string

OBJECT

403
{
  "status_code": 403,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "use_https",
  "error_message": "Please use https instead of http.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/403/use_https"
}

400 errors

active_totp_exists

400Bad request

Cannot create a new TOTP for the specified user since the user already has an active TOTP. Users may only have one active TOTP at a time.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "active_totp_exists",
  "error_message": "Cannot create a new TOTP for the specified user since the user already has an active TOTP. Users may only have one active TOTP at a time.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/active_totp_exists"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

allowed_auth_methods_required_for_restricted

400Bad request

Allowed auth methods must be set for 'RESTRICTED' auth methods

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "allowed_auth_methods_required_for_restricted",
  "error_message": "Allowed auth methods must be set for 'RESTRICTED' auth methods",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/allowed_auth_methods_required_for_restricted"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

apple_oauth_config_not_found

400Bad request

The Apple OAuth config was not found.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "apple_oauth_config_not_found",
  "error_message": "The Apple OAuth config was not found.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/apple_oauth_config_not_found"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

argon_2_key_length_mismatch

400Bad request

The key_length value doesn't match the length of the provided hash.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "argon_2_key_length_mismatch",
  "error_message": "The key_length value doesn't match the length of the provided hash.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/argon_2_key_length_mismatch"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

bad_request

400Bad request

The submitted request is invalid.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "bad_request",
  "error_message": "The submitted request is invalid.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/bad_request"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

billing_not_verified

400Bad request

You cannot use this endpoint in the live environment until credit card details are added to your account, but you can try the endpoint in the test environment. Once your billing information is verified, this endpoint can be used in live. Your first 5,000 monthly active users are free every month, but collecting this information helps us prevent abuse of the platform. Please go to billing settings to provide billing information.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "billing_not_verified",
  "error_message": "ou cannot use this endpoint in the Live environment until credit card details are added to your account, but you can try the endpoint in the Test environment. Once your billing information is verified, this endpoint can be used in Live. Your first 5,000 monthly active users are free every month, but collecting this information helps us prevent abuse of the platform. Please go to https://stytch.com/settings/billing to provide billing information.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/billing_not_verified"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

billing_not_verified_for_email

400Bad request

You can only send magic links to emails matching your project's domain until credit card details are added to your account. Once your billing information is verified, emails can be sent to anyone. Your first 5,000 monthly active users are free every month, but collecting this information helps us prevent abuse of the platform. Please go to billing settings to provide billing information.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "billing_not_verified_for_email",
  "error_message": "You can only send magic links to emails matching your project's domain until credit card details are added to your account. Once your billing information is verified, emails can be sent to anyone. Your first 5,000 monthly active users are free every month, but collecting this information helps us prevent abuse of the platform. Please see https://stytch.com/settings/billing to provide billing information.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/billing_not_verified_for_email"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

cannot_delete_default_sso_connection

400Bad request

Please update the default SSO connection setting for this organization to a different SSO connection before deleting.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "cannot_delete_default_sso_connection",
  "error_message": "Please update the default SSO connection setting for this organization to a different SSO connection before deleting.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/cannot_delete_default_sso_connection"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

cannot_delete_email

400Bad request

Cannot delete the last email for a user with a password. This ensures they can complete a password reset.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "cannot_delete_email",
  "error_message": "Cannot delete the last email for a user with a password. This ensures they can complete a password reset.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/cannot_delete_email"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

cannot_delete_last_primary_factor

400Bad request

You cannot delete the last primary factor (email, phone number, crypto wallet) for a user because that would make their account difficult or impossible to recover. If you want to remove the user from your project, delete the user instead.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "cannot_delete_last_primary_factor",
  "error_message": "Cannot delete the last primary factor (email, phone number, crypto wallet) for a user. If you want to delete the user instead, use the DeleteUser endpoint: https://stytch.com/docs/api/delete-user",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/cannot_delete_last_primary_factor"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

cannot_delete_last_sso_verification_key

400Bad request

Cannot delete the last verification certificate for a connection. Please pass in another one before deleting this one.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "cannot_delete_last_sso_verification_key",
  "error_message": "Cannot delete the last verification certificate for a connection. Please pass in another one before deleting this one.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/cannot_delete_last_sso_verification_key"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

cannot_reset_password_with_existing_password

400Bad request

Cannot reset user's password using their existing password. This could be because their existing password was part of a data breach or to prevent password squatting. Please reset the password via a session or email reset.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "cannot_reset_password_with_existing_password",
  "error_message": "Cannot reset user's password using their existing password. This could be because their existing password was part of a data breach or to prevent password squatting. Please reset the password via a session or email reset.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/cannot_reset_password_with_existing_password"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

cannot_use_webauthn_with_pending_user

400Bad request

WebAuthn can only be used with active users. To learn more about WebAuthn and user states please see here and here.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "cannot_use_webauthn_with_pending_user",
  "error_message": "WebAuthn can only be used for active users. To learn more about WebAuthn and user states read more at https://stytch.com/docs/api/webauthn-overview and https://stytch.com/docs/api/user-states.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/cannot_use_webauthn_with_pending_user"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

client_secret_too_long

400Bad request

Client secret is too long. Please make sure you have the correct value.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "client_secret_too_long",
  "error_message": "Client secret is too long. Please make sure you have the correct value.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/client_secret_too_long"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

custom_claims_too_large

400Bad request

Custom claims are too large.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "custom_claims_too_large",
  "error_message": "Custom claims are too large.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/custom_claims_too_large"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

deprecated_endpoint

400Bad request

This endpoint has been deprecated

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "deprecated_endpoint",
  "error_message": "This endpoint has been deprecated",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/deprecated_endpoint"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_email

400Bad request

A user with the specified email already exists for this project.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_email",
  "error_message": "A user with the specified email already exists for this project.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_email"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_email_for_user

400Bad request

The specified email is already tied to this user.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_email_for_user",
  "error_message": "The specified email is already tied to this user.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_email_for_user"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_email_template_vanity_id

400Bad request

Email template vanity ID already exists.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_email_template_vanity_id",
  "error_message": "Email template vanity ID already exists.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_email_template_vanity_id"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_member_email

400Bad request

This email already exists for this organization.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_member_email",
  "error_message": "This email already exists for this organization.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_member_email"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_organization

400Bad request

An organization with the specified name already exists.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_organization",
  "error_message": "An organization with the specified name already exists.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_organization"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_organization_user

400Bad request

A user with the specified email already exists for this organization.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_organization_user",
  "error_message": "A user with the specified email already exists for this organization.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_organization_user"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_project_user

400Bad request

A project user for the specified organization user already exists for this project.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_project_user",
  "error_message": "A project user for the specified organization user already exists for this project.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_project_user"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_redirect_url

400Bad request

A redirect URL already exists for the provided URL.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_redirect_url",
  "error_message": "A redirect URL already exists for the provided URL.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_redirect_url"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_saml_connection

400Bad request

The SAML connection already exists for this organization and IDP.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_saml_connection",
  "error_message": "The SAML connection already exists for this organization and IDP.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_saml_connection"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_saml_response

400Bad request

This SAML response has already been seen. Please attempt to log in again.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_saml_response",
  "error_message": "This SAML response has already been seen. Please attempt to log in again.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_saml_response"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

duplicate_webauthn_registration

400Bad request

The supplied credential ID already exists for this project.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "duplicate_webauthn_registration",
  "error_message": "The supplied credential ID already exists for this project.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/duplicate_webauthn_registration"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

expired_oidc_response

400Bad request

Too much time has passed since the login flow started. Please attempt to log in again.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "expired_oidc_response",
  "error_message": "Too much time has passed since the login flow started. Please attempt to log in again.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/expired_oidc_response"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

expired_saml_response

400Bad request

Too much time has passed since the login flow started. Please attempt to log in again.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "expired_saml_response",
  "error_message": "Too much time has passed since the login flow started. Please attempt to log in again.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/expired_saml_response"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

expired_totp

400Bad request

The TOTP for this user has expired without being verified.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "expired_totp",
  "error_message": "The TOTP for this user has expired without being verified.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/expired_totp"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

failed_saml_response

400Bad request

The user failed to log in to their IDP, or the IDP failed to authenticate the application.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "failed_saml_response",
  "error_message": "The user failed to log in to their IDP, or the IDP failed to authenticate the application.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/failed_saml_response"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

id_token_expired

400Bad request

ID token is expired.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "id_token_expired",
  "error_message": "ID token is expired.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/id_token_expired"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

id_token_incorrect_audience

400Bad request

ID token's audience does not match the OAuth configuration's ID.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "id_token_incorrect_audience",
  "error_message": "ID token's audience does not match the OAuth configuration's ID.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/id_token_incorrect_audience"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

id_token_invalid

400Bad request

ID token is invalid.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "id_token_invalid",
  "error_message": "ID token is invalid.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/id_token_invalid"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

id_token_nonce_invalid

400Bad request

The provided nonce does not match the nonce in the ID token.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "id_token_nonce_invalid",
  "error_message": "The provided nonce does not match the nonce in the ID token.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/id_token_nonce_invalid"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

inactive_email

400Bad request

The email provided has been marked as inactive by our email provider. This happens most often when the email is undeliverable due to a hard bounce.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "inactive_email",
  "error_message": "The email provided has been marked as inactive by our email provider. This happens most often when the email is undeliverable due to a hard bounce.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/inactive_email"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

indeterminate_sso_connection_for_organization

400Bad request

The organization owns more than one SSO Connection. Please specify the specific connection to be used.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "indeterminate_sso_connection_for_organization",
  "error_message": "The organization owns more than one SSO Connection. Please specify the specific connection to be used.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/indeterminate_sso_connection_for_organization"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

invalid_append_salt

400Bad request

The append_salt value is not supported because it's too long.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "invalid_append_salt",
  "error_message": "The append_salt value is not supported because it's too long.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/invalid_append_salt"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

invalid_argon_2_iteration_amount

400Bad request

The iteration_amount value is invalid.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "invalid_argon_2_iteration_amount",
  "error_message": "The iteration_amount value is invalid.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/invalid_argon_2_iteration_amount"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

invalid_argon_2_key_length

400Bad request

The key_length value is invalid.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "invalid_argon_2_key_length",
  "error_message": "The key_length value is invalid.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/invalid_argon_2_key_length"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

invalid_argon_2_memory

400Bad request

The memory value is invalid.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "invalid_argon_2_memory",
  "error_message": "The memory value is invalid.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/invalid_argon_2_memory"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

invalid_argon_2_salt

400Bad request

The salt value is an unsupported length.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "invalid_argon_2_salt",
  "error_message": "The salt value is an unsupported length.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/invalid_argon_2_salt"
}
How to get help
Visit our forum
Stytch Forum

Send us an email
support@stytch.com

Ask in Slack
Slack

invalid_argon_2_threads

400Bad request

The threads value is invalid.

Error

{
  "status_code": 400,
  "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
  "error_type": "invalid_argon_2_threads",
  "error_message": "The threads value is invalid.",
  "error_url": "https://stytch.com/docs/b2b/api/errors/400/invalid_argon_2_threads"
}
How to get help