Add Credentials to a Wallet
There are three ways a credential is added to an SVX Wallet:
Issuer-initiated issuance (OpenID4VCI) — the wallet acts on a credential offer, obtains an access token, and collects the issued credential.
Wallet-initiated issuance (OpenID4VCI) - the wallet initiates the issuance by selecting an issuer and credential configuration before obtaining the credential.
Direct import — an already-issued, encoded credential is stored in the wallet in a single call.
In all cases the credential is stored in the wallet, encrypted at rest, and can then be listed, viewed, presented, or deleted.
Prerequisites
An access token — all requests require a
Bearertoken. See Using the Wallet API.An existing wallet. A wallet is identified by its
walletIdand is created withPOST /wallets. See Manage Wallets.POST /wallets{ "external_reference": "wallet-240201" }A key (or DID) to bind the credential to the holder. Most credentials are issued against a holder key; create one with
POST /wallets/{walletId}/keysand note the returnedkid. See Manage Keys.POST /wallets/{walletId}/keys{ "key": { "kty": "EC", "crv": "P-256" } }
Issuer-initiated issuance (OpenID4VCI)
Receiving a credential from an issuer via issuer-initiated issuance is a sequence of three calls. Each call returns a state value that links the steps of a single flow; pass it to the next call.
1. Register the credential offer
The flow begins with a credential offer from an issuer, typically delivered as an openid-credential-offer:// URI (for example, encoded in a QR code). Register the offer with the wallet to start the flow.
Endpoint
Request
You may instead pass a credential_offer_uri directly, or an inline credential_offer object, if you already hold the offer.
Response
The response echoes the resolved offer and returns the state for the flow. The offer's grants indicate how to obtain an access token — here a pre-authorized_code grant that also requires a 4-digit transaction code (PIN).
2. Obtain an access token
Exchange the offer for an access token from the issuer's authorization server.
Endpoint
Request (pre-authorized_code grant)
When the offer specifies a tx_code, supply the PIN the issuer shared with the holder.
Response
Note Authorization code grant: if the offer uses an
authorization_codegrant instead, this call returns anauthorization_urlrather than an access token. Open that URL in a browser, complete the login, and the issuer redirects back to the wallet to continue the flow. The access token is then held against thestateready for the next step.
3. Collect the credential
Request the credential, binding it to a holder key by kid (or to a did). The wallet stores the issued credential automatically and returns it.
Endpoint
Request
Note Provide exactly one of
kidordid.didis only supported forjwt_vc_jsonformat. For thedc+sd-jwtformat the holder's key is embedded as acnf.jwkclaim. For themso_mdocformat the holder's key is embedded asDeviceKeyInfo.
Response
The credential is now stored in the wallet. id is the wallet's identifier for the stored credential, and credential is the issued credential in its encoded form.
You can review in-progress and completed flows for a wallet with GET /wallets/{walletId}/receive, or a single flow with GET /wallets/{walletId}/receive/{state}.
Wallet-initiated issuance (OpenID4VCI)
Obtaining a credential from an issuer via wallet-initiated issuance is a sequence of three calls. Each call returns a state value that links the steps of a single flow; pass it to the next call.
Wallet-initiated issuance uses the OAuth 2.0 Authorization Code grant.
1. Discover the issuer's supported credentials.
Retrieve the Credential Issuer Metadata to determine the issuer identifier and the credential configuration (or scope) to request.
The following values will be required for the next step:
credential_issuersupported_credential_configuration[].scopeof the desired credential
Endpoint
Example Response
2. Obtain an access token
Start the authorization flow with the issuer.
Endpoint
Request
The response returns an authorization_url.
Open this URL in a browser and complete authentication with the issuer. Once authorization is complete, the issuer redirects back to the wallet, which then redirects to the redirect_uri supplied in the request. The wallet stores the resulting access token against the state for the next step.
Response
3. Collect the credential
Request the credential, binding it to a holder key by kid (or to a did). The wallet stores the issued credential automatically and returns it.
Endpoint
Request
Note Provide exactly one of
kidordid.didis only supported forjwt_vc_jsonformat. For thedc+sd-jwtformat the holder's key is embedded as acnf.jwkclaim. For themso_mdocformat the holder's key is embedded asDeviceKeyInfo.
Response
The credential is now stored in the wallet. id is the wallet's identifier for the stored credential, and credential is the issued credential in its encoded form.
You can review in-progress and completed flows for a wallet with GET /wallets/{walletId}/receive, or a single flow with GET /wallets/{walletId}/receive/{state}.
Import a credential directly
If you already hold an issued, encoded credential, store it in the wallet in a single call — no offer or access token is involved. This is useful when a credential is obtained out of band or migrated from another store.
Endpoint
Request
credential– the encoded credential stringformat– the credential format. Supported values:FormatDescriptionjwt_vc_jsonW3C Verifiable Credential as a JWT.
dc+sd-jwtSD-JWT VC (selective disclosure).
mso_mdocISO mdoc / mDL.
Response
The stored credential is returned, including the wallet's id for it and parsed metadata such as the issuer and credential type.
Once stored, a credential can be listed and retrieved with GET /wallets/{walletId}/credentials, presented to a verifier, or removed. See Credentials.
Last updated