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

# Send verification codes via WhatsApp

Use WhatsApp verification codes for registration, login, account recovery, and additional verification of sensitive actions. After a customer chooses WhatsApp, your system sends an authentication template. The customer copies or autofills the code, and your backend validates it.

## Why use WhatsApp for verification?

### Add another delivery channel alongside SMS

WhatsApp receives messages over an internet connection. It gives customers another way to receive a code when Wi-Fi is available but SMS reception is unreliable. The recipient still needs WhatsApp and a working internet connection.

### Reduce code-entry steps

Copy-code buttons reduce manual transcription. One-tap and zero-tap experiences can reduce app switching on supported, integrated Android apps. For customers who already use WhatsApp, these options can make verification easier. Measure the effect on completion in your own flow.

### Optimize the cost of a completed verification

Evaluate WhatsApp as a potential way to reduce verification costs by market. Compare authentication and applicable authentication-international rates, YCloud charges, SMS fallback costs, and completion rates.

Use total verification-channel charges divided by successful verifications as a practical measure. Meta charges for delivered messages; an undelivered message does not incur the corresponding Meta message fee. Other charges depend on your YCloud plan. See [WhatsApp pricing](/en/documentation/whatsapp-business-platform/pricing-limits-and-quality/whatsapp-pricing) and [Meta pricing](https://business.whatsapp.com/products/platform-pricing).

### Locate drop-off in the verification flow

Track request acceptance, message delivery, and successful verification separately. This helps you distinguish sending problems from problems receiving or entering a code.

WhatsApp carries the code. Your verification system still decides whether it is valid, expired, already used, and authorized for the requested action.

## Before you start

1. Sign in to [YCloud](https://www.ycloud.com/console/#/entry/login) and [connect a WABA and sender](/en/documentation/quick-start/connect-whatsapp-to-ycloud).
2. Prepare code request, generation, storage, and validation logic. This guide uses the WhatsApp Messages API; your system owns the code lifecycle. For YCloud's verification service, see [Verify](/en/documentation/integrations/channels/verify/index).
3. Prepare a [server-side API key](/en/documentation/developer/manage-api-keys) and [webhook receiver](/en/documentation/developer/webhooks).
4. Use a test recipient who requested the code. A code request is not permission for later marketing.
5. Configure and test an SMS channel if you need fallback. The WhatsApp Messages API does not automatically send SMS because you follow the recommendations in this guide.

## 1. Choose the code experience

| Experience | Customer action | What you prepare | When to choose it |
| - | - | - | - |
| **Copy code** | Copy in WhatsApp, then enter the code in your website or app. | An input screen and backend verification. | Websites, multiple platforms, and an initial integration. |
| **One-tap / Autofill** | Tap a button that passes the code to a supported Android app. | Package name, signing hash, and handshake integration. | Reduce switching and pasting on Android. |
| **Zero-tap** | A supported Android app receives the code without switching to WhatsApp. | Android integration, eligibility checks, and acceptance of the applicable terms. | Further reduce interaction when you can test the supported conditions. |

One-tap or zero-tap can fall back to another experience, such as copy code, when device or application requirements are not met. Support this fallback. Selecting the option in the editor does not integrate your client application.

Meta also documents OTP keyboard suggestions from notifications on iOS 26 and later. This is separate from Android one-tap and zero-tap; test them separately. See [Authentication templates](/en/documentation/whatsapp-business-platform/messaging/message-templates/authentication-message-templates/index) and [Meta authentication documentation](https://developers.facebook.com/docs/whatsapp/business-management-api/authentication-templates/).

<Frame caption="Meta example: the customer copies the verification code and enters it in your app. The code and expiry shown are demonstration values.">
  <img src="https://mintcdn.com/lchnan/gXEJIQXV2JH2VUQJ/product-assets/english-help-2026-09-22/meta-authentication-copy-code-annotated.svg?fit=max&auto=format&n=gXEJIQXV2JH2VUQJ&q=85&s=285ea260055d40a8647623d797848f19" alt="Meta authentication example with a short arrow pointing to Copy code." width={380} data-path="product-assets/english-help-2026-09-22/meta-authentication-copy-code-annotated.svg" />
</Frame>

Source: [Meta authentication templates](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/authentication-templates/authentication-templates/).

## 2. Create an authentication template

### Select the WABA, name, and language

Open **Templates** for the intended WABA in YCloud, select **Add Template**, and choose **Authentication**.

Use lowercase letters, digits, and underscores for a name such as `login_verification`. Choose your customer's language and record the exact approved name and language code for sending. See [Create template](/en/documentation/channels/whatsapp-accounts-management/template-management/create-template/index).

### Configure the content and code action

Authentication uses preset code text, with supported security and expiry notices. Do not insert ordinary promotional copy, URLs, media, or emojis into the body.

Choose **Copy code**, **Autofill**, or **Zero Tap**. For Autofill and Zero Tap, enter the actual Android package name and signing hash and complete the app integration. Zero Tap also requires accepting the applicable terms.

For API configuration, use the current `supported_apps` contract rather than older top-level `package_name` and `signature_hash` examples. Follow the [authentication integration guides](/en/documentation/whatsapp-business-platform/messaging/message-templates/authentication-message-templates/index) for Android SDK and handshake details.

### Configure three separate expiry settings

| Setting | What it controls | Five-minute example |
| - | - | - |
| Backend code expiry | When your server rejects the code. | Five minutes after generation. |
| Displayed expiry notice | What the customer is told. | Five minutes, matching your actual policy. |
| Delivery time-to-live (TTL) | How long delivery may be attempted. | No longer than the code's remaining useful lifetime, allowing for time between generation and sending. |

The current YCloud contract supports regular custom authentication TTL values of **30–900 seconds**, with a **10-minute default** for new templates. Historical defaults can differ; inspect the saved `messageSendTtlSeconds`. The displayed expiry notice supports **1–90 minutes** but does not change backend expiry or extend the regular delivery TTL range.

The contract also supports `-1`, which sets a custom TTL of 30 days. This is not recommended for short-lived codes and does not mean immediate expiry or disabled retries. See the [YCloud OpenAPI contract](https://newdocs.ycloud.com/openapi/endpoints/ycloud-api-v2.yaml).

For example, a code generated at 10:00 and expiring at 10:05 has one minute left if it arrives at 10:04. Receipt does not restart its lifetime. TTL expiry stops outstanding delivery attempts; it does not retract a message already delivered to a customer's device.

### Submit and check availability

Submit the template and inspect its actual review status. Send only after it is approved and usable. If rejected, inspect the reason and follow [Template review and lifecycle](/en/documentation/whatsapp-business-platform/messaging/message-templates/template-review-and-lifecycle). Do not depend on a fixed approval time.

## 3. Send through the API

Send immediately after the customer requests a code. Choose the submission behavior your flow needs:

| Endpoint | Behavior |
| - | - |
| `POST /v2/whatsapp/messages/sendDirectly` | Submit synchronously to the WhatsApp Business API; useful when the OTP flow needs the submission result immediately. |
| `POST /v2/whatsapp/messages` | Queue the message for asynchronous submission. |

The endpoint name `sendDirectly` describes submission timing. It is separate from the Utility Direct Send feature that handles template generation. This flow still uses an approved authentication template.

### Prepare the request

* Authenticate server-side with `X-API-Key`.
* Use E.164 numbers, including country codes, for `from` and `to`.
* Set `type` to `template` and use the approved name and language for the selected WABA.
* Supply the same code in the body and OTP button parameters.
* Associate your verification request with the YCloud message ID. `externalId` helps reconciliation but does not guarantee idempotency.

Example Copy code request body. Replace placeholders; `123456` is fictional and must be generated by your verification system in production:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "from": "BUSINESS_PHONE_NUMBER",
  "to": "CUSTOMER_PHONE_NUMBER",
  "type": "template",
  "template": {
    "name": "APPROVED_TEMPLATE_NAME",
    "language": { "code": "APPROVED_LANGUAGE_CODE" },
    "components": [
      {
        "type": "body",
        "parameters": [{ "type": "text", "text": "123456" }]
      },
      {
        "type": "button",
        "sub_type": "url",
        "index": 0,
        "parameters": [{ "type": "text", "text": "123456" }]
      }
    ]
  },
  "externalId": "VERIFICATION_REQUEST_REFERENCE"
}
```

The sending parameters for the OTP button use `sub_type: url`; do not use an ordinary marketing coupon-code button structure. See [Copy-code authentication](/en/documentation/whatsapp-business-platform/messaging/message-templates/authentication-message-templates/copy-code-authentication) and [Send a WhatsApp message](/en/api-reference/guides/whatsapp-platform/send-whatsapp-message). You can also select **More → Copy as cURL** on an approved template and check the generated parameters against its configuration.

A successful API response does not confirm delivery. If a request times out, inspect available message records and callbacks before sending again.

## 4. Receive delivery updates

In **Developers → Webhooks**, create an endpoint, enter your callback URL, and subscribe to `whatsapp.message.updated`. Follow the [Webhook guide](/en/documentation/developer/webhooks) for signature verification, acknowledgements, and retries.

Associate each message ID with its verification request:

| Status | Meaning | Flow response |
| - | - | - |
| `sent` | Sent, without confirmation of arrival on the customer's device. | Wait for delivery or failure updates. |
| `delivered` | Delivered to the recipient. | Wait for successful code validation. |
| `read` | A read receipt was received. | Do not mark verification complete or treat missing receipts as failure. |
| `failed` | Sending or delivery failed. | Inspect the error before fixing configuration, retrying, or switching channels. |

Mark verification complete only when your backend validates the code. Handle duplicate and late callbacks without allowing an earlier status to overwrite a later one. Use [Message logs](/en/documentation/channels/whatsapp-accounts-management/data-analysis/message-logs) for manual investigation.

## 5. Design the interface and SMS fallback

### Make the receiving channel clear

Before submission, say that the code will arrive through WhatsApp. After sending, show a masked destination, waiting message, resend countdown, and available alternatives. Let customers go back and correct the number.

| Strategy | When it fits | Experience |
| - | - | - |
| WhatsApp first, SMS fallback | Your data shows that customers predominantly use WhatsApp. | Identify the first channel; offer SMS on failure or delay, or send according to a disclosed fallback policy. |
| Customer chooses | Markets, devices, or preferences differ. | Offer WhatsApp and SMS together and remember appropriate preferences. |

Where the operating system permits it, your app can use WhatsApp availability detection to suggest a channel. Installation does not prove that the entered number is registered or reachable. A negative result does not rule out receiving on another device. Do not use installation detection as number verification.

### Handle failure and delay separately

| Situation | Recommended action |
| - | - |
| Explicit failure | Classify the error. Use SMS when the fallback policy permits and the number and code remain valid. Fix API-key, template, or account errors rather than masking them with fallback alone. |
| Submission without timely delivery confirmation | Use a configurable wait before offering another channel or applying fallback. Missing confirmation is not proof of nondelivery. |
| Delivered without verification completion | Keep input and retry options available; do not continuously resend just because verification is incomplete. |
| Verification complete or code expired | Stop further sends for this request. |

The original guide's **15–60 seconds** can be an experimental waiting range. Adjust it using observed latency and abandonment. It is not a WhatsApp requirement or delivery promise.

For the same challenge, you may send the same still-valid code through the fallback channel. If you generate a new code, invalidate the previous one according to your policy and explain the behavior. Fallback must not extend an old code's lifetime.

Use one verification request to control channel attempts, cooldown, and completion. Repeated taps or duplicate and late callbacks must not trigger multiple SMS messages. If WhatsApp and SMS both arrive, each channel may incur charges.

## 6. Test before launch

| Test | Expected result |
| - | - |
| Normal verification | Body and button values match; a correct unexpired code succeeds. |
| Wrong, expired, or reused code | The backend rejects it according to policy and the interface explains the result. |
| New code request | Old and new code validity matches your policy. |
| Offline or delayed recipient | Delivery TTL remains separate from code lifetime; waiting and fallback follow configuration. |
| Unsupported Android autofill conditions | A usable fallback lets the customer continue. |
| iOS and multiple devices | Test notification, copying, and filling on the actual clients; do not assume identical behavior. |
| Duplicate callbacks, late callbacks, request timeout | Do not create duplicate outcomes or uncontrolled resends. |
| SMS fallback | Use the correct destination and a valid code; stop after successful verification. |

After launch, compare delivery rate, delivery latency, verification completion, SMS fallback share, and cost per successful verification by market, channel, and device. Use these results to tune channel priority and waiting thresholds rather than promising that WhatsApp is always faster or cheaper than SMS.

## Additional scenario: customer-initiated verification

In a customer-initiated verification flow, a customer opens WhatsApp from an app, sends a message containing information for the current verification, then returns to the app. Evaluate this separately. An ordinary inbound WhatsApp message is not sufficient by itself to log someone into a website or app.

This approach needs a one-time challenge, session binding, expiry, replay protection, and user confirmation. The cited YCloud material does not establish a ready-made login feature, so this guide does not present it as a default integration step.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.