<Intro>

<EndpointHeader />

<Description>

Advances an in-progress verification to the next channel in its plan and sends a fresh passcode there, for a recipient who reports not receiving the code. Identify the verification by the same `to` used to create it; you do not need to store a verification ID.

The send bypasses the resend cooldown (a deliberate channel switch is a different act from a same-channel resend), and every passcode already sent stays valid, so a code that arrives late can still be checked. The response is the verification with `last_channel` set to the channel the new passcode went to. Concurrent requests for the same recipient are safe: each advances the plan at most one step. When two race, the request that completes the newer send is the authoritative one; the other returns the verification's committed state, whose `last_channel` still names the most recent send that completed. A later read of the verification always reflects the settled outcome.

An error status is returned when the verification cannot be advanced: `404` when no verification is in progress for the recipient, `422` with `NoNextChannel` when the plan has no further channel (fall back to a plain resend), `422` with `NoAvailableChannel` when every remaining channel failed to send, and `429` when sends for the account are requested too quickly.

</Description>

</Intro>

<Payload kind="request">

<Field name="to" type="object" required>

<Description>

The recipient to verify. Provide an `email_address`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.

</Description>

<FieldChildren kind="request">

<Field name="email_address" type="string" prefix="to.">

<Description>

The recipient's email address. Case does not matter; the address is lowercased before use.

</Description>

</Field>

<Field name="phone_number" type="string" prefix="to.">

<Description>

The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).

</Description>

</Field>

</FieldChildren>

</Field>

</Payload>

<Payload kind="response">

<Field name="id" type="string" required />

<Field name="status" type="string" required>

<Description>

The verification's current state: `pending` (the initial state, awaiting a correct passcode), `verified` (a correct passcode was submitted), `failed` (too many incorrect attempts), `expired` (the time window elapsed before a correct passcode), `canceled` (the verification was canceled before completing), or `blocked` (it was stopped by a fraud or abuse control).

</Description>

<Description>

Possible values: `pending`, `verified`, `failed`, `expired`, `canceled`, `blocked`

</Description>

</Field>

<Field name="reason" type="nullable string">

<Description>

Why the verification reached its final state, or null while `pending` and once `verified`. See the enum for the values it can take.

</Description>

</Field>

<Field name="to" type="object" required>

<Description>

The recipient to verify. Provide an `email_address`, a `phone_number`, or both; at least one is required. The addresses also identify the verification: a check must supply exactly the set used on the create call, so a verification created with both addresses is not found by either one alone.

</Description>

<FieldChildren kind="response">

<Field name="email_address" type="string" prefix="to.">

<Description>

The recipient's email address. Case does not matter; the address is lowercased before use.

</Description>

</Field>

<Field name="phone_number" type="string" prefix="to.">

<Description>

The recipient's phone number in E.164 format, with the leading `+` and country code (for example `+15551234567`). A number in any other format is rejected as an invalid recipient (`422`).

</Description>

</Field>

</FieldChildren>

</Field>

<Field name="channels" type="array of object" required>

<Description>

The channels this verification uses to deliver the passcode, in attempt order: the first entry is tried first and later entries are fallbacks. An email recipient is verified over email; a phone recipient is verified over the phone channels enabled for its destination country, in the order that country's configuration sets.

</Description>

<FieldChildren kind="response">

<Field name="channel" type="string" prefix="channels." required>

<Description>

The channel a passcode is delivered over. Open enum — new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.

</Description>

<Description>

Possible values (may grow over time): `email`, `sms`, `whatsapp`

</Description>

</Field>

</FieldChildren>

</Field>

<Field name="last_channel" type="nullable string">

<Description>

The channel the most recent passcode was sent on, or null before the first send. Open enum; new channels may be added over time, so treat any unrecognized value as a future channel rather than an error.

</Description>

<Description>

Possible values (may grow over time): `email`, `sms`, `whatsapp`

</Description>

</Field>

<Field name="metadata" type="object">

<Description>

The key/value pairs attached when the verification was created.

</Description>

</Field>

<Field name="expires_at" type="string" required>

<Description>

When the verification expires if no correct passcode is submitted first. After this time its status reports `expired`.

</Description>

</Field>

<Field name="verified_at" type="nullable string">

<Description>

When the verification was completed, or null if it is not yet verified.

</Description>

</Field>

<Field name="created_at" type="string" required />

<Field name="updated_at" type="string" required />

</Payload>