(01)
One tap, no password
Your customers sign in with a tap on Start in your bot. No password to store, no email flow to run. Telegram gives you no email address, so ask for one after sign-in if you need it.
(Nautilus · Telegram sign-in)
Your customers tap Start in your Telegram bot and they are signed in: no password to store, no email to deliver. You connect your own bot from the dashboard and call two HTTP endpoints; Nautilus runs the bot side and hands you an access token and the Telegram profile.
curl -X POST https://api.vernesoft.com/v1/passepartout/login/start \
-H "Authorization: Bearer vrn_passepartout_•••"
# => { "nonce": "n_9f2c…", "deep_link": "https://t.me/your_bot?start=n_9f2c…" }(Why not passwords)
Passwords come with reset flows, verification emails and the support tickets that follow. SMS codes trade that for a bill per message. If your customers are already on Telegram, there is a third way, and it costs neither.
Password or SMS sign-in
Telegram sign-in
(The Login Widget)
Telegram's login button was an iframe widget, and Telegram's own pages now call it legacy and document an OpenID Connect login instead. If you are running the widget, these are the five places it stops. This sign-in takes a different route: the user ends up in your bot, not on a page Telegram renders for you.
Where it stops
Telegram Login Widget (legacy)
Telegram sign-in
(01)
Telegram Login Widget (legacy)
Bound to the one domain you set with /setdomain in BotFather. A staging environment usually needs a second bot, and the wrong origin fails with "Bot domain invalid".
Telegram sign-in
No domain to register. The same bot serves production, staging and every developer machine.
(02)
Telegram Login Widget (legacy)
In practice it will not run on localhost, so the sign-in you ship is not the one you tested.
Telegram sign-in
The deep-link flow does not care where your app runs. The same two calls work locally and in production; the user taps Start in your bot either way.
(03)
Telegram Login Widget (legacy)
Hands back a signed payload and stops there. There is no session to expire and nothing to log out of.
Telegram sign-in
Returns an access token that expires after an hour, and an endpoint to introspect it. There is no logout call, so a token ends by expiry.
(04)
Telegram Login Widget (legacy)
An iframe you configure rather than markup you control: button size, corner radius and whether to show the photo, in Telegram's own styling.
Telegram sign-in
You render your own button, because the flow is two HTTP calls and a link. It looks like the rest of your design system.
(05)
Telegram Login Widget (legacy)
You build the data-check string and verify the HMAC yourself, correctly, in every backend that accepts a login.
Telegram sign-in
Handled on our side: the bot receives the tap straight from Telegram, so there is no signed payload to verify. Your backend introspects one token.
(Core Features)
(01)
Your customers sign in with a tap on Start in your bot. No password to store, no email flow to run. Telegram gives you no email address, so ask for one after sign-in if you need it.
(02)
Each account's Telegram users live in their own namespace in Ory Kratos, apart from other accounts' users. The same person signing in to two accounts gets two separate identities.
(03)
Create a bot with @BotFather, paste its token into the dashboard and enable it. No public webhook, and no server of yours has to be reachable from Telegram.
(04)
Start a login to get a nonce and a t.me link. The user taps Start in your bot, and you poll the status until it returns an access token and the Telegram id, username, first name and photo. The nonce is good for five minutes.
(05)
Bot tokens from @BotFather are encrypted with AES-256-GCM. Nautilus reads your bot's updates by long-polling Telegram, so you never expose a webhook. A token lets its holder act as the bot, so if yours does other work, make a separate bot for sign-in.
(06)
The official Node, PHP, Python and Rust SDKs have a passepartout resource, so each of the two calls is one line.
(One Product)
Telegram sign-in sits in the same Nautilus account as everything else: the same dashboard, the same plan, an API key scoped to it. It is one way for a person to sign in. Email and password, Google, GitHub and eight more providers go through the sign-in API on that account. A Telegram sign-in is its own user: Nautilus does not merge it with an email or social account of the same person.
See sign-in and users(Developer Experience)
Start a login, send the user to the link, poll for completion, in any language. Check the token you get back with one introspection call.
# 1. Start a login — returns a nonce and a Telegram deep link
curl -X POST https://api.vernesoft.com/v1/passepartout/login/start \
-H "Authorization: Bearer $VERNE_PASSEPARTOUT_KEY" \
-H "Content-Type: application/json"
# => { "nonce": "n_9f2c…", "deep_link": "https://t.me/your_bot?start=n_9f2c…" }
# 2. Poll for status until the user taps Start in your bot
curl "https://api.vernesoft.com/v1/passepartout/login/status?nonce=n_9f2c…" \
-H "Authorization: Bearer $VERNE_PASSEPARTOUT_KEY"
# => { "status": "completed", "access_token": "…", "user": { "id": "…" } }(FAQ)
Your backend calls POST /v1/passepartout/login/start and gets a nonce and a t.me link. The user opens the link and taps Start in your bot. Your backend then polls GET /v1/passepartout/login/status with the nonce until it returns a completed status with an access token and the user's Telegram profile.
No. Nautilus reads your bot's updates by long-polling Telegram, so there is no webhook to expose or secure. You only add the bot token from @BotFather in the dashboard.
Telegram users are namespaced per account in the shared Ory Kratos store, and each account connects its own bot. Bot tokens are encrypted at rest with AES-256-GCM.
Telegram's iframe widget, which its own pages now call legacy, is bound to one domain you set in BotFather, has no session or logout, and leaves HMAC checking to your code. This is a deep-link flow instead: it works from any origin, we do the validation, and you get an access token with an expiry. Telegram's newer OpenID Connect login lifts the one-domain rule and costs nothing; it sends users to Telegram's own page, where this keeps them in your bot. Pick whichever fits your flow.
Yes. There is no domain to register, so the same flow runs in local development and in production, and the user taps Start in your bot either way.
Nothing is billed per message, because delivery rides Telegram. A sign-in costs one or two requests — starting it, and checking the token if you do — however long the person takes to tap Start: polling for the result is free. Usage is measured in API requests: the free plan includes 3,000 a month, Starter is €19 for 50,000 and Pro €79 for 300,000. The pricing page has the current list.
(Get Started Today)
No password to store, no email to deliver. Connect a bot, make a key, and the first 3,000 requests every month are free.
What passwordless costs
Passwordless has a price list, and it only becomes obvious in production. SMS one-time codes bill per message in every country, permanently, and the most expensive routes tend to serve the cheapest customers. Magic links move the cost to email: a transactional provider, a warmed domain, and the sign-ups you lose to a spam folder you cannot inspect.
Telegram delivery has neither cost. It arrives in an app the user already has open, there is no per-message charge to pass on, and there is no domain reputation to maintain. What it costs instead is reach: your users have to be on Telegram, which is a real constraint and the honest reason this is one sign-in method rather than the only one.
So the arithmetic is short. Where your audience is already on Telegram, you have no per-message bill and no email deliverability to look after; where it is not, the sign-in API covers email, password and ten login providers on the same account. A bot token from @BotFather is the whole setup, and the first 3,000 requests each month are free.