Issuance Sessions
Every credential offer created by an issuer opens an issuance session that the platform tracks from the moment the offer is generated until the credential is delivered to a wallet (or the offer expires). Issuance sessions let you observe issuance progress, retrieve the offer URI again, and regenerate the QR code — without re-creating the offer.
All issuance-session endpoints require a valid Bearer token:
Authorization: Bearer <token>The service validates the JWT against the configured JWKS endpoint; any valid token is accepted at this layer (see Authentication).
How a session is created
A session is opened automatically when you create a credential offer — there is no separate create-session endpoint. The offer response returns an issuanceSessionId, which is the handle for every operation on this page.
POST /issuers/:issuerDid/credential-offers
POST /issuers/did:key:z6Mkk.../credential-offers
Authorization: Bearer <token>
Content-Type: application/jsonRequest Body
{
"credentialConfigurationIds": ["[email protected]:sd-jwt"],
"requirePin": false,
"issuanceMetadata": {
"claimsByConfigurationId": {
"[email protected]:sd-jwt": {
"employee_id": "EMP-001",
"full_name": "Ada Lovelace",
"department": "Engineering"
}
}
}
}Response Body
credentialOfferUri: The
openid-credential-offer://URI a wallet scans or follows to claim the credential.issuanceSessionId: The identifier of the session opened for this offer. Use it to track progress and to fetch the session's QR code.
credentialConfigurationIds: The credential configuration ids the offer covers, each of the form
Name@Version:format.userPin: Present only when
requirePinistrue; the PIN the holder must enter to complete the pre-authorized code flow.
Optional fields such as userPin are omitted from the JSON when they do not apply (for example, when requirePin is false) rather than returned as null. Keep the returned issuanceSessionId — it is the path parameter for the get-session and QR-code endpoints below.
List sessions for an issuer
Returns all issuance sessions belonging to a single issuer DID, most useful for an operator dashboard that shows pending and completed offers. The issuerId query parameter filters sessions to one issuer; it is not checked against existing issuers, and omitting it returns all issuance sessions across all issuers.
GET /issuance-sessions?issuerId=<issuerId>
Response Body
issuerId: The issuer DID to filter by, passed as the
issuerIdquery parameter.
For a freshly created OfferCreated session, issuedCredentials is an empty array (no credentials have been issued yet), and the optional userPin and errorMessage fields are absent from the JSON because they do not apply.
Get a single session
Reads one session by its identifier, returning its current state and all tracking fields.
GET /issuance-sessions/:sessionId
Response Body
Optional fields are omitted when they do not apply: userPin appears only when the offer required a PIN, and errorMessage appears only when the session ended in the Error state.
Session fields
id: Internal session identifier (the same value as
issuanceSessionIdfrom the offer response).issuerId: The issuer DID that owns the session.
state: Current lifecycle state of the session (see below).
credentialOfferUri: The credential offer URI tied to the session.
createdAt: ISO 8601 timestamp of when the session (and offer) was created.
expiresAt: ISO 8601 timestamp after which the offer can no longer be claimed.
userPin: The PIN for the pre-authorized code flow, present only when the offer required one.
errorMessage: A human-readable error message when the session ended in the
Errorstate; otherwise absent.issuedCredentials: The credential configuration ids issued in this session (for example
[email protected]:sd-jwt). It is an empty array until issuance completes, and is filled in as credentials are issued (fully populated once the state reachesCompleted).
Session states
The state field advances through the OpenID4VCI pre-authorized code flow as the wallet interacts with the issuer:
OfferCreated: The offer has been generated and the session is waiting for a wallet to retrieve it.
OfferUriRetrieved: A wallet has fetched the offer payload from the offer URI.
AuthorizationInitiated / AuthorizationGranted: Authorization steps preceding token issuance.
AccessTokenRequested / AccessTokenCreated: The wallet has requested and received an access token to call the credential endpoint.
CredentialRequestReceived: The wallet has submitted a credential request.
CredentialsPartiallyIssued: At least one — but not all — of the offered credentials has been issued.
Completed: All offered credentials have been issued;
issuedCredentialslists their configuration ids.Error: Issuance failed;
errorMessagedescribes what went wrong.
To track issuance progress, poll GET /issuance-sessions/:sessionId and watch the state field. A session is finished when it reaches Completed (success) or Error (failure), or when expiresAt has passed without completion.
Get the session QR code
Returns a PNG QR code that encodes the session's credential offer URI. This is handy for re-displaying an offer for an existing session without creating a new one — for example, refreshing the QR shown in an operator panel.
GET /issuance-sessions/:sessionId/qr-code
Response
Body: A 400×400 PNG image (
Content-Type: image/png) of the QR code.Header
X-Credential-Offer-Uri: Theopenid-credential-offer://URI encoded in the QR code, so callers can copy the offer without decoding the image.
A wallet that scans this QR code is taken through the same flow as the original offer, and its progress is reflected in the same session. The endpoint always regenerates the image from the session's stored offer URI, so it stays valid for the life of the offer (until expiresAt).

Notes
Use the
issuanceSessionIdfrom the offer response as the:sessionIdpath parameter for the get-session and QR-code endpoints.If you need the offer URI and QR at creation time rather than after the fact, the credential-offer endpoint has a
qr-codevariant (POST /issuers/:issuerDid/credential-offers/qr-code) that returns the PNG directly withX-Credential-Offer-Uri,X-Issuance-Session-Id, andX-Pinheaders. See the credential issuance flow documentation.
Last updated