Skip to main content

Receiving a Credential

Overview

When your wallet receives a credential offer from an issuer, the process varies depending on the authorization flow used. This guide covers the three supported flows:

  1. Pre-Authorized Code Flow: The issuer has already authorized the credential issuance

  2. Authorization Code Flow (issuer-initiated): The issuer starts the flow with an invitation

  3. Authorization Code Flow (wallet-initiated): Your wallet initiates the credential request

Handle Invitation

Most credential issuance flows begin when an issuer shares an invitation URL (often as a QR code). Use the "Handle invitation" endpoints to parse the invitation and determine the next steps.

Your system must support the issuance protocol used by the issuer to parse the invitation correctly.

curl -L -X POST '/api/interaction/v1/handle-invitation' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"url": "openid-credential-offer-final1://?credential_offer_uri=https...", // Get invitation URL from QR code or deep link
"redirectUri": "myapp://callback" // Your registered deep link
}'

Request parameters

  • url (required): The invitation URL from the issuer
  • redirectUri: Your wallet's registered deep link where the authorization server should redirect after authentication. This URI must be registered as a deep link in your wallet application. This value is required for Authorization Code Flows and ignored in Pre-Authorized Code Flows.
  • transport: For wallets with multiple transport protocols enabled, use this array to specify which transport protocol(s) should be used.
Transport protocol selection
hint

This is typically only applicable to mobile devices, which could have, for example, BLE and MQTT transport protocols.

The system determines which transport protocol to use based on both the transport array and your transport order configuration:

transport array valueSystem behavior
Not provided or []Uses the transport protocol with the highest order value from your configuration
[one value]Uses the specified transport protocol
[multiple values]Uses the first supported transport found, following the order in your configuration

See the supportedTransports capability of your verification protocol for supported options.

Related guide: Transport order configuration

Response

This endpoint returns information that determines which flow to follow:

  • interactionId: A unique reference for the interaction
  • interactionType: Will be ISSUANCE for credential offers
  • authorizationCodeFlowUrl (conditional): If present, you must follow the Authorization Code Flow (issuer-initiated). Redirect the user to this URL to complete authentication.
  • keyStorageSecurity: An enum providing guidance on the security required for issuance of the credential.
  • txCode (conditional): If present, the issuer requires a transaction code. The user must provide this code to complete issuance.

Determining the next steps

Based on the response from "Handle invitation":

Response includesNext action
authorizationCodeFlowUrlFollow the Authorization Code Flow (issuer-initiated)
txCode objectPrompt user for transaction code, then [accept with transaction code]
NeitherContinue directly to [accept the credential]

Pre-Authorized Code Flow

In this flow, the issuer has already authorized the credential issuance. After handling the invitation, you can immediately accept the credential.

Accept credential issuance

Call the "Accept issuance" endpoint to accept the credential offer. There are two options when accepting an offer:

  • Let the system auto-generate a new key pair (recommended)
  • Specify an existing identifier

When letting the system auto-generate a new key pair, you only need to reference the interactionId. The key pair will be generated according to your configuration. See Auto-Generate Keys for Credential Issuance for a configuration guide.

Transaction codes

Some issuers require a transaction code to complete credential issuance. The issuer provides this code through a separate channel – for example, via email, SMS, or displayed on their website.

When "Handle invitation" returns a txCode object, you must prompt the user to enter this code.

Transaction code object

The txCode object contains:

  • length: The expected length of the code
  • inputMode: The type of input expected (for example numeric, text)
  • description: Instructions for the user on where to find or how to use the code

Accepting with a transaction code

Include the user-provided transaction code in the "Accept issuance" request:

curl -L -X POST '/api/interaction/v1/issuance-accept' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"identifierId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", // Choose an identifier
"interactionId": "27755a19-f29f-434a-bf65-fcaed99a3642", // From handle invitation response
"txCode": "123456" // User-provided transaction code
}'

The endpoint returns the credential ID directly.

Retrieve the credential

Accepting an issuance returns the credential ID. Retrieve it for the user to review.

Authorization Code Flow (issuer-initiated)

To enable this flow, the issuer and client ID must be specified in the configuration.

Security

This flow supports PKCE (Proof Key for Code Exchange) and PAR (Pushed Authorization Requests) for enhanced security. These are handled automatically by the system.

When "Handle invitation" returns an authorizationCodeFlowUrl, the user must complete authentication before the credential can be issued.

Step 1: Redirect to authorization server

When "Handle invitation" returns an authorizationCodeFlowUrl, redirect the user to this URL. The user will complete authentication with the authorization server outside your wallet system.

Step 2: Continue issuance

Once authentication is complete, the authorization server redirects the user back to your wallet using the redirectUri you provided. Pass the redirect URL to the "Continue Issuance" endpoint to exchange the authorization code for an access token.

The response returns the same information as "Handle invitation":

  • interactionId: A unique reference for the interaction
  • interactionType: Will be ISSUANCE for credential offers

Step 3: Accept and retrieve

After continuing issuance, follow the same process as the Pre-Authorized Code Flow to accept and retrieve the credential.

Authorization Code Flow (wallet-initiated)

Use this flow when your wallet initiates the credential request rather than responding to an issuer's invitation.

Security

This flow supports PKCE (Proof Key for Code Exchange) and PAR (Pushed Authorization Requests) for enhanced security. These are handled automatically by the system.

Step 1: Initiate issuance

For wallet-initiated flows, use this endpoint to make the initial request for credential issuance. This endpoint requires authorization request parameters.

The following is an example call:

curl -L -X POST '/api/interaction/v1/initiate-issuance' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"protocol": "OpenID4VCI", // From your configuration
"issuer": "https://example.com", // Issuer URL
"clientId": "openid-client", // Wallet's client ID
"redirectUri": "https://example.com", // Optional
"scope": [ // Either provide the scope, OR
"bli",
"blu"
],
"authorizationDetails": [ // Provide the authorizationDetails
{
"type": "openid_credential",
"credentialConfigurationId": "UniversityDegreeCredential"
}
]
}'

The issuer responds with the authorization endpoint URL; the end user can follow this to complete the authorization process with the authorization server.

Step 2: Continue issuance

Once authentication is complete, the authorization server redirects the user back to your wallet using the redirectUri you provided. Pass the redirect URL to the "Continue Issuance" endpoint to exchange the authorization code for an access token.

The response returns the same information as "Handle invitation":

  • interactionId: A unique reference for the interaction
  • interactionType: Will be ISSUANCE for credential offers

Step 3: Accept and retrieve

After continuing issuance, follow the same process as the Pre-Authorized Code Flow to accept and retrieve the credential.

Optional: Reject an Offer

If you are within the token expiration time, you can optionally reject a credential offer. This action:

  • Sends a "credential_deleted" notification to the issuer (if supported)
  • Sets the credential status to REJECTED in your wallet system

Some issuers using OpenID4VCI include an optional notification_id during credential issuance. When present, this enables your wallet to send status updates back to the issuer about what happened with the offer.