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

# Verify OTP

> Verify a code sent via the Send OTP endpoint

Verify the code a customer entered against an `otp_id` from [Send OTP](/whatsapp/send-otp).

## Endpoint

```text theme={null}
POST https://xwialxkobwygraiddimj.supabase.co/functions/v1/public-api/v1/otp/verify
```

### Request body

<ParamField body="otp_id" type="string" required>
  The `otp_id` returned when the code was sent.
</ParamField>

<ParamField body="code" type="string" required>
  The code the customer entered.
</ParamField>

### Response

<ResponseField name="valid" type="boolean">
  Whether the code matched and hasn't expired.
</ResponseField>

<ResponseField name="attempts_remaining" type="integer">
  Only present when `valid` is `false` — attempts left before this `otp_id` locks.
</ResponseField>

```bash cURL theme={null}
curl https://xwialxkobwygraiddimj.supabase.co/functions/v1/public-api/v1/otp/verify \
  -H "Authorization: Bearer tvk_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "otp_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "code": "482913" }'
```

```json Response (correct code) theme={null}
{
  "valid": true
}
```

```json Response (wrong code) theme={null}
{
  "valid": false,
  "attempts_remaining": 3
}
```

<Warning>
  Each `otp_id` allows a limited number of incorrect attempts (default 5). Once exhausted, verification returns the `otp_max_attempts` error instead of `valid: false` — send a new code rather than retrying indefinitely. An expired code returns `otp_expired`. Both are structured errors, not `valid: false` — see [Errors](/errors).
</Warning>

## What happens on success

A successful verification fires an `otp.verified` webhook event if you've registered one — see [Webhooks](/webhooks-overview).
