openapi: 3.0.3
info:
title: Stytch B2B Authentication Application B2B OTP API
version: 2.0.0
description: Stytch's B2B API for multi-tenant authentication. Supports Organizations, Members, SSO (SAML/OIDC), Magic Links, OTP, OAuth, Discovery, Sessions, B2B RBAC, SCIM, TOTP, Recovery Codes, Passwords, Impersonation, and the B2B IDP.
contact:
name: Stytch
url: https://stytch.com/docs
license:
name: Proprietary
servers:
- url: https://api.stytch.com
description: Production
- url: https://test.stytch.com
description: Test
tags:
- name: B2B OTP
paths:
/v1/b2b/otps/sms/send:
post:
summary: Send
operationId: api_b2b_otp_v1_b2b_otp_sms_Send
tags:
- B2B OTP
description: "Send a One-Time Passcode (OTP) to a Member's phone number.\n\nIf the Member already has a phone number, the `mfa_phone_number` field is not needed; the endpoint will send an OTP to the number associated with the Member.\nIf the Member does not have a phone number, the endpoint will send an OTP to the `mfa_phone_number` provided and link the `mfa_phone_number` with the Member.\n\nAn error will be thrown if the Member already has a phone number and the provided `mfa_phone_number` does not match the existing one.\n\nOTP codes expire after two minutes. Note that sending another OTP code before the first has expired will invalidate the first code.\n\nIf a Member has a phone number and is enrolled in MFA, then after a successful primary authentication event (e.g. [email magic link](https://stytch.com/docs/b2b/api/authenticate-magic-link) or [SSO](https://stytch.com/docs/b2b/api/sso-authenticate) login is complete), an SMS OTP will automatically be sent to their phone number. In that case, this endpoint should only be used for subsequent authentication events, such as prompting a Member for an OTP again after a period of inactivity.\n\nIf the Member already has an active MFA factor, then passing an intermediate session token, session token, or session JWT with the existing MFA factor on it is required to prevent bypassing MFA. \n\nOtherwise, passing an intermediate session token, session token, or session JWT is not required, but if passed must match the `member_id` passed.\n\n### Cost to send SMS OTP\nBefore configuring SMS or WhatsApp OTPs, please review how Stytch [bills the costs of international OTPs](https://stytch.com/pricing) and understand how to protect your app against [toll fraud](https://stytch.com/docs/guides/passcodes/toll-fraud/overview).\n\nEven when international SMS is enabled, we do not support sending SMS to countries on our [Unsupported countries list](https://stytch.com/docs/guides/passcodes/unsupported-countries).\n\n__Note:__ SMS to phone numbers outside of the US and Canada is disabled by default for customers who did not use SMS prior to October 2023. If you're interested in sending international SMS, please add those countries to your Project's allowlist via the [Dashboard](https://stytch.com/dashboard/country-code-allowlists) or [Programmatic Workspace Actions](https://stytch.com/docs/workspace-management/pwa/set-allowed-country-codes), and [add credit card details](https://stytch.com/dashboard/settings/billing) to your account."
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_sms_SendRequest'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_sms_SendResponse'
'400':
description: Bad request
'401':
description: Unauthorized
content:
application/json:
example:
status_code: 401
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: unauthorized_credentials
error_message: Unauthorized credentials.
error_url: https://stytch.com/docs/api/errors/401
'429':
description: Too Many Requests
content:
application/json:
example:
status_code: 429
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: too_many_requests
error_message: Too many requests have been made.
error_url: https://stytch.com/docs/api/errors/429
'500':
description: Internal server error
content:
application/json:
example:
status_code: 500
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: internal_server_error
error_message: Oops, something seems to have gone wrong, please reach out to support@stytch.com to let us know what went wrong.
error_url: https://stytch.com/docs/api/errors/500
x-code-samples:
- lang: csharp
label: C#
source: "// POST /v1/b2b/otps/sms/send\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n};\n\nclient.OTPs.Sms.Send(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: go
label: Go
source: "// POST /v1/b2b/otps/sms/send\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/b2bstytchapi\"\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/otp/sms\"\n)\n\nfunc main() {\n\tclient, err := b2bstytchapi.NewClient(\n\t\t\"${projectId}\",\n\t\t\"${secret}\",\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"error instantiating client: %v\", err)\n\t}\n\n\tparams := &sms.SendParams{\n\t\tOrganizationID: \"${organizationId}\",\n\t\tMemberID: \"${memberId}\",\n\t}\n\n\tresp, err := client.OTPs.Sms.Send(context.Background(), params)\n\tif err != nil {\n\t\tlog.Fatalf(\"error in method call: %v\", err)\n\t}\n\n\tlog.Println(resp)\n}\n"
- lang: java
label: Java
source: "// POST /v1/b2b/otps/sms/send\npackage com.example;\n\nimport com.stytch.java.b2b.models.otpsms.SendRequest;\nimport com.stytch.java.b2b.StytchB2BClient;\nimport com.stytch.java.common.StytchResult;\n\npublic class Main {\n public static void main(String[] args) {\n StytchB2BClient.configure(\"${projectId}\", \"${secret}\");\n\n SendRequest params = new SendRequest();\n params.setOrganizationId(\"${organizationId}\");\n params.setMemberId(\"${memberId}\");\n\n Object result = StytchB2BClient.getOTPs().getSms().send(params);\n if (result instanceof StytchResult.Success) {\n System.out.println(((StytchResult.Success) result).getValue());\n } else {\n System.out.println(((StytchResult.Error) result).getException());\n }\n }\n}"
- lang: kotlin
label: Kotlin
source: "// POST /v1/b2b/otps/sms/send\npackage com.example\n\nimport com.stytch.java.b2b.StytchB2BClient\nimport com.stytch.java.b2b.models.otpsms.SendRequest\n\nfun main() {\n StytchB2BClient.configure(\n projectId = \"${projectId}\",\n secret = \"${secret}\",\n )\n\n when (\n val result =\n StytchB2BClient.otps.sms.send(\n SendRequest(\n organizationId = \"${organizationId}\",\n memberId = \"${memberId}\",\n ),\n )\n ) {\n is StytchResult.Success -> println(result.value)\n is StytchResult.Error -> println(result.exception)\n }\n}\n"
- lang: javascript
label: Node.js
source: "// POST /v1/b2b/otps/sms/send\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n};\n\nclient.otps.sms.send(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: php
label: PHP
source: "$response = $client->otps->sms->send([\n 'organization_id' => '${organizationId}',\n 'member_id' => '${memberId}',\n]);"
- lang: python
label: Python
source: "# POST /v1/b2b/otps/sms/send\nfrom stytch import B2BClient\n\nclient = B2BClient(\n project_id=\"${projectId}\",\n secret=\"${secret}\",\n)\n\nresp = client.otps.sms.send(\n organization_id=\"${organizationId}\",\n member_id=\"${memberId}\",\n)\n\nprint(resp)\n"
- lang: ruby
label: Ruby
source: "# POST /v1/b2b/otps/sms/send\nrequire 'stytch'\n\nclient = StytchB2B::Client.new(\n project_id: \"${projectId}\",\n secret: \"${secret}\"\n)\n\nresp = client.otps.sms.send(\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\"\n \n)\n\nputs resp"
- lang: rust
label: Rust
source: "// POST /v1/b2b/otps/sms/send\nuse stytch::b2b::client::Client;\nuse stytch::b2b::otp_sms::SendRequest;\n\nfn main() {\n let client = Client::new(\"${projectId}\", \"${secret}\").unwrap();\n let resp = client.otps.sms.send(\n SendRequest{\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n ..Default::default()\n }\n ).await;\n println!(\"The response is {:?}\", resp);\n}"
- lang: bash
label: cURL
source: "# POST /v1/b2b/otps/sms/send\ncurl --request POST \\\n --url https://test.stytch.com/v1/b2b/otps/sms/send \\\n -u '${projectId}:${secret}' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"organization_id\": \"${organizationId}\",\n \"member_id\": \"${memberId}\"\n }'"
/v1/b2b/otps/sms/authenticate:
post:
summary: Authenticate
operationId: api_b2b_otp_v1_b2b_otp_sms_Authenticate
tags:
- B2B OTP
description: 'SMS OTPs may not be used as a primary authentication mechanism. They can be used to complete an MFA requirement, or they can be used as a step-up factor to be added to an existing session.
This endpoint verifies that the one-time passcode (OTP) is valid and hasn''t expired or been previously used. OTP codes expire after two minutes.
A given Member may only have a single active OTP code at any given time. If a Member requests another OTP code before the first one has expired, the first one will be invalidated.
Exactly one of `intermediate_session_token`, `session_token`, or `session_jwt` must be provided in the request.
If an intermediate session token is provided, this operation will consume it.
Intermediate session tokens are generated upon successful calls to primary authenticate methods in the case where MFA is required,
such as [email magic link authenticate](https://stytch.com/docs/b2b/api/authenticate-magic-link),
or upon successful calls to discovery authenticate methods, such as [email magic link discovery authenticate](https://stytch.com/docs/b2b/api/authenticate-discovery-magic-link).
If the Organization''s MFA policy is `REQUIRED_FOR_ALL`, a successful OTP authentication will change the Member''s `mfa_enrolled` status to `true` if it is not already `true`.
If the Organization''s MFA policy is `OPTIONAL`, the Member''s MFA enrollment can be toggled by passing in a value for the `set_mfa_enrollment` field.
The Member''s MFA enrollment can also be toggled through the [Update Member](https://stytch.com/docs/b2b/api/update-member) endpoint.
Provide 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 duration of 60 minutes.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_sms_AuthenticateRequest'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_sms_AuthenticateResponse'
'400':
description: Bad request
'401':
description: Unauthorized
content:
application/json:
example:
status_code: 401
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: unauthorized_credentials
error_message: Unauthorized credentials.
error_url: https://stytch.com/docs/api/errors/401
'429':
description: Too Many Requests
content:
application/json:
example:
status_code: 429
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: too_many_requests
error_message: Too many requests have been made.
error_url: https://stytch.com/docs/api/errors/429
'500':
description: Internal server error
content:
application/json:
example:
status_code: 500
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: internal_server_error
error_message: Oops, something seems to have gone wrong, please reach out to support@stytch.com to let us know what went wrong.
error_url: https://stytch.com/docs/api/errors/500
x-code-samples:
- lang: csharp
label: C#
source: "// POST /v1/b2b/otps/sms/authenticate\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n code: \"${exampleCode}\",\n intermediate_session_token: \"${token}\",\n};\n\nclient.OTPs.Sms.Authenticate(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: go
label: Go
source: "// POST /v1/b2b/otps/sms/authenticate\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/b2bstytchapi\"\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/otp/sms\"\n)\n\nfunc main() {\n\tclient, err := b2bstytchapi.NewClient(\n\t\t\"${projectId}\",\n\t\t\"${secret}\",\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"error instantiating client: %v\", err)\n\t}\n\n\tparams := &sms.AuthenticateParams{\n\t\tOrganizationID: \"${organizationId}\",\n\t\tMemberID: \"${memberId}\",\n\t\tCode: \"${exampleCode}\",\n\t\tIntermediateSessionToken: \"${token}\",\n\t}\n\n\tresp, err := client.OTPs.Sms.Authenticate(context.Background(), params)\n\tif err != nil {\n\t\tlog.Fatalf(\"error in method call: %v\", err)\n\t}\n\n\tlog.Println(resp)\n}\n"
- lang: java
label: Java
source: "// POST /v1/b2b/otps/sms/authenticate\npackage com.example;\n\nimport com.stytch.java.b2b.models.otpsms.AuthenticateRequest;\nimport com.stytch.java.b2b.StytchB2BClient;\nimport com.stytch.java.common.StytchResult;\n\npublic class Main {\n public static void main(String[] args) {\n StytchB2BClient.configure(\"${projectId}\", \"${secret}\");\n\n AuthenticateRequest params = new AuthenticateRequest();\n params.setOrganizationId(\"${organizationId}\");\n params.setMemberId(\"${memberId}\");\n params.setCode(\"${exampleCode}\");\n params.setIntermediateSessionToken(\"${token}\");\n\n Object result = StytchB2BClient.getOTPs().getSms().authenticate(params);\n if (result instanceof StytchResult.Success) {\n System.out.println(((StytchResult.Success) result).getValue());\n } else {\n System.out.println(((StytchResult.Error) result).getException());\n }\n }\n}"
- lang: kotlin
label: Kotlin
source: "// POST /v1/b2b/otps/sms/authenticate\npackage com.example\n\nimport com.stytch.java.b2b.StytchB2BClient\nimport com.stytch.java.b2b.models.otpsms.AuthenticateRequest\n\nfun main() {\n StytchB2BClient.configure(\n projectId = \"${projectId}\",\n secret = \"${secret}\",\n )\n\n when (\n val result =\n StytchB2BClient.otps.sms.authenticate(\n AuthenticateRequest(\n organizationId = \"${organizationId}\",\n memberId = \"${memberId}\",\n code = \"${exampleCode}\",\n intermediateSessionToken = \"${token}\",\n ),\n )\n ) {\n is StytchResult.Success -> println(result.value)\n is StytchResult.Error -> println(result.exception)\n }\n}\n"
- lang: javascript
label: Node.js
source: "// POST /v1/b2b/otps/sms/authenticate\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n code: \"${exampleCode}\",\n intermediate_session_token: \"${token}\",\n};\n\nclient.otps.sms.authenticate(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: php
label: PHP
source: "$response = $client->otps->sms->authenticate([\n 'organization_id' => '${organizationId}',\n 'member_id' => '${memberId}',\n 'code' => '${exampleCode}',\n 'intermediate_session_token' => '${token}',\n]);"
- lang: python
label: Python
source: "# POST /v1/b2b/otps/sms/authenticate\nfrom stytch import B2BClient\n\nclient = B2BClient(\n project_id=\"${projectId}\",\n secret=\"${secret}\",\n)\n\nresp = client.otps.sms.authenticate(\n organization_id=\"${organizationId}\",\n member_id=\"${memberId}\",\n code=\"${exampleCode}\",\n intermediate_session_token=\"${token}\",\n)\n\nprint(resp)\n"
- lang: ruby
label: Ruby
source: "# POST /v1/b2b/otps/sms/authenticate\nrequire 'stytch'\n\nclient = StytchB2B::Client.new(\n project_id: \"${projectId}\",\n secret: \"${secret}\"\n)\n\nresp = client.otps.sms.authenticate(\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n code: \"${exampleCode}\",\n intermediate_session_token: \"${token}\"\n \n)\n\nputs resp"
- lang: rust
label: Rust
source: "// POST /v1/b2b/otps/sms/authenticate\nuse stytch::b2b::client::Client;\nuse stytch::b2b::otp_sms::AuthenticateRequest;\n\nfn main() {\n let client = Client::new(\"${projectId}\", \"${secret}\").unwrap();\n let resp = client.otps.sms.authenticate(\n AuthenticateRequest{\n organization_id: \"${organizationId}\",\n member_id: \"${memberId}\",\n code: \"${exampleCode}\",\n intermediate_session_token: Some(String::from(\"${token}\")),\n ..Default::default()\n }\n ).await;\n println!(\"The response is {:?}\", resp);\n}"
- lang: bash
label: cURL
source: "# POST /v1/b2b/otps/sms/authenticate\ncurl --request POST \\\n --url https://test.stytch.com/v1/b2b/otps/sms/authenticate \\\n -u '${projectId}:${secret}' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"organization_id\": \"${organizationId}\",\n \"member_id\": \"${memberId}\",\n \"code\": \"${exampleCode}\",\n \"intermediate_session_token\": \"${token}\"\n }'"
/v1/b2b/otps/email/login_or_signup:
post:
summary: Loginorsignup
operationId: api_b2b_otp_v1_b2b_otp_email_LoginOrSignup
tags:
- B2B OTP
description: 'Send either a login or signup email OTP to a Member. A new, pending, or invited Member will receive a signup email OTP. Non-active members will have a pending status until they successfully authenticate. An active Member will receive a login email OTP.
The OTP is valid for 10 minutes. Only the most recently sent OTP is valid: when an OTP is sent, all OTPs previously sent to the same email address are invalidated, even if unused or unexpired.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_email_LoginOrSignupRequest'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_email_LoginOrSignupResponse'
'400':
description: Bad request
'401':
description: Unauthorized
content:
application/json:
example:
status_code: 401
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: unauthorized_credentials
error_message: Unauthorized credentials.
error_url: https://stytch.com/docs/api/errors/401
'429':
description: Too Many Requests
content:
application/json:
example:
status_code: 429
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: too_many_requests
error_message: Too many requests have been made.
error_url: https://stytch.com/docs/api/errors/429
'500':
description: Internal server error
content:
application/json:
example:
status_code: 500
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: internal_server_error
error_message: Oops, something seems to have gone wrong, please reach out to support@stytch.com to let us know what went wrong.
error_url: https://stytch.com/docs/api/errors/500
x-code-samples:
- lang: csharp
label: C#
source: "// POST /v1/b2b/otps/email/login_or_signup\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n email_address: \"${email}\",\n};\n\nclient.OTPs.Email.LoginOrSignup(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: go
label: Go
source: "// POST /v1/b2b/otps/email/login_or_signup\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/b2bstytchapi\"\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/otp/email\"\n)\n\nfunc main() {\n\tclient, err := b2bstytchapi.NewClient(\n\t\t\"${projectId}\",\n\t\t\"${secret}\",\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"error instantiating client: %v\", err)\n\t}\n\n\tparams := &email.LoginOrSignupParams{\n\t\tOrganizationID: \"${organizationId}\",\n\t\tEmailAddress: \"${email}\",\n\t}\n\n\tresp, err := client.OTPs.Email.LoginOrSignup(context.Background(), params)\n\tif err != nil {\n\t\tlog.Fatalf(\"error in method call: %v\", err)\n\t}\n\n\tlog.Println(resp)\n}\n"
- lang: java
label: Java
source: "// POST /v1/b2b/otps/email/login_or_signup\npackage com.example;\n\nimport com.stytch.java.b2b.models.otpemail.LoginOrSignupRequest;\nimport com.stytch.java.b2b.StytchB2BClient;\nimport com.stytch.java.common.StytchResult;\n\npublic class Main {\n public static void main(String[] args) {\n StytchB2BClient.configure(\"${projectId}\", \"${secret}\");\n\n LoginOrSignupRequest params = new LoginOrSignupRequest();\n params.setOrganizationId(\"${organizationId}\");\n params.setEmailAddress(\"${email}\");\n\n Object result = StytchB2BClient.getOTPs().getEmail().loginOrSignup(params);\n if (result instanceof StytchResult.Success) {\n System.out.println(((StytchResult.Success) result).getValue());\n } else {\n System.out.println(((StytchResult.Error) result).getException());\n }\n }\n}"
- lang: kotlin
label: Kotlin
source: "// POST /v1/b2b/otps/email/login_or_signup\npackage com.example\n\nimport com.stytch.java.b2b.StytchB2BClient\nimport com.stytch.java.b2b.models.otpemail.LoginOrSignupRequest\n\nfun main() {\n StytchB2BClient.configure(\n projectId = \"${projectId}\",\n secret = \"${secret}\",\n )\n\n when (\n val result =\n StytchB2BClient.otps.email.loginOrSignup(\n LoginOrSignupRequest(\n organizationId = \"${organizationId}\",\n emailAddress = \"${email}\",\n ),\n )\n ) {\n is StytchResult.Success -> println(result.value)\n is StytchResult.Error -> println(result.exception)\n }\n}\n"
- lang: javascript
label: Node.js
source: "// POST /v1/b2b/otps/email/login_or_signup\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n email_address: \"${email}\",\n};\n\nclient.otps.email.loginOrSignup(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: php
label: PHP
source: "$response = $client->otps->email->login_or_signup([\n 'organization_id' => '${organizationId}',\n 'email_address' => '${email}',\n]);"
- lang: python
label: Python
source: "# POST /v1/b2b/otps/email/login_or_signup\nfrom stytch import B2BClient\n\nclient = B2BClient(\n project_id=\"${projectId}\",\n secret=\"${secret}\",\n)\n\nresp = client.otps.email.login_or_signup(\n organization_id=\"${organizationId}\",\n email_address=\"${email}\",\n)\n\nprint(resp)\n"
- lang: ruby
label: Ruby
source: "# POST /v1/b2b/otps/email/login_or_signup\nrequire 'stytch'\n\nclient = StytchB2B::Client.new(\n project_id: \"${projectId}\",\n secret: \"${secret}\"\n)\n\nresp = client.otps.email.login_or_signup(\n organization_id: \"${organizationId}\",\n email_address: \"${email}\"\n \n)\n\nputs resp"
- lang: rust
label: Rust
source: "// POST /v1/b2b/otps/email/login_or_signup\nuse stytch::b2b::client::Client;\nuse stytch::b2b::otp_email::LoginOrSignupRequest;\n\nfn main() {\n let client = Client::new(\"${projectId}\", \"${secret}\").unwrap();\n let resp = client.otps.email.login_or_signup(\n LoginOrSignupRequest{\n organization_id: \"${organizationId}\",\n email_address: \"${email}\",\n ..Default::default()\n }\n ).await;\n println!(\"The response is {:?}\", resp);\n}"
- lang: bash
label: cURL
source: "# POST /v1/b2b/otps/email/login_or_signup\ncurl --request POST \\\n --url https://test.stytch.com/v1/b2b/otps/email/login_or_signup \\\n -u '${projectId}:${secret}' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"organization_id\": \"${organizationId}\",\n \"email_address\": \"${email}\"\n }'"
/v1/b2b/otps/email/authenticate:
post:
summary: Authenticate
operationId: api_b2b_otp_v1_b2b_otp_email_Authenticate
tags:
- B2B OTP
description: "Authenticate a Member with a one-time passcode (OTP). This endpoint requires an OTP that is not expired or previously used. \nOTPs have a default expiry of 10 minutes. If the Member's status is `pending` or `invited`, they will be updated to `active`.\nProvide 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.\n\nIf the Member is required to complete MFA to log in to the Organization, the returned value of `member_authenticated` will be `false`, and an `intermediate_session_token` will be returned.\nThe `intermediate_session_token` can be passed into the [OTP SMS Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-otp-sms), [TOTP Authenticate endpoint](https://stytch.com/docs/b2b/api/authenticate-totp), \nor [Recovery Codes Recover endpoint](https://stytch.com/docs/b2b/api/recovery-codes-recover) to complete the MFA step and acquire a full member session.\nThe `intermediate_session_token` can also be used with the [Exchange Intermediate Session endpoint](https://stytch.com/docs/b2b/api/exchange-intermediate-session) or the [Create Organization via Discovery endpoint](https://stytch.com/docs/b2b/api/create-organization-via-discovery) to join a different Organization or create a new one.\nThe `session_duration_minutes` and `session_custom_claims` parameters will be ignored.\n\nIf a valid `session_token` or `session_jwt` is passed in, the Member will not be required to complete an MFA step."
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_email_AuthenticateRequest'
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/api_b2b_otp_v1_b2b_otp_email_AuthenticateResponse'
'400':
description: Bad request
'401':
description: Unauthorized
content:
application/json:
example:
status_code: 401
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: unauthorized_credentials
error_message: Unauthorized credentials.
error_url: https://stytch.com/docs/api/errors/401
'429':
description: Too Many Requests
content:
application/json:
example:
status_code: 429
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: too_many_requests
error_message: Too many requests have been made.
error_url: https://stytch.com/docs/api/errors/429
'500':
description: Internal server error
content:
application/json:
example:
status_code: 500
request_id: request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141
error_type: internal_server_error
error_message: Oops, something seems to have gone wrong, please reach out to support@stytch.com to let us know what went wrong.
error_url: https://stytch.com/docs/api/errors/500
x-code-samples:
- lang: csharp
label: C#
source: "// POST /v1/b2b/otps/email/authenticate\nconst stytch = require('stytch');\n\nconst client = new stytch.B2BClient({\n project_id: '${projectId}',\n secret: '${secret}',\n});\n\nconst params = {\n organization_id: \"${organizationId}\",\n email_address: \"${email}\",\n code: \"${exampleCode}\",\n};\n\nclient.OTPs.Email.Authenticate(params)\n .then(resp => { console.log(resp) })\n .catch(err => { console.log(err) });"
- lang: go
label: Go
source: "// POST /v1/b2b/otps/email/authenticate\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/b2bstytchapi\"\n\t\"github.com/stytchauth/stytch-go/v17/stytch/b2b/otp/email\"\n)\n\nfunc main() {\n\tclient, err := b2bstytchapi.NewClient(\n\t\t\"${projectId}\",\n\t\t\"${secret}\",\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"error instantiating client: %v\", err)\n\t}\n\n\tparams := &email.AuthenticateParams{\n\t\tOrganizationID: \"${organizationId}\",\n\t\tEmailAddress: \"${email}\",\n\t\tCode: \"${exampleCode}\",\n\t}\n\n\tresp, err := client.OTPs.Email.Authenticate(context.Background(), params)\n\tif err != nil {\n\t\tlog.Fatalf(\"error in method call: %v\", err)\n\t}\n\n\tlog.Println(resp)\n}\n"
- lang: java
label: Java
source: "// POST /v1/b2b/otps/email/authenticate\npackage com.example;\n\nimport com.stytch.java.b2b.models.otpemail.Authen
# --- truncated at 32 KB (121 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/stytch/refs/heads/main/openapi/stytch-b2b-otp-api-openapi.yml