1. The redirect to redirect_uri — the main path
The outcome arrives exactly as in any OIDC flow: the initiator’s browser returns to redirect_uri
with an authorization code, and the application exchanges it for tokens. Nothing here is specific
to Veriqa.
For a desktop web application that is all you need: the sign-in page takes the user back on its
own.
The return query carries
iss (RFC 9207). A strict relying party should compare it with its
expected issuer — cheap protection against a substituted provider.2. Live status — SignalR
While the person picks up their phone, scans the code and taps the button, the initiator can show the state: waiting for confirmation, confirmed, declined. The/hubs/auth hub exists for that —
the Veriqa sign-in page uses it itself, and it is available to your surface too.
This is what makes the wait legible on a TV or a kiosk, where nobody is watching the address bar.
3. Status polling — the fallback
Where WebSockets are unavailable (a strict proxy, a restricted network, an embedded device), polling remains:This endpoint is about polling the state of the current sign-in. A confirmation your server
creates goes through a separate entry point:
POST /api/transaction/confirmation creates a
confirmation transaction (the application authenticates with client credentials and receives a
transaction_id and an entry point for the user), and GET /api/transaction/{id}/result returns
its outcome (application token required). The full contract is in
Server-to-server confirmation API.Send include_channel_entries: true in the creation request and the response also carries
channel_entries — a deep link with its QR code for every available channel — next to the single
channel_entry, which stays as it is. Which channels are listed and in what order comes from the
channel display configuration (a ui_config record included), not from your request. A channel
with no address to open — Email in Pull mode, for one — is not listed, and when confirmation is
configured to happen on the web page the array is empty. Showing a single entry from the list is
your call. response_valid_until is then the earliest moment among all the entries returned.Once the result is confirmed, a client the integrator has allowed to do so can also obtain the
confirming person’s id_token — see
linking from your server.The Email channel behaves differently
An important difference for integrators: the web confirmation step depends on the channel.- on Telegram the
/connect/authorize/callbackreturn redirects immediately: the person has already tapped “yes” in the messaging app; - on Email the same address renders a “Confirm your sign-in” page with a form — no code is issued until it is submitted.
@username, or the phone number masked down
to its last four digits (Telegram · +•••••••1234). The internal channel user ID and the display name
are never shown. Whoever holds the page may not be the account’s owner, so this line is what lets them
refuse a sign-in to someone else’s account. Both answers bring the browser back to your
redirect_uri, even on another domain.
The link in the email of a confirmation transaction (an action your application asks the person to
confirm, not a sign-in) opens a page with a single “Continue” button. Opening the link changes nothing,
so a mail scanner that follows links confirms nothing. “Continue” leads to the page that shows what is
being confirmed, and the answer is accepted only in the browser that came through the link: a window
opened on another device shows a neutral page, and the person answers where they read the email.
After the confirmation
What the window does on success (close, show a message, continue automatically) is a configuration matter — part of the sign-in settings bundle the project owner or the integrator assigns to a client. Receiving the tokens does not depend on it.Next
Sign-in surfaces
How a TV and a kiosk differ from a desktop.
Troubleshooting
What the callback failures mean.