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

# Verify

> Server-generated, expiring, single-use WhatsApp verification codes.

`POST /verify/verifications` generates a six-digit cryptographically random code for Live, binds it to a project/environment/recipient/purpose and queues a shared authentication-template send. The API never returns the Live code. Sandbox explicitly uses `123456`.

```json theme={null}
{
  "projectId": "<project-uuid>",
  "environmentId": "<environment-uuid>",
  "recipient": "+2348031234568",
  "purpose": "login",
  "consentReference": "your-server-request-id"
}
```

Supply `Idempotency-Key`. Save the resulting verification ID against the exact user, recipient and purpose on your server. Code checks use `POST /verify/verifications/{id}/check` with `{ "code": "123456" }`. Your service key stays on your server; your browser should call your own login endpoint.

### Security and limits

* Codes expire five minutes after acceptance, including queue time.
* At most five incorrect checks per challenge; the fifth locks it.
* A successful code is consumed once. Subsequent checks return `verified: false` with status `Verified`.
* Resending creates a new challenge; pending challenges for the same recipient/purpose/environment are superseded. Use a new key only for an intentional new send.
* At most one accepted send per recipient/environment in 60 seconds and ten in a rolling 24 hours per organization. Organization-wide acceptance is capped at 1,000 verifications per rolling hour.
* Limits span keys for the same project/environment; normal global API limits also apply. They are checked transactionally. Apply additional user/IP abuse protection in your own login flow.
* Suppressed known recipients cannot receive verification messages.
* Codes are encrypted in the durable outbox, never returned/logged, and removed after terminal dispatch or expiry. Verification uses a keyed hash with an encrypted random key. Consumed, locked, superseded and expired challenges erase verification secrets.

GET verification also returns `deliveryStatus`, the accepted `amount` and an optional `failureCode`, so delivery progress remains distinct from code verification.

`status` may be `Pending`, `Verified`, `Locked`, `Expired` or `Superseded`. A code check is not charged; the accepted Live send is charged once plus VAT. There is no unapproved verification-completion surcharge.

A code check confirms knowledge of the code, not that your application has authenticated the right account. Your server must bind the ID to the intended request and prevent duplicate session creation. Do not treat a stored `Verified` status supplied by a browser as authorization.

### Meta restrictions and events

Live Verify uses only an operator-reviewed approved authentication template with the OTP in the required body and copy-code button parameters. It does not insert arbitrary text, organization identity, links or branding. Operator review must confirm that the Meta template has the same five-minute validity and copy-code format.

Subscribe to `verify.message-status` for send progress and `verification.status` for completed/locked checks. Codes and recipients are excluded from these webhook payloads. Use GET status/expiry as authoritative; do not depend on an expiry event. Shared live availability remains [approval-gated](https://docs.sendlyy.app/guides/availability.md).


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