API Documentation

REST API for notifications via Telegram and Max. Subscribers, OTP, broadcasts, forms, helpdesk.

OTP (one-time passwords)

Send and verify confirmation codes via messenger.

POST /v1/otp/send

Generates a 6-digit code and sends it to the subscriber.

subscriber_id string (UUID) required

Subscriber UUID

POST /v1/otp/send
 
{
"subscriber_id": "550e8400-e29b-..."
}

Response

{
"sent": true,
"expires_in_seconds": 300
}

POST /v1/otp/verify

Verifies the entered code.

subscriber_id string (UUID) required

Subscriber UUID

code string required

6-digit code from the user

POST /v1/otp/verify
 
{
"subscriber_id": "550e8400-e29b-...",
"code": "482916"
}

Response

✓ Code valid

{
"verified": true
}

✗ Code invalid

{
"verified": false
}

OTP limits: max 5 verification attempts, 5-minute code TTL, 1 active code per subscriber.

POST /v1/otp/request — OTP for non-subscribers

If the user isn't subscribed to the project yet, a plain /v1/otp/send returns 404. This endpoint creates a bot deeplink where the user consents to subscribe and get the code in one tap.

  1. User clicks «Get code» on your site → you call /v1/otp/request and get request_id + deeplinks.
  2. Open the right deeplink for the user (Telegram or Max). The bot shows project name + description and asks to subscribe and receive the code.
  3. Poll GET /v1/otp/request/{request_id}/status until status=sent — the response also contains subscriber_id.
  4. User enters the code on your site → you make a regular POST /v1/otp/verify with the obtained subscriber_id + code.

Create request

channel string

Preferred channel (telegram or max). If omitted, both deeplinks are returned.

ttl_minutes integer

Code TTL in minutes, 1-30 (default 5).

max_attempts integer

Max code entry attempts, 1-10 (default 3).

POST /v1/otp/request
 
{
"channel": "telegram" // optional
}

Response

{
"request_id": "Kq9xV3mN2pT7rL8s",
"telegram_link": "https://t.me/zapnotybot?start=otp_Kq9xV3mN2pT7rL8s",
"max_link": "https://max.ru/zapnotybot?start=otp_Kq9xV3mN2pT7rL8s",
"expires_in": 900
}

Check status

Poll every 1-2s. Statuses: pending (waiting for user), sent (subscribed + code delivered), cancelled (user tapped Cancel), expired (link expired after 15 min).

GET /v1/otp/request/{request_id}/status

Response

{
"status": "sent", // pending | sent | cancelled | expired
"subscriber_id": "550e8400-e29b-...",
"channel": "telegram"
}

request_id lives for 15 min. If the user is already subscribed, the bot skips the consent screen and sends the code immediately. The classic /v1/otp/send is unchanged and faster when subscriber_id is already known.

Related sections