What you'll learn
- Recognise the SD-JWT VC credential offer format
- Accept SD-JWT VC credential offers via the Wallet API
- Understand how selective disclosures appear in the API response
Learn how to accept SD-JWT VC credentials (IETF) via OID4VCI in a wallet using walt.id's Wallet API, including the credential offer format and how selective disclosures are represented in the response.
What you'll learn
Relevant concepts
The API call to accept an SD-JWT VC credential is identical to accepting a W3C VC — the same
/wallet-api/wallet/{walletId}/exchange/useOfferRequest endpoint is used. The differences lie in the
credential offer format and the structure of the response.
As with all OID4VCI issuance, the issuer communicates the credential offer via a URL beginning
with openid-credential-offer://.
Example Offer URL
openid-credential-offer://issuer.portal.walt.id/?credential_offer=<credential_offer>
Example Credential Offer Object
For SD-JWT VCs, the offer uses a vct field (Verifiable Credential Type) instead of the types array used by
W3C credentials. This URI uniquely identifies the credential type defined by the issuer.
{
"credential_issuer": "https://issuer.demo.walt.id",
"credential_configuration_ids": [
"identity_credential"
],
"grants": {
"urn:ietf:params:oauth:grant-type:pre-authorized_code": {
"pre-authorized_code": "<pre-authorized_code>",
"user_pin_required": false
}
}
}
Endpoint: /wallet-api/wallet/{walletId}/exchange/useOfferRequest | API Reference
Example Request
curl -X 'POST' \
'http://0.0.0.0:7001/wallet-api/wallet/{walletId}/exchange/useOfferRequest?did={did}' \
-H 'accept: application/json' \
-H 'Content-Type: text/plain' \
-H 'authorization: Bearer {token}' \
-d 'openid-credential-offer://issuer.portal.walt.id/?credential_offer=<credential_offer>'
Path Parameters
walletId: String - The ID of the wallet to receive the credential into. See Accounts & Wallets for how to retrieve it.Query Parameters
did (optional): String - The DID of the wallet holder to use when accepting the credential. If omitted, the wallet's default DID is used.Header Parameters
authorization: String - Bearer token obtained from the login endpoint. Format: Bearer {token}.Body
The credential offer URL received from the issuer, provided as plain text.
openid-credential-offer://issuer.portal.walt.id/?credential_offer=<credential_offer>
When using the terminal, the credential offer URL returned from the issuer may have a % at the end. Make sure to remove this before passing it to the wallet.
Example Response
On success, the API returns a list of the credentials received and stored in the wallet.
[
{
"wallet": "6006b6f4-e651-46db-b6ae-e7bd6e9c40f2",
"id": "urn:uuid:48841c75-36cb-416b-af2e-6d4e606c8ca6",
"document": "eyJraWQiOiJkaWQ6a2V5Ono2TWtqb1JocTFqU05KZExpcnVTWHJGRnhhZ3FyenRaYVhIcUhHVVRLSmJjTnl3cCN6Nk1ram9SaHExalNOSmRMaXJ1U1hyRkZ4YWdxcnp0WmFYSHFIR1VUS0piY055d3AiLCJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwiZW1haWwiOiJqb2huZG9lQGV4YW1wbGUuY29tIiwicGhvbmVfbnVtYmVyIjoiKzEtMjAyLTU1NS0wMTAxIiwiYWRkcmVzcyI6eyJzdHJlZXRfYWRkcmVzcyI6IjEyMyBNYWluIFN0IiwibG9jYWxpdHkiOiJBbnl0b3duIiwicmVnaW9uIjoiQW55c3RhdGUiLCJjb3VudHJ5IjoiVVMifSwiaXNfb3Zlcl8xOCI6dHJ1ZSwiaXNfb3Zlcl8yMSI6dHJ1ZSwiaXNfb3Zlcl82NSI6dHJ1ZSwiaWQiOiJ1cm46dXVpZDo0ODg0MWM3NS0zNmNiLTQxNmItYWYyZS02ZDRlNjA2YzhjYTYiLCJpYXQiOjE3NzYzNTIzNjEsIm5iZiI6MTc3NjM1MjM2MSwiZXhwIjoxODA3ODg4MzYxLCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6ImRpZDprZXk6ejZNa2pvUmhxMWpTTkpkTGlydVNYckZGeGFncXJ6dFphWEhxSEdVVEtKYmNOeXdwIiwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2Iiwia2lkIjoialo0WlFHampnLXpYRmZGNFpmbldfZDhXYkljZ0VYSW9uNGhJbXhhYzRiZyIsIngiOiJuMUNoQTNJSU1SdkVNSm51V055djU0bTVrZURhay1leHN0N3F6eXdPTmZFIiwieSI6Il9qWVN6U19Db3RQX2dMMGxiVUNyZWVOTmU4MXIweHEzMlllSjJ0NG1xblkifX0sInZjdCI6Imh0dHBzOi8vaXNzdWVyLmRlbW8ud2FsdC5pZC9kcmFmdDEzL2lkZW50aXR5X2NyZWRlbnRpYWwiLCJfc2QiOlsid2NXMkJXU2g5MXhneHh1RjhFckJJMkkxOVpoUEFST2pBTEtoZGRrX0JXUSJdfQ.u198RgZC1pv3VbZy7DbMHh6g432qnT4AIHhploWyyITtW5PCbUp_6ewJBvNjwf1tfNu8cDhcdP8E4UyG0djZAQ",
"disclosures": "WyJVd3hscTJaX2ZCdlpZNGF2Y2JDTWpRIiwiYmlydGhkYXRlIiwiMTk0MC0wMS0wMSJd",
"addedOn": "2026-04-16T15:12:41.345828048Z",
"pending": false,
"format": "vc+sd-jwt",
"parsedDocument": {
"given_name": "John",
"family_name": "Doe",
"email": "johndoe@example.com",
"phone_number": "+1-202-555-0101",
"address": {
"street_address": "123 Main St",
"locality": "Anytown",
"region": "Anystate",
"country": "US"
},
"is_over_18": true,
"is_over_21": true,
"is_over_65": true,
"id": "urn:uuid:48841c75-36cb-416b-af2e-6d4e606c8ca6",
"iat": 1776352361,
"nbf": 1776352361,
"exp": 1807888361,
"_sd_alg": "sha-256",
"iss": "did:key:z6MkjoRhq1jSNJdLiruSXrFFxagqrztZaXHqHGUTKJbcNywp",
"cnf": {
"jwk": {
"kty": "EC",
"crv": "P-256",
"kid": "jZ4ZQGjjg-zXFfF4ZfnW_d8WbIcgEXIon4hImxac4bg",
"x": "n1ChA3IIMRvEMJnuWNyv54m5keDak-exst7qzywONfE",
"y": "_jYSzS_CotP_gL0lbUCreeNNe81r0xq32YeJ2t4mqnY"
}
},
"vct": "https://issuer.demo.walt.id/draft13/identity_credential",
"_sd": ["wcW2BWSh91xgxxuF8ErBI2I19ZhPAROjALKhddk_BWQ"]
}
}
]
Response Fields
wallet: String - The ID of the wallet the credential was stored in.id: String - The unique identifier of the stored credential.document: String - The raw signed SD-JWT token.disclosures: String - Base64url-encoded disclosure(s) included with the credential. Each disclosure
encodes a salt, claim name, and claim value — representing a selectively disclosable attribute the
holder can choose to reveal when presenting. Decoding the value from the example above gives:
["Uwxlq2Z_fBvZY4avcbCMjQ", "birthdate", "1940-01-01"]
addedOn: String - ISO 8601 timestamp of when the credential was stored.pending: Boolean - Whether the credential is pending acceptance.format: String - The credential format. vc+sd-jwt identifies this as an IETF SD-JWT VC.parsedDocument: Object - The decoded credential claims as a flat JSON object. Key fields include:
vct: String - The Verifiable Credential Type URI identifying the credential type.iss: String - The DID of the issuer.cnf.jwk: Object - The holder's public key, binding the credential to the wallet._sd_alg: String - The hash algorithm used for selective disclosure (typically sha-256)._sd: Array - Hashes of claims that are selectively disclosable but withheld in this issuance.iat, nbf, exp: Number - Issued at, not before, and expiration timestamps (Unix).On this page