Authentication flow
1
Create a session
Your client calls
POST /api/v1/generate/public (browser/mobile) or your server calls POST /api/v1/generate (with the secret key). Bondify returns a deeplink, a session_token, and an expires_at.2
Open Telegram
The client opens the
deeplink (https://t.me/<bot>?start=<session_token>). The user lands in the bot.3
Confirm in Telegram
The user taps Confirm. Bondify marks the session
confirmed and records the Telegram identity.4
Detect confirmation
Your client polls
POST /api/v1/verify/public (the SDK does this for you), or your server polls POST /api/v1/verify. The moment the status is confirmed, the response includes a signed proof. Alternatively, configure a webhook to be pushed the confirmed identity directly.5
Verify on your backend
Your client sends the proof to your own endpoint. Your server calls
verifyProof(proof) — a local HMAC/JWT check. If valid, you create your own session (cookie, JWT, DB record — whatever you already use).The proof format
A proof is a JWT (HS256). Decoded, the payload looks like this:whsec_…):
The proof is signed with the webhook secret (
whsec_…), not the secret key (sk_…). The same whsec_… verifies both proofs and webhook signatures, so your backend only needs one secret. See Backend verification.Security properties
No verifying secret on the client
Yourwebhook_secret and secret_key never leave your server. The browser only ever sees the public project_id, which can initiate sessions but cannot verify proofs or call management APIs.
Proof is short-lived and single-use
- A proof’s
expis 5 minutes after it is issued. JWT libraries reject it automatically once expired — verify it promptly after you receive it. - A session can be read once via
/verify; on the firstconfirmedread it transitions tousedand will not produce another proof.
Sessions expire fast
A pending session lives for 10 minutes. If the user never confirms, it becomesexpired and the deep link stops working. Generate a fresh session for the next attempt.
Minimal data
Bondify stores only Telegram identity (telegram_id, telegram_name, telegram_username), session metadata (status, timestamps), and — only if you enable phone collection on Pro/Business — telegram_phone. It never stores passwords or OAuth tokens. See Security.
Signed webhooks
Every webhook delivery is signed withX-Bondify-Signature — a hex HMAC-SHA256 of the raw request body, keyed with your webhook_secret. Always verify it before processing. See Webhooks.
Infrastructure
All API requests are HTTPS only.
What Bondify does not do
- It does not store your users in its own database (only Telegram identity + session metadata).
- It does not manage your session cookies or JWTs — that is your responsibility.
- It does not send emails or SMS.
- It does not provide a UI for user profiles or settings — you build that.