(Nautilus · Telegram sign-in)

Let your customers sign in with Telegram No password, no SMS bill, no domain to register

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 cost support time, SMS codes cost money

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

  • ✕ Password storage and reset flows you have to secure and maintain.
  • ✕ Verification emails that arrive late or land in spam, which blocks sign-ups.
  • ✕ SMS one-time codes billed per message, in every country, for as long as you use them.
  • ✕ Telegram bot tokens, if you wire it up yourself, scattered across config and env files.

Telegram sign-in

  • ✓ No password to store, leak or reset.
  • ✓ One tap on a deep link: no email round trip, no code to type.
  • ✓ Users stored per account in Ory Kratos, apart from other accounts' users.
  • ✓ Bot tokens encrypted at rest with AES-256-GCM.

(The Login Widget)

Where Telegram's Login Widget stops

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.

(01)

Domain Binding

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)

Local Development

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)

Sessions And Logout

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)

The Button

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)

Signature Checking

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)

What you get with Telegram sign-in

(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.

(02)

Users kept per account

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)

Bring your own bot

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)

Two HTTP calls

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 encrypted at rest

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)

SDKs for four languages

The official Node, PHP, Python and Rust SDKs have a passepartout resource, so each of the two calls is one line.

(One Product)

Telegram is one way in, not the whole login

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
User taps Start in your botNautilus signs them inYour app gets an access token

(Developer Experience)

Add Telegram sign-in with two calls

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)

Frequently Asked Questions

How does the Telegram login flow work?

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.

Do I need to run a public webhook for the Telegram bot?

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.

How are my users kept apart from other accounts' users?

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.

How is this different from the Telegram Login Widget?

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.

Does it work on localhost?

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.

Does it cost per message, like SMS one-time codes?

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)

Give your customers a Telegram sign-in

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.