> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prelude.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Verification Lifecycle

> Understand the verification lifecycle and how it allows you to build a fully-functional verification flow in your application.

The Verify API is not just an API to send a verification code to a phone number. It's a tool that allows you to build and manage the full phone verification flow in your application.

By understanding the verification lifecycle, you can leverage the full potential of the Verify API and build a fully-functional verification flow in your application.

# Verification window

A verification window is the time span that starts when you send a verification request for a phone number. Any subsequent calls for that same number within this window are treated as retries on the same verification rather than new one. When the window ends—or the user successfully checks the code—the next verification call creates a new verification window.

<Steps>
  <Step title="Create a verification request" titleSize="h3">
    Your user enters their phone number in your application and you [perform a verification request](/verify/v2/api-reference/create-or-retry-a-verification).
  </Step>

  <Step title="Filter-out fraud" titleSize="h3">
    We analyze the request and check for fraud using our existing database and
    the [Signals](/verify/v2/documentation/prevent-fraud#signals) you provided.

    If the verification is suspicious, Prelude can:

    * return `blocked` (no verification window is opened and no code is sent), or
    * return `challenged` (a verification window is opened, but delivery is restricted to non-SMS and non-voice channels only).

    Challenge mode is a feature that must be enabled per customer account. If you want to use it, contact [Prelude support](mailto:support@prelude.so) to enable it.

    If no challenge-safe channels are available, suspicious requests are returned as `blocked`.

    Learn more about our fraud prevention system [here](/verify/v2/documentation/prevent-fraud).
  </Step>

  <Step title="Start the verification window" titleSize="h3">
    Prelude creates a new verification window. Inside this window, any subsequent attempts and checks will be added.

    Any subsequent attempts and checks will be added to this lifecycle up until:

    * the user converts by inputting a correct code.
    * the maximum number of attempts is reached.
    * the maximum number of checks is reached.
    * the window expires (typically after a few minutes).

    A response with the status `success` will be returned when a new verification window is created for normal traffic.
    For suspicious traffic routed in challenge mode, the status is `challenged`.

    <Info>
      You can configure the maximum number of attempts as well as the duration of the verification window from the [Prelude dashboard](https://app.prelude.so/)
    </Info>
  </Step>

  <Step title="Send the code" titleSize="h3">
    Prelude compares all of the available <Tooltip tip="A route is a combination of a provider and a channel. A provider can offer different channels.">routes</Tooltip> and sends a code using the one with the better combination of cost and conversion rate.

    Learn more about multi-routing and multi-channel delivery [here](/introduction/concepts/multi-routing).
  </Step>

  <Step title="Retry sending the code" titleSize="h3">
    If the user requests another, you can initiate a retry during the same verification window by repeating [the same verification request](/verify/v2/api-reference/create-or-retry-a-verification) with the same phone number.

    A response with the status `retry` will be returned when a new attempt is created within the same verification window.

    The request will fail with a `429 Too Many Requests` error code if the maximum number of attempts is reached (`too_many_attempts`), if it is performed before the minimum delay between retries is reached (`premature_retry`), or if request volume temporarily exceeds available throughput (`rate_limited`). When you receive `rate_limited`, wait for the duration specified in the `Retry-After` header before retrying.

    For each new attempt, Prelude selects the next best available route — again optimizing for cost and conversion rate, and excluding routes already tried in this verification — to increase the chances of the user receiving the code and converting.

    This next route may be a different provider on the same channel or a different channel altogether, so a retry is not guaranteed to switch channels. For example, if a WhatsApp attempt is undeliverable, the following attempt is whichever route ranks best next — which may be another non-SMS route rather than SMS. If you need a specific channel to be prioritized, set `preferred_channel` on your request.

    Each non-SMS channel (such as WhatsApp, RCS, Viber, Telegram or Zalo) is used at most once within a verification; only SMS can be attempted multiple times across retries.

    To limit how many attempts Prelude adds on its own — whether by moving to the next route immediately or by retrying after an undeliverable delivery receipt — set `max_auto_fallbacks` on the request that creates the verification. `0` keeps it to the single attempt you asked for, leaving any further attempt to you. Because the limit is recorded on the verification when it is created, it applies for the rest of the lifecycle: sending it again on a retry has no effect, and each retry you request gets a fresh allowance of the same limit.
  </Step>

  <Step title="Check the code" titleSize="h3">
    The user receives the code and enters it in your application.

    You then send it to the [Check](/verify/v2/api-reference/check-a-code) endpoint.
    If it's correct, the endpoint returns a `valid` status code.

    The request will fail with a `429 Too Many Requests` error code if the maximum number of checks is reached (`too_many_checks`).
  </Step>
</Steps>

For each verification request, you can inspect it along with the entire verification lifecycle from the [Prelude dashboard](https://app.prelude.so/) by looking at the **Verifications** tab or by searching for it using the search modal.

# Rate limiting

We limit the number of verification requests per phone number per time span. This is to prevent excessive charges and abuse attempts (such as SMS pumping) on your account.

You can configure the amount of verification requests per phone number per time span from the [Prelude dashboard](https://app.prelude.so/).

If a phone number exceeds the limit of verification requests per time span, you will receive a response with the status `blocked`. The phone number will be automatically unblocked after the time span has expired.

If your request volume temporarily exceeds available throughput, the API returns `429 Too Many Requests` with the `rate_limited` error code. Retry after the duration specified in the `Retry-After` header, or contact support if you need higher throughput. The same error can occur on phone and email verification requests.

***

# Next steps

Build a fully-functional SMS verification flow in your application by following the steps below.

<CardGroup cols={3}>
  <Card title="Set up your app" href="/verify/v2/documentation/quickstart#1-get-your-sdk" icon="circle-1">
    And get your credentials.
  </Card>

  <Card title="Send a verification code" href="/verify/v2/documentation/quickstart#3-send-a-code" icon="circle-2">
    To your user's phone.
  </Card>

  <Card title="Verify a code" href="/verify/v2/documentation/quickstart#4-verify-the-code" icon="circle-3">
    And authenticate a user.
  </Card>
</CardGroup>
