Skip to main content

Verifying user contact details

Verifying user contact details

Contents

Overview

A user account holds two contact details which can be confirmed as belonging to the account holder:

  • the user's email address, held in the username field
  • the user's phone number, held in the phone_number field

Verification confirms that the person using the account actually controls the address or number on it. This matters for password resets, transactional messaging, marketing consent and for de-duplicating accounts.

Each contact detail has its own verification status field on the user (email_status and phone_number_status), and each is verified through its own delivery channel: email addresses are verified by email, phone numbers by SMS. Verification is always started by the client application (for example your webshop, app or the Spaaza white-label mobile app) on behalf of a signed-in user, and is enabled per business.

Verification methods

Contact detailMethodDelivered byEndpoints
Email addressOne-time passcodeEmailotp-request then otp-verify
Email addressVerification linkEmailemail-verify-request then email-verify
Phone numberOne-time passcodeSMSotp-request then otp-verify

A one-time passcode ("OTP") is a 6-digit code which the user reads from the message and types back into your application, which then submits it to Spaaza. A verification link is a signed, single-use link which verifies the address when the user opens it, with nothing for the user to type.

Enabling verification for a chain

Verification is switched on per chain, and the chain setting is the single source of truth for which flow applies. Both settings can be read with get-chain and set with alter-chain:

SettingValuesEffect
email_verification_methodoff, otp or deeplinkSelects the email verification flow. off (the default) disables email verification.
verify_phone_numberstrue or falseEnables phone number verification by SMS OTP. Default is false.

Because the chain setting is enforced by the endpoints, a chain configured for otp cannot use the verification-link endpoints, and a chain configured for deeplink cannot use the email OTP purpose on otp-request. Requests to the wrong flow are rejected with the email_verification_not_enabled error (code 559). Clients can read email_verification_method from get-chain to decide which flow to present to the user.

Sending the messages themselves also has to be configured for the chain: the verification email and SMS messages are delivered by Spaaza's notification service, and SMS additionally requires an SMS provider (see SMS Service Integrations). Contact Spaaza to have email or SMS verification switched on for your business.

Verifying an email address with a one-time passcode

Used when the chain's email_verification_method is otp.

  1. Request a code. Call otp-request with purpose set to email_verification_rate_limit, the user's email, and user_id and chain_id. The email address supplied must match the email address on the account. The response contains a verification_code_key, the expiry date of the code, and the number of seconds until another code can be requested.
  2. Spaaza emails the code. The user receives an email containing the 6-digit code.
  3. Verify the code. Collect the code from the user and call otp-verify with the verification_code and the verification_code_key from step 1. On success the user's email_status is set to 1 (verified).

Used when the chain's email_verification_method is deeplink.

  1. Request a verification email. Call email-verify-request with user_id and chain_id. No email address is passed: the address used is the one on the account.
  2. Spaaza emails the link. The user receives an email containing a "Verify email" button. The link carries a signed, single-use verification token, is valid for 3 days, and points at a Spaaza verification page which completes the flow.
  3. Verify the link. The page which the user lands on calls email-verify with the user's username and the token from the link. On success the user's email_status is set to 1 (verified).

Requesting a new verification email does not invalidate links from earlier emails: each link stays valid until it is used or expires.

Verifying a phone number

Used when the chain has verify_phone_numbers enabled. The flow is the same OTP flow as for email addresses, with the code delivered by SMS:

  1. A phone number is saved. When add-user or alter-user stores a new or changed phone number for a chain with verification enabled, the response includes a phone_results object containing a verification_code_key, and Spaaza sends a verification code by SMS.
  2. Request a further code if needed. Call otp-request with purpose set to phone_number_verification_rate_limit, the number in e164PhoneNumber, and user_id and chain_id.
  3. Verify the code. Call otp-verify with the verification_code and verification_code_key. On success the user's phone_number_status is set to 3 (verified).

For the SMS providers available and how sending is configured, see SMS Service Integrations.

Verification is separate from uniqueness. A chain can also require that a phone number is used by only one account, by setting require_unique_phone_number to true with alter-chain. When that setting is enabled, add-user and alter-user reject a phone number which is already held by another active account with the phone_number_already_exists error (code 555), instead of only flagging it through phone_number_duplicate. There is no equivalent setting for email addresses, because a duplicate email address (username) is always rejected with the user_already_exists error (code 234).

Verification status fields

Both status fields are returned in the user_info object by get-user, add-user and alter-user.

email_status — integer:

  • 0 (unverified) — the email address has not been confirmed by the user. This is the default for new and existing accounts.
  • 1 (verified) — the email address was confirmed by the user, using either email verification method.

phone_number_status — integer:

  • 0 (unchecked) — the phone number has not been validated.
  • 1 (invalid) — the phone number failed validation (legacy API versions only).
  • 2 (validated) — the phone number is a valid, correctly formatted number, but has not been confirmed by the user.
  • 3 (verified) — the phone number was confirmed by the user with an OTP code.

Changing the contact detail resets its status, because a previous verification no longer applies to the new value:

  • Changing a user's email address (username) resets email_status to 0. This applies to every way an email address can change, including add-user, alter-user, user imports and webshop synchronisation.
  • Changing a user's phone number re-evaluates phone_number_status. Re-submitting the same, already-verified number keeps the VERIFIED status.

Rate limits and code validity

LimitValue
Requests for a code or verification email1 per 60 seconds, counted per contact detail and per user
One-time passcode validity5 minutes
One-time passcode attempts5, after which the code is invalidated and a new one is needed
Verification link validity3 days, single use

Exceeding the request limit returns email_verification_rate_limit_exceeded (code 557) for email verification, or phone_number_verification_rate_limit_exceeded (code 548) for phone number verification.

PageDescription
otp-requestRequest a one-time passcode for an email address or a phone number.
otp-verifyVerify a one-time passcode.
email-verify-requestRequest a verification link to be emailed to a user.
email-verifyVerify an email address from a verification link.
alter-chainConfigure email_verification_method and verify_phone_numbers for a chain.
SMS Service IntegrationsSMS providers used to deliver phone number verification codes.