Bot Auth
Authenticate your website users via Telegram/Max bots. User clicks a link, confirms in the bot, automatically subscribes to notifications, and you receive their data.
How it works
1. User clicks the bot link
2. Bot shows authorization request with "Login" / "Cancel" buttons
3. User clicks "Login" → automatic subscription to notifications + code generation
4. Bot sends "Go to website" button → callback_url?code=CODE
5. Your server calls POST /v1/auth/verify → receives data
Setup
In the project dashboard go to Settings → Auth and set the Callback URL and Origin URL.
Static links
Simple option — a permanent link. Get it via API or in the dashboard:
The static authorization link (format auth_<slug>) works only if a callback URL is configured for the project (Settings → Auth). Without it the bot replies «Authorization for this project is not set up». The configured field in the response indicates whether the project is ready for authorization.
Subscription ≠ authorization
If you just need a notification subscription (without the user logging into your site) — use a separate mechanism: the proj_<slug> link from GET /v1/subscribe-link. It requires no callback configuration and always works. The auth_ prefix is authorization (login that returns user data), the proj_ prefix is a plain subscription. See the Subscribers section.
API sessions (with state)
To pass state (e.g., browser session ID), create a session via API:
- state — 1–128 characters, printable ASCII without spaces or the < > & symbols. Put an opaque token there (not an email/phone) — it is returned in auth.completed and in /v1/auth/verify.
- redirect_uri — optional. For the notification-only flow (receiving the result via the auth.completed webhook) no callback is needed at all. If set, it must exactly match a URL from the project allowlist.
- A session lives 30 minutes (expires_in: 1800). Usually the user completes linking right away: open link → bot → confirm. The 30 minutes is a buffer in case they get distracted. If the link does expire — the bot replies with an "expired" message on /start; just create a new session. Stop status polling after expires_in.
Code verification
After confirmation, the user lands on callback_url?code=CODE. Verify the code:
QR/Polling (cross-device)
For desktop auth via a mobile bot: create a session, display a QR code with the link, and poll the status. When the user confirms on their phone, you receive a code. Poll interval: 2-3 seconds. The code is one-time — after receiving status=completed, a repeat request returns expired.
Receiving the result: three ways
After the user follows the link and confirms login in the bot, you can obtain the result in one of three ways:
- Webhook auth.completed — always sent. The payload contains subscriber_id, state (your token) and subscriber data. The simplest path for a backend integration: no callback service needed.
- Polling GET /v1/auth/session/{session_id}/status — when status: "completed" a code is returned, then POST /v1/auth/verify.
- Redirect with code — if a callback URL is configured for the project.
Callback URL and redirect
Zapnoty does not redirect the browser automatically. If a callback URL is set for the project, after confirmation the bot shows the user a "go to site" button linking to:
{callback_url}?code=<code>&state=<urlencoded state>
- code — always; state — if it was passed to /v1/auth/session.
- The callback URL is taken from the redirect_uri of the /v1/auth/session request or from the project settings. Any URL used must be in the project allowlist (project settings → authorization) — exact match, open-redirect protection.
- If no callback URL is configured — the flow is notification-only: the bot just shows a success message, and you receive the data via the auth.completed webhook.
Customizing authorization texts
The authorization message text and button label are configured via PUT /v1/sender (fields auth_text and auth_button_text, multilingual {ru, en}). auth_text must contain the {{url}} variable (≤500 chars), auth_button_text — ≤32 chars. Project management.