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

# Telegram

> Send one-time codes directly to your users' Telegram accounts through the Telegram Gateway.

The Telegram API sends a one-time code to the Telegram account registered to a phone number. The message comes from Telegram's official **Verification Codes** account, so users trust it and it can't be spoofed.

A Telegram code costs a flat **\$0.02**, and it's refunded if Telegram doesn't deliver it before it expires.

<Tip>
  Want SMS as a backup when a user isn't on Telegram? Use [Verify](/guides/verify) instead. It sends on Telegram first and falls back to SMS automatically.
</Tip>

## Send a code

```bash theme={null}
curl -X POST https://api.otpbay.com/v1/messages/telegram \
  -H "Authorization: Bearer $OTPBAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+14155552671" }'
```

| Field      | Required | Description                                                                                               |
| ---------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `to`       | Yes      | Phone number in international format.                                                                     |
| `code`     | No       | Your own code, 4–8 digits. Leave it out and Telegram generates one.                                       |
| `metadata` | No       | Your own data, returned in responses and webhooks.                                                        |
| `callback` | No       | URL for [webhooks](/webhooks) on every delivery status change. Defaults to the Telegram default callback. |

The response is `201` with a `sid` that starts with `TG`, the code's `expires_at`, and `status: "sent"`.

If the number has no Telegram account, or Telegram rejects the request for another reason, the request fails with `422 TELEGRAM_REJECTED` and you aren't charged.

## Check the code

Whether you pass your own `code` or let Telegram generate one, check what your user enters with [Verify a Telegram code](/api-reference/telegram/verify):

```bash theme={null}
curl -X POST https://api.otpbay.com/v1/messages/telegram/TG6650c52ad3e4f5a6b7c8d9e0/verify \
  -H "Authorization: Bearer $OTPBAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "482913" }'
```

Read `valid` in the response. Telegram tracks wrong attempts and expiry; `verification_status` tells you the result of the latest check:

| `verification_status`        | Meaning                                    |
| ---------------------------- | ------------------------------------------ |
| `code_valid`                 | The code is correct. `valid` is `true`.    |
| `code_invalid`               | The code is wrong. The user can try again. |
| `code_max_attempts_exceeded` | Too many wrong codes. Send a new code.     |
| `expired`                    | The code expired. Send a new code.         |

<Note>
  If you passed your own `code`, you can also compare it yourself. Calling the verify endpoint is still recommended — it records the result, which improves Telegram's delivery statistics.
</Note>

## Delivery status

`status` follows the message on Telegram:

| Status      | Meaning                                                       |
| ----------- | ------------------------------------------------------------- |
| `sending`   | Being handed to Telegram.                                     |
| `sent`      | Telegram accepted the code.                                   |
| `delivered` | The code reached the user's device.                           |
| `read`      | The user opened the message.                                  |
| `expired`   | The code expired before it was delivered.                     |
| `revoked`   | The message was revoked.                                      |
| `failed`    | The code never reached Telegram. `last_error` has the reason. |

With a `callback`, OTPBay sends a [webhook](/webhooks) each time the status changes. Without one, [get the code](/api-reference/telegram/get) to read the latest status.

## Settings

Open **Messaging → Telegram** in the dashboard:

| Setting       | Default   | Range                                               |
| ------------- | --------- | --------------------------------------------------- |
| Enabled       | On        | Turned off, sends fail with `403 CHANNEL_DISABLED`. |
| Code length   | 6 digits  | 4–8 digits. Used when Telegram generates the code.  |
| Expires after | 5 minutes | 30 seconds – 60 minutes                             |
| Callback URL  | None      | Public `http` or `https` URL                        |

## Refunds

The \$0.02 is charged when you send. It's refunded when:

* Telegram rejects the request, or it never reaches Telegram.
* Telegram doesn't deliver the code before it expires.

Telegram reports an undelivered code when OTPBay next checks its status. With a `callback` set, OTPBay checks automatically until shortly after the code expires; otherwise the check happens when you [get the code](/api-reference/telegram/get). Codes sent by [Verify](/guides/verify) are always checked when the verification finishes.

After a refund, `cost` on the message shows `0.00`.
