Verification Sessions
A verification session tracks a single OpenID4VP exchange from the moment you create an authorization request until the holder's presentation is verified (or the session errors out). When you create an authorization request, the Verifier returns a verificationSessionId; you use that identifier to read the session's current state, or to subscribe to live updates over a Server-Sent Events (SSE) stream.
This page documents the two session endpoints: reading a session once with GET /verification-sessions/{sessionId}, and watching it in real time with GET /verification-sessions/{sessionId}/events.
Overview
A session is created for you by the authorization-request endpoints (see Defining What Credentials to Request). You do not create sessions directly.
Every session belongs to a registered verifier and carries a state that advances as the holder interacts with the request.
You can observe a session two ways:
Poll the session with
GET /verification-sessions/{sessionId}whenever you need its latest state.Subscribe to
GET /verification-sessions/{sessionId}/eventsand react tosessionevents as the Verifier pushes them, which avoids polling.
Both endpoints require a valid OIDC JWT Bearer token (
Authorization: Bearer <token>). They carry no specific role requirement (see Authentication).
Session States
A session moves through the following states. Read the current value from the session's state field.
RequestCreated— the authorization request has been created and is waiting for a wallet to pick it up. This is the initial state.RequestUriRetrieved— a wallet has fetched the request URI and is in the process of responding.ResponseVerified— the holder returned a presentation and the Verifier successfully verified it. This is the terminal success state.Error— the session failed (for example, an invalid presentation was supplied). TheerrorMessagefield describes what went wrong. This is the terminal failure state.
Treat ResponseVerified and Error as final outcomes; once a session reaches either, no further state changes occur.
Get a Verification Session
GET /verification-sessions/{sessionId}
Returns the verification session identified by sessionId. Use this to read the session's current state on demand.
Path Parameters
sessionId(string, required) — the verification session identifier returned when the authorization request was created.
Response Body
A 200 OK response returns the session record:
id— the session identifier.verifierId— the identifier of the verifier that created the session (may be a DID).state— the current session state (see Session States).authorizationRequestId— the authorization request identifier, present for hosted requests.authorizationRequestUri— theopenid4vp://...URI the wallet opens to fulfill the request.authorizationResponseRedirectUri— the redirect URI supplied when the request was created, if any.expiresAt— ISO timestamp when the request expires, if set.errorMessage— the last error observed in the session lifecycle, present whenstateisError.
Example response
Once the holder has presented an [email protected]:sd-jwt credential and the Verifier has checked it, the same call returns "state": "ResponseVerified".
Watch a Verification Session (SSE)
GET /verification-sessions/{sessionId}/events
Opens a Server-Sent Events (SSE) stream for the session. The Verifier immediately emits the session's current state, then pushes a new event every time the state changes — so you can drive UI updates without polling.
Path Parameters
sessionId(string, required) — the verification session identifier.
Event Types
The stream emits two kinds of events, distinguished by the SSE event: field:
session— carries the full session record as itsdatapayload. The same fields as theGETresponse are included, serialized as JSON. The firstsessionevent reflects the session's current state at subscription time; each subsequent one corresponds to a state change.ping— a heartbeat with thedatapayloadkeepalive, emitted every 15 seconds. It carries no session data; its only purpose is to keep the connection alive and let you detect a dropped stream. Ignorepingevents in your handler.
Example stream
The stream stays open after a terminal state; close it from the client once you observe ResponseVerified or Error.
Consuming the Stream with EventSource
In the browser, use the native EventSource API. Because session and ping are named events, register a listener for each with addEventListener; the default onmessage handler only fires for unnamed events and will not receive them.
The browser's EventSource does not let you set custom request headers, so it cannot attach an Authorization: Bearer token directly. Because this endpoint requires a valid token, the browser must not connect to it directly in production. Instead, terminate the SSE stream behind your own backend: hold the Bearer token there, subscribe to the Verifier's stream with a server-side SSE client (or HTTP client that streams the response), and relay the session and ping events to the browser over a route on your own origin. See Front-End Integration for a full backend-relay example. Only in local development with AUTH_DISABLED=true can the browser connect to the endpoint directly.
Notes
Sessions are created by the authorization-request endpoints; this page covers reading and watching them. See Defining What Credentials to Request for how a session begins.
Authentication is an OIDC JWT Bearer token; these endpoints require a valid token but no specific role.
The SSE stream is the recommended way to react to verification outcomes in near real time; fall back to polling
GET /verification-sessions/{sessionId}where a long-lived connection is impractical.
Last updated