A signup form sends a phone number to a check and gets back something that is not a clean pass. The decision is what your signup code does next: continue, retry, route to review, or hand off to an OTP provider you already run. This article walks through the four synthetic branches of the downloadable example, lists the exact fixture outputs, and separates what the example implements from what your application must design. It also explains why phone validity is not possession or identity, especially on the current free production route.
The problem: one call, four different meanings
Many signup handlers reduce a phone check to pass or reject. That shortcut breaks as soon as the check cannot answer. The result might be unknown, or the provider call might have failed. Rejecting both turns a temporary gap into a lost signup. Letting both through without any next step treats missing evidence as success. Your decision is to treat the result as four branches, not two outcomes, and to give each branch an owner. The example models these as normal, unknown, provider_failure and otp. Every branch returns mode synthetic_fixture, otp_sent false and live_line_type_available false. The interesting fields are state, valid, line_type and next.
Validity is not possession or identity
A phone check describes the number. It does not establish that the person typing controls it, that it can receive a message, or who that person is. Possession needs a separate proof, such as an OTP sent by a provider you already use. Identity needs a separate identity check. The current free production route, Basic Lookup, is offered to eligible businesses as an application adjunct with a technical rate limit of 60 requests per minute. It does not request line type, ownership, reachability or OTP delivery. That is why the fixture's normal branch shows line_type mobile only as a synthetic value, while live_line_type_available stays false. Do not build a rule that depends on line type from the free route.
A worked hypothetical scenario with expected fixture outputs
Hypothetical: a small B2B tool adds a phone field to account creation and runs the four branches locally before wiring any real lookup. The example needs Python 3.10 or later, no credentials and no network. Expected outputs: normal returns state simulated, valid true, line_type mobile, next continue_customer_policy. Unknown returns state unknown, valid null, line_type null, next review_or_existing_otp. Provider_failure returns state unknown, valid null, line_type null, next bounded_retry_then_review. Otp returns state unsupported, valid null, line_type null, next customer_otp_provider. Note that unknown and provider_failure share state and valid; only next distinguishes them. Your code must branch on next, not on valid alone. An unsupported branch name raises UNSUPPORTED_FIXTURE.
Failure handling without automatic rejection
Proposed application design, not implemented behavior: for unknown, keep the signup in a pending state and either queue human review or, if your policy allows, ask your existing OTP provider for a possession check. For provider_failure, retry a small, fixed number of times with a delay, then move to review; never loop indefinitely. For otp, call your own OTP provider; the fixture never sends a code, and otp_sent is always false. For normal, apply your own policy; valid true is one input, not approval. Log the branch and next value with each attempt so reviewers can see why a signup paused. The example only names these next steps. Retry counts, review queues and OTP calls belong to your application.
What the example does and does not prove
Implemented: a local function returning fixed synthetic results for four branches, plus engineering tests that cover simulated transitions. Not implemented: any live lookup, provider adapter, OTP sending or real line type. The tests do not prove production success, external adoption or live route availability, which needs separate confirmation. A passing local run means your handler reads the fields correctly. It does not mean a real number was checked or that any business permission exists.
Acceptance checklist
Before wiring a real route: 1. All four branches run locally and match the expected outputs above. 2. Your handler branches on next and treats valid null as no conclusion, never as invalid. 3. Unknown and provider_failure never cause automatic rejection. 4. Provider_failure has a bounded retry count, then review. 5. The otp branch calls your existing provider and your UI never assumes a code was sent by the check. 6. No rule depends on line type from the free route. 7. Nothing in your records labels a valid number as owned or as an identity. 8. Your request rate stays under 60 per minute. 9. Live availability is confirmed separately before any real signup depends on it.
Disclosure: this tutorial was drafted with AI and checked against executable local examples and an independent factual review. Sample values are test inputs, not verified people or accounts. Application policy remains the caller’s responsibility.
Top comments (0)