Create auth session
Create a new passwordless auth session (login). Returns a deep link and QR code for the selected channel. Rate limited: 15 requests per minute per IP.
The email channel additionally honours the account-bootstrap decline cooldown: if the owner of the address used the "this wasn't me" link on a recent message from us, this endpoint answers 429 identity_declined for an hour. That covers sign-in mail as well, so a client should offer the other channels (Telegram, WhatsApp, SMS) rather than retrying.
No credential is required. A client that DOES present an API key (Authorization: Bearer pk_…) — an MCP connection signing in from inside — has it checked: a key the API no longer accepts (unknown, revoked, expired) is refused with 401 invalid_api_key before anything is stored or sent, so a connection whose key was revoked cannot sign back in to the account. A live presented key is recorded on the session, and the user session issued when the sign-in completes is BOUND to it: revoking that key by any path ends the session, and it cannot be refreshed once the key is revoked or expired. If the key is revoked before the person completes the sign-in, no session is issued at all.
ON THE EMAIL CHANNEL A 201 MEANS THE MAIL WAS ACCEPTED FOR DELIVERY. The code and the magic link travel in that message and are returned by nothing, so a session created after a failed send could never be completed — if delivery fails, this endpoint answers 503 challenge_delivery_failed and the session is discarded rather than returning a session to poll. Do not look for an email_sent: false to decide whether to tell someone to check their inbox: on this route a 201 already carries that answer. A field of that name DOES mean something elsewhere — POST /api/v1/accounts (AccountSessionResponse) and POST /api/v1/accounts/{id}/send (its own response shape) split creating a session from mailing it, and report a withheld or failed send that way — but those are different endpoints. This one still carries email_sent on an email-channel 201, where it is ALWAYS true (a failed send never reaches a 201), and it never returns email_error at all. Note that email_sent is NOT part of the declared 201 schema below: AuthSessionResponse is shared with the session-poll and submit operations, which return no such field, so it is documented here rather than declared there — a generated client type for this response will not carry it.
Request
- Base URL: https://api.proof.holdings
- URL: https://api.proof.holdings/api/v1/auth/sessions
- Auth: none declared
Request body
Example request
{
"channel": "telegram",
"phone_number": "+37069199199",
"email": "user@example.com",
"return_to": "/oauth/consent?request=mcpr_abc"
}Response
Auth session created
Example response
{
"id": "auth_abc123",
"channel": "telegram",
"status": "pending",
"deep_link": "https://t.me/bot?start=auth_abc123",
"expires_at": "2026-02-13T12:10:00Z",
"instructions": "Open Telegram and tap the link to log in"
}Changes
No recorded changes to this operation across all 1 revision of this API.