Build an issuer
You run the brand side: start an exchange and deliver a signed authenticity credential into the product's wallet — over the same VCALM exchange loop the wallet speaks.
You'll do exactly 3 things
- Expose an interaction URL (on a tag, QR, or link) that advertises
vcapi. - When the wallet POSTs to your exchange URL, respond with the
authenticity credential in a
verifiablePresentation. - Optionally bind the credential to the current owner first, then deliver; finish the exchange.
1. Advertise the exchange
The wallet dereferences your interaction URL (iuv=1) and you
return the protocols you support. Offer vcapi for VCALM:
{
"protocols": {
"vcapi": "https://issuer.brand.example/exchanges/bag-456"
}
}
2. Deliver the credential
The wallet POSTs an empty body to start. You respond with the signed
authenticity credential wrapped in a verifiablePresentation:
{
"verifiablePresentation": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiablePresentation"],
"verifiableCredential": [{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://w3id.org/traceability/v1"
],
"type": ["VerifiableCredential", "ProductPassportCredential"],
"issuer": "did:web:brand.example",
"credentialSubject": {
"id": "did:example:bag-456",
"product": {"sku": "HB-2026-0042", "model": "Atelier Tote"},
"origin": {"country": "FR", "facility": "Paris Atelier"},
"manufacturedOn": "2026-03-14"
},
"proof": { "...": "brand signature" }
}]
}
}
The exchange is complete when you return no
verifiablePresentationRequest.
3. (Optional) Bind to the current owner first
To tie the credential to whoever holds the product, respond to the wallet's
first POST with a verifiablePresentationRequest for DID
Authentication, then deliver on the next turn:
{
"verifiablePresentationRequest": {
"query": [{
"type": "DIDAuthentication",
"acceptedMethods": [{"method": "example"}]
}],
"challenge": "99612b24-63d9-11ea-b99f-4f66f3e4f81a",
"domain": "issuer.brand.example"
}
}
That's it
A conformant provenance issuer is this exchange: advertise, deliver, confirm. Signing the credential is your issuer instance's job — the coordinator just runs the exchange.
Prefer a library to raw HTTP?
Issuer-side helpers live in Digital Bazaar's Bedrock VC modules. A dogfooded standalone VCALM client is planned; until it ships, the HTTP flow above is the supported path.