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) requiredSubscriber UUID
ttl_minutes integer Code TTL in minutes (1–30, default 5)
max_attempts integer Max verification attempts (1–10, default 3)
code_length integer Code length: 4, 6 or 8 digits. Default — project setting (6)
purpose string Code purpose (login/payment/signature etc., up to 32 chars). Multiple active OTPs of different purposes coexist
Response
POST /v1/otp/verify
Verifies the entered code.
subscriber_id string (UUID) requiredSubscriber UUID
code string required6-digit code from the user
purpose string Purpose — verifies the code of exactly this purpose (must match the one passed to /send)
Response
✓ Code valid
✗ Code invalid
Invalid code → HTTP 400 with body {error, code, retryable}. If no active code exists or attempts are exhausted → HTTP 404. There is no {verified: false} response — success is always HTTP 200 {verified: true}.
OTP limits: 3 verification attempts by default (range 1–10), 5-minute code TTL, 1 active code per (subscriber, purpose) pair.
Resending a code
Each new /v1/otp/send invalidates the subscriber's previous active code — only the latest one is valid. For a 'Resend' button on your side use a 30-second debounce to avoid spam. Limit: 3 codes per hour per subscriber (429 on exceed).
Invalidation is scoped per purpose: a purpose=login code does not cancel a purpose=payment code — the user can have both active at once.
OTP webhook events
Subscribe a webhook to these events for conversion analytics and security alerts.
otp.sent — code successfully delivered to the subscriber
otp.verified — code verified correctly
otp.failed_attempt — wrong code entered, attempts still remain
otp.max_attempts_reached — wrong code and all attempts exhausted — a possible brute-force signal
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.
- User clicks «Get code» on your site → you call /v1/otp/request and get request_id + deeplinks.
- Open the right deeplink for the user (Telegram or Max). The bot shows project name + description and asks to subscribe and receive the code.
- Poll GET /v1/otp/request/{request_id}/status until status=sent — the response also contains subscriber_id.
- 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).
Response
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).
Response
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.