Phone verification API versus number validation: where does OTP fit?

Build your integration in the free sandbox before preparing for production.

Your measurement choice is reused on this site and can be turned off. Account association requires separate consent.

Phone verification API versus number validation: where does OTP fit?

A product manager asks for a phone verification API on signup. Before choosing a vendor, decide which question you need answered: what the number is, whether the person can receive a message on it, or who the person is. These are three different proofs. This article compares them, walks through a hypothetical signup using the local synthetic example, lists the exact fixture outputs, covers failure handling and ends with an acceptance checklist. The local example sends no OTP and makes no network calls.

curl https://gridzen.ai/console/api/quickstart/trial \
  -H 'Content-Type: application/json' \
  -d '{"task": "signup_phone", "scenario": "success"}'

Integration guide

The problem: one word, three proofs

"Verify the phone" can mean three things. Number validation describes properties of the number: is it well formed, is it valid, what line type it might be. OTP delivery tests channel access: can whoever is typing receive a code on that channel right now. Identity verification checks a person's claim, usually through a hosted document and liveness journey. None substitutes for another. A valid mobile number does not prove ownership, a received code does not prove who someone is, and an Approved identity result is not unconditional permission. Your decision is which proof the signup task actually needs, and which component owns each one.

What each proof answers, and what GridZen covers today

Number properties: the free Basic Lookup route available to eligible businesses is an application adjunct. It does not request line type, ownership, reachability or OTP delivery, and a technical rate limit of 60 requests per minute applies. Channel access: OTP delivery is unsupported in the local example and is not part of the current free route. If your task needs proof that someone can receive a code, keep or choose your own authorized OTP provider. Identity: hosted identity onboarding is a separate task with its own synthetic example and its own enrollment. Treat these as three components with three owners in your design, not one call that returns "verified".

Hypothetical scenario: a small B2B signup

Imagine a hypothetical team whose signup form asks for a work phone number. Their proposed design: call a number check first, route the result through their own policy, and only send a code through an existing OTP provider when the policy asks for channel proof. Seller payouts, if ever needed, go through identity onboarding later. This is proposed application design, not implemented GridZen behavior. What is implemented is the local four-branch phone fixture in delivery.py, which returns a next step for each branch so the team can wire handlers before any real lookup runs. It runs on Python 3.10 or newer with no credentials or network.

Expected fixture outputs for each branch

Every branch returns mode synthetic_fixture, otp_sent false and live_line_type_available false. The normal branch returns state simulated, valid true, line_type mobile and next continue_customer_policy; the mobile value is synthetic and says nothing about a live line. The unknown branch returns state unknown, valid null, line_type null and next review_or_existing_otp. The provider_failure branch returns state unknown, valid null, line_type null and next bounded_retry_then_review. The otp branch returns state unsupported, valid null, line_type null and next customer_otp_provider. That last value names a component you must supply; no message is sent. An unrecognized branch raises UNSUPPORTED_FIXTURE. Note that this downloadable four-branch example is distinct from the anonymous three-scenario HTTP trial.

Failure handling your application owns

Do not collapse unknown or provider_failure into invalid. Unknown means the check could not answer, so route to review or to an OTP step you already run. Provider failure means the call failed, so retry a bounded number of times, then review. Unsupported means the requested proof does not exist on this route; hand off to your own OTP provider rather than waiting for a code. Never read valid true as ownership or reachability. If you later add identity onboarding, note that its fixture accepts only synthetic fixture_callback events, not real signatures, and its recover step expires sessions locally without polling any provider. Fixture permission records are not live business permission.

Acceptance checklist

Before calling the integration ready for a sandbox request, confirm: all four branches run locally and match the outputs above; otp_sent is false in every result and no screen waits for a code from this fixture; unknown and provider_failure each reach a distinct handler, not rejection; customer_otp_provider maps to a named, authorized OTP provider you control, or the task does not require channel proof; no copy or log claims ownership, reachability or identity from a number check; identity needs are scoped as a separate task; and any live route is confirmed separately, since synthetic results and anonymous trials are not production approval. Tests cover simulated transitions only, not production success.

Run the checked synthetic example

Download and extract https://gridzen.ai/downloads/verification-delivery.zip, enter verification_delivery, then run with Python 3.10+. This local example makes no network calls. Use a fresh database for an independent identity run.

python3 delivery.py phone --branch unknown
python3 delivery.py phone --branch provider_failure

Sources and scope

https://gridzen.ai/guides/phone-otp-identity/ https://gridzen.ai/guides/current-capabilities/ Based on the checked source snapshot and local fixture; proposed application rules are design advice, not proven production behavior. Written with AI assistance and reviewed independently.

Separately try three sandbox outcomes Create an account to continue integrating

A download does not prove a successful run. Local examples and the online sandbox are tested separately.

Connect your app

Run three synthetic outcomes · Get integration help

Connect a free sandbox account

Basic number validity does not prove possession or reachability and does not send OTP. Your app owns the admission decision.