Design the action that follows a code check before adding a send button. A completed verification gives your application a code-match result for a recipient. Your application still decides whether the pending action is eligible, authorized and unused.
This guide uses a fictional Fieldnotes customer confirming a new contact address. It also shows how a phone delivery plan changes recovery. Finish with a record your product, engineering and support teams can use to review the complete flow.
Bind the code to a pending action
Record the intended action and exact recipient in application-held state. Include the relevant account context, expiry and whether the action has already been completed. Use that stored recipient for sending and checking rather than accepting an unrelated recipient from the code-entry form.
For Fieldnotes, the pending action is “confirm this new email address for this customer.” If the customer edits the address, create a new application intent and clear the old entry state. A result for the earlier address must not complete the new action.
The sending and checking guide contains the SDK requests and recipient rules. A verification created with both an email address and a phone number must be checked with that same address set.
Select a channel for the purpose
Scroll horizontally to see more columns.
| Purpose or starting recipient | Design decision |
|---|---|
| Confirm a requested email address | Use the email challenge to establish its possession under the pending action |
| Reach a supplied phone number | Inspect the recipient's available plan and choose eligible channels for the destination |
| Offer email-to-phone recovery | Include both eligible addresses in the original recipient and obtain the necessary customer choice |
| Protect an account action | Apply your account authorization and authentication policy in addition to the code result |
| Use a channel whose availability is uncertain | Confirm configuration and access before offering it as a recovery path |
Email address confirmation and a strong second authentication factor serve different purposes. The maintained security guidance explains email's limitations and restrictions on telephone-network authentication. Changing between phone delivery channels does not provide a different authenticator type.
Channel options narrow or reorder the recipient's eligible plan. They do not make an unavailable channel eligible. In particular, confirm Voice access and configuration before presenting a Voice option; do not infer availability from a phone number alone.
Work through the email example
- Record the customer's requested address and the pending confirmation action.
- Send a verification using that recipient and retain the returned expiry and state.
- Show the code-entry view without claiming that an accepted send reached the inbox.
- Submit the entered code against the same stored recipient.
- Inspect the returned code result. A successful HTTP response can still contain an incorrect or expired code result.
- If the code matches, check the application's pending action again and complete it once when its conditions still hold.
Suppose the code matches after the customer has canceled the address change. Keep the verification observation, but leave the canceled application action unchanged. If the action already completed, show its existing result instead of completing it again.
An email arriving late is a delivery observation. It cannot revive an expired application intent or change a previously recorded code result.
Recover a phone delivery attempt
For a recipient with a stored WhatsApp-then-SMS plan, distinguish a resend from advancing to SMS. Follow resend and next-channel behavior rather than creating competing recovery jobs.
Scroll horizontally to see more columns.
| Situation | Useful response |
|---|---|
| The customer asks for a resend within cooldown | Show the existing verification; do not promise another send |
| A resend is eligible after cooldown | Send through the resolved plan while retaining the live verification's original expiry |
| The customer requests another eligible channel | Advance within the stored plan using the maintained next-channel operation |
| Delivery fallback is already progressing | Inspect the current verification and avoid racing it with another send |
| The send or check response is lost | Recover the original logical request using the documented idempotency contract |
| No eligible next channel remains | Explain the available recovery choice without inventing another recipient |
Advancement preserves the verification's expiry and check-attempt budget. Its send updates the last-send time used for subsequent resend cooldown. Ordinary create/resend requests can resolve the current plan after cooldown; deliberate advancement follows the stored plan.
Track create/resend sends separately from total channel sends. Manual or automatic channel advancement bypasses the create/resend meter, but its actual send still contributes to usage. Changing channels is not a way to create unlimited free attempts.
Reconcile uncertainty before a new action
Retain the original request identity after a timeout and follow the idempotency contract. A new request key can create a new action; do not use one merely because the previous response was lost.
If the application intent expires while the code result is uncertain, show that the action has expired. A later successful reconciliation may establish what happened to the code check, but it cannot authorize the expired application action. A new action needs its own current intent and policy checks.
After a confirmed result, a late unavailable or missing response should not erase that known result. Preserve the observed facts separately: send state, code result and application completion. Handle request errors, wrong codes and exhausted attempts through their documented outcomes.
Measure completion and cost separately
Define a cohort of unique pending actions, then record how many resulted in a successful code check and how many completed the intended application action. Keep unresolved actions visible. Counting successful checks over delivered messages answers a different question from completion over started actions.
For an illustrative cohort of 100 started actions, suppose 82 have a recorded code match and 79 complete the application action. The observed rates are 82% and 79% respectively. Record why the other three matched actions did not complete, such as canceled intent, rather than reporting 82 completed actions.
Use the current Verify pricing for a workload estimate. Count actual sends by channel and destination, distinguish processed and delivered charges, and include resends and fallback. Missing rates leave the estimate incomplete; they do not establish a zero price.
Keep the implementation record
Pending action / account context / application owner:
Exact recipient set / change and cancellation behavior:
Purpose / permitted channel plan / unavailable-channel path:
Expiry / code policy / attempts / cooldown:
Send observation / code result / application result:
Original request identity / lost-response recovery evidence:
Resend test / advancement test / total sends / metered sends:
Wrong code / expired intent / reused action / refused action:
Late missing or unavailable response after a confirmed result:
Cohort definition / unresolved count / completed actions:
Per-channel workload / rate source / missing quote inputs:
Support continuation / evidence retention / reviewer:Use the maintained SDK examples to implement the requests and Verify events to interpret delivery observations. Start with Verify for an eligible test flow, or contact sales about channel and volume requirements.