Skip to content
Last updated

Banxa Native supports headless OTP: your app collects the customer's email address, triggers the verification flow server-side, and handles the code entry UI natively. No Banxa-hosted screens, no redirects.

If your app has a login mechanism, the OTP requirement can be disabled entirely — contact your Banxa integration manager. If your app does not have a login mechanism, headless OTP is required before you can process a transaction.


When to use OTP verification

OTP is used to verify a customer's email address as part of identity establishment. It is relevant when:

  • Your app does not have its own login or authentication mechanism and you need Banxa to verify the customer's email access
  • A customer's identity was created without an email address (sparse identity) and you want to collect and verify email via OTP — if you only need to add an email without verification, use the identity patch endpoint instead

If OTP is not enabled on your account, the endpoints return 403 OtpFeatureNotEnabled.


Endpoints

Both endpoints use HMAC authentication. See Authentication for signing details.

ActionEndpoint
Send OTP codePOST /eapi/v1/verifications/otp
Verify OTP codePOST /eapi/v1/verifications/otp/verify

The verification flow

BanxaYour backendAppBanxaYour backendAppCustomer submits emailPOST /eapi/v1/verifications/otp200 { message: "OTP sent successfully" }Email with OTP code (via customer's inbox)Customer enters OTP codeCode submittedPOST /eapi/v1/verifications/otp/verify200 { message: "Success" }Email verified — proceed
BanxaYour backendAppBanxaYour backendAppCustomer submits emailPOST /eapi/v1/verifications/otp200 { message: "OTP sent successfully" }Email with OTP code (via customer's inbox)Customer enters OTP codeCode submittedPOST /eapi/v1/verifications/otp/verify200 { message: "Success" }Email verified — proceed

Step 1 — Send the OTP code

POST /eapi/v1/verifications/otp

{
  "identityReference": "customer-12345",
  "email": "[email protected]"
}
FieldTypeDescription
identityReferencestringYour stable identifier for this customer
emailstringThe email address to verify

Success response (200):

{
  "message": "OTP sent successfully"
}

Banxa sends a short-lived 4-digit code to the provided email address. Your app should prompt the customer to check their inbox and enter the code promptly.

Rate limit: 3 requests per minute per customer.


Step 2 — Verify the OTP code

POST /eapi/v1/verifications/otp/verify

{
  "identityReference": "customer-12345",
  "email": "[email protected]",
  "code": "1234"
}
FieldTypeDescription
identityReferencestringSame value used in the send request
emailstringSame email address used in the send request
codestring4-character code from the email

Success response (200):

{
  "message": "Success"
}

On success, the email address is recorded as verified on the customer's identity. You can proceed with eligibility checks and ramp creation.

Rate limit: 4 verification attempts per minute per customer.


Sparse identity and email collection

OTP can be used to collect and verify a customer's email address after identity creation. An identity created without an email address is valid — the OTP send call writes the email onto the identity record on successful verification.

This pattern is useful when your onboarding flow collects email separately from identity creation:

  1. Create identity via POST /eapi/v0/identities/basic — omit the email field
  2. When ready to verify the customer's email, call POST /eapi/v1/verifications/otp with the identityReference and email
  3. The email is written onto the identity record on successful verification

Email merging

If the email address supplied in the OTP flow already exists on a different Banxa identity record, Banxa merges the two records. The identityReference from the newer identity is moved onto the existing account; the newer identity and its associated externalCustomerId are removed.

Practical effect: after a merge, the identityReference you supplied continues to work, but it now refers to the older account. Any KYC state from the older account is carried over.

What to watch for: if a customer uses an email address that belongs to an existing Banxa account (e.g. they previously transacted via a different partner), the merge will silently absorb their new identity into the existing one. The customer's KYC history is preserved, but be aware that the older account's state governs their compliance tier.


Error handling

Wrong OTP code

A 422 response indicates the code is incorrect:

{
    "message": "Code does not match, please try again",
    "code": 180,
    "traceId": "2f92b534-55a0-4340-9e2a-2575913ff792"
}

An incorrect code cannot be corrected — the OTP flow must restart from the beginning. Call POST /eapi/v1/verifications/otp again to issue a new code before prompting the customer to re-enter.

Rate limit exceeded

A 429 response is returned when the per-minute limit is reached:

{
  "message": "Too many OTP requests. Please try again later.",
  "code": 429,
  "traceId": "9fafad58-f1eb-44db-a77e-329610b1b755"
}
LimitThreshold
OTP send3 per minute per customer
OTP verify4 per minute per customer

Present a clear wait-state to the customer rather than retrying silently.

Feature not enabled

A 403 response means OTP is not enabled on your merchant account. Contact your Banxa integration manager.

Invalid identity reference

A 422 response with "The selected identity reference is invalid." means the identityReference does not exist in Banxa's system. Ensure identity creation has completed successfully before triggering OTP.


Interaction with Banxa Hosted Checkout

If your integration also uses Banxa Hosted Checkout, headless OTP suppresses the email verification screen that Banxa Hosted Checkout would otherwise show to the customer.


Summary

StepEndpointRate limit
1. Send OTPPOST /eapi/v1/verifications/otp3/min
2. Verify codePOST /eapi/v1/verifications/otp/verify4/min

On wrong code: restart from step 1. On rate limit: wait and retry. On success: email is verified on the identity record and the customer can proceed.