Skip to main content

Credential Offer

A Credential Offer is the message an issuer sends to a wallet to start issuance under OpenID4VCI: it names the issuer, says which credentials are on offer, and tells the wallet how it is allowed to collect them.

In practice the offer is what sits behind the QR code on an issuance page or the link in an email or app. It can be delivered by value, embedded directly in an openid-credential-offer:// deep link or QR payload, or by reference, as a URL the wallet fetches to retrieve the same content, which keeps the code short when the offer names several credentials or carries a long issuer state. Scanning or opening it hands the wallet the issuer's URL and one or more credential configuration identifiers, plus a grant that decides the rest of the flow: an authorization code grant sends the holder through the issuer's own login first, useful when the offer was generated on a different device to the one completing the flow, while a pre-authorized code grant is used when the holder was already authenticated where the offer was created, for example right after logging into a government portal, optionally protected by a transaction code shown on that same channel so a code intercepted in transit cannot be redeemed by someone else. From there the wallet reads the issuer's metadata to learn what the named credentials actually contain, exchanges the grant for an access token at the issuer's token endpoint, and calls the credential endpoint to collect what was offered, one credential or a batch at a time depending on what the issuer supports.

Why do some Credential Offers ask for a transaction code and others do not?

A transaction code is required whenever the offer uses a pre-authorized code grant, since the holder was already authenticated on another channel and the code proves the person scanning the offer is the same person that channel authenticated. An authorization code grant instead sends the holder through the issuer's own login as part of the flow, so there is no separate channel to bind and no code needed.

Back to the glossary