API Reference
Full reference for the Verne Passepartout HTTP API. All endpoints are served from https://api.vernesoft.com.
Examples are shown as raw curl requests and as calls through the official SDKs — see Installation to set one up. SDK snippets assume an initialized verne client with a passepartout key.
1. Authentication
Every request must include a Bearer token in the Authorization header. A key is vrn_ followed by random characters; it does not name an API. The Passepartout API needs a key with the passepartout scope (shown as Telegram sign-in in the dashboard), chosen when the key is created. A key without it is refused with 403 Forbidden and the code forbidden (This API key is not authorized for Passepartout.). Keys created before scopes existed and named vrn_passepartout_... still work and open the Passepartout API only. There is no sandbox mode: logins always run against the bot you configured. See API Keys.
Example header:
Authorization: Bearer vrn_9f8a7...
The key authenticates your application. The access token returned by a completed login (prefixed ppt_live_) represents an authenticated end-user — pass that back to your app's session, not the API key. Keys are scoped to a single tenant, and you create and revoke them on the Dashboard → Keys page.
Bot setup. Before any login works, configure your Telegram bot token (from @BotFather) and enable it on the Dashboard → Passepartout page. Tokens are encrypted at rest with AES-256-GCM.
2. Start Login
POST /v1/passepartout/login/start
Begins a Telegram login attempt. Returns a nonce and a deep_link; send the end-user to the deep_link, then poll Get Login Status with the nonce. Takes no request body.
Example Request
curl -X POST https://api.vernesoft.com/v1/passepartout/login/start \
-H 'Authorization: Bearer vrn_9f8a7...'
Response
{
"nonce": "n_9f2c8a1b",
"deep_link": "https://t.me/your_bot?start=n_9f2c8a1b",
"expires_at": "2026-07-25T12:05:00Z"
}
| Status Code | Meaning |
|---|---|
200 OK | Login started; nonce and deep_link returned. |
401 Unauthorized | Missing or invalid Bearer token. |
403 Forbidden | Key lacks the passepartout scope. |
409 Conflict | No bot configured or enabled for this tenant. |
429 Too Many Requests | Rate limit reached — retry after the Retry-After header. |
Signing in is never blocked for billing reasons. A suspended account, or one with an unpaid renewal, can still start a login, poll its status and introspect tokens: your users are not locked out of your app because of a payment. The only 402 on the sign-in path is ACTIVE_USER_LIMIT_REACHED for a new person, described under Get Login Status.
3. Get Login Status
GET /v1/passepartout/login/status
Returns the current state of a login attempt. Poll this after sending the user to the deep link. While the user hasn't finished, status is pending; once done it becomes completed and carries the access_token and user.
If the person has been deactivated, the login does not complete: no token is issued, the person is told in Telegram that the account is disabled, and this call answers 403 with the code account_disabled.
Polling is not metered, and it is never refused for billing, so a login that has begun can finish. Poll each login about every 2 seconds; the limit is 3,000 polls a minute per account, and beyond it you get 429 Too Many Requests with a Retry-After header.
Each person who completes a login is an active user for that calendar month, however many times they sign in; that is what your plan limits (see Plans, Limits and Refusals). If your account is over its active-user limit and the month to move to a higher plan has ended, a new person's first login is refused and this call answers 402 with the code ACTIVE_USER_LIMIT_REACHED. People who already have an account sign in as usual.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
nonce | string | Yes | The nonce returned by Start Login. |
Example Request
curl 'https://api.vernesoft.com/v1/passepartout/login/status?nonce=n_9f2c8a1b' \
-H 'Authorization: Bearer vrn_9f8a7...'
Response
{
"status": "pending"
}
| Status Code | Meaning |
|---|---|
200 OK | Status returned (pending or completed). |
401 Unauthorized | Missing or invalid Bearer token. |
403 Forbidden | The person who tried to sign in is deactivated (account_disabled). No token is issued. |
402 Payment Required | ACTIVE_USER_LIMIT_REACHED: a new person tried to sign in and your account is past its active-user limit and the month to move up. Nothing was created. Moving to a higher plan lifts it; retrying does not. |
404 Not Found | Unknown or expired nonce. |
429 Too Many Requests | Polling faster than the account limit — retry after the Retry-After header. |
4. Introspect Token
POST /v1/passepartout/tokens/introspect
Validates a Passepartout access token and returns its attributes. A token is reported as { "active": false } when it is unknown or expired, is owned by another tenant, or belongs to a user you have deactivated or deleted.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
access_token | string | Yes | The ppt_live_ token returned by a completed login. |
Example Request
curl -X POST https://api.vernesoft.com/v1/passepartout/tokens/introspect \
-H 'Authorization: Bearer vrn_9f8a7...' \
-H 'Content-Type: application/json' \
-d '{ "access_token": "ppt_live_7bK2mQ9pXr…" }'
Response
{
"active": true,
"subject": "9d3f1c22-4a8e-4b17-9c5e-2f0a1b6d8e44",
"tenant_id": "b1a7…",
"scopes": ["passepartout"],
"expires_at": "2026-07-25T13:00:00Z"
}
| Status Code | Meaning |
|---|---|
200 OK | The token is active or not — { "active": false } is an answer, not an error. |
401 Unauthorized | Missing or invalid Bearer token. |
502 Bad Gateway | The state of the user could not be checked (upstream_unavailable). Retry; the token is never reported active when this happens. |
5. Deactivated Users
You can switch an end-user off without deleting them: PATCH /v1/gate/identities/{id}/state with { "state": "inactive" }, using a key with the gate scope of the same tenant and the identity_id that the completed login (and the token's subject) carries. See Identity State Management. While a user is inactive:
- They cannot sign in. A login they start does not complete: Get Login Status answers
403withaccount_disabledand no token is issued, and the bot tells the person the account is disabled. - Their existing tokens are inactive. Introspect Token answers
{ "active": false }for every token issued to them. The tokens are suspended, not revoked: set the user back toactiveand the same tokens are active again until they expire, and the person can sign in again as the same user.
Introspection checks the user's state each time it is called, so a deactivation takes effect on the next call.
Error Format
All errors follow a consistent structure. The SDKs surface these fields as a typed error:
{
"error": {
"code": "bot_not_configured",
"message": "No Telegram bot is configured or enabled for this tenant.",
"request_id": "req_abc123"
}
}
Include the request_id when contacting support for faster resolution.