acme:proof-of-degree or didx:basic-identity-request).
To verify something, you pick a preset and create a request from it for a specific user. Think of the preset as a checklist: “show me a credential of this type, with these fields, signed by one of these issuers.” The user’s wallet receives the checklist, finds credentials that satisfy each line, and returns just the requested fields — already cryptographically validated end to end.
The shape, end to end
templateCredentials.
Identity and metadata
Once published, a preset is immutable; the identifier you choose at creation lives forever. Choose the slug carefully.
templateCredentials: the request itself
This array carries the request itself. Each entry is a credential the user must produce for the request to be satisfied. If the array has one entry, one credential is enough; two entries means the user must produce credentials matching both, and so on. Entries can mix formats — one preset can ask for an SD-JWT credential and an mDoc credential in the same request.
A single entry expresses three things: which kind of credential, which fields from it, and which issuers count as proof.
format and type: which kind of credential
The
type must exactly match the type that issuers put on the credentials they issue. Even a one-character mismatch fails.
attributes: which fields you want back
The shape of the attributes map depends on format.
SD-JWT uses a flat map of attribute name to (currently empty) definition:
properties carry the attribute names and an intentToRetain flag:
intentToRetain is the verifier’s signal to the holder about whether it intends to store the attribute after presentation (privacy-relevant under ISO 18013-5). Set true when you genuinely need to retain the value (e.g. record-keeping); set false for transient checks (e.g. age gate).
In both formats, only the attributes listed here are requested. The user’s wallet uses selective disclosure to reveal just those, leaving anything else in the credential hidden.
trustedIssuers: which issuers count as proof
The issuers whose signature on this credential type counts as proof. Even if the user holds a credential of the right type, it only counts if it’s signed by an issuer in this list. This is the part that makes verification with verifiable credentials powerful: you’re not only asking what the user has, you’re declaring which issuers you accept it from.
Each entry describes an issuer directly, with a human-readable name:
kind: "did". A Decentralised Identifier the issuer publishes (e.g.did:web:sarb.gov.za, hosted athttps://sarb.gov.za/.well-known/did.json). The wallet resolves the DID to fetch the issuer’s signing key.kind: "x509". A PEM-encoded X.509 certificate. Used for issuers that operate via traditional PKI (common for ISO 18013-5 mDLs).
name is what the wallet shows the user when asking for consent. Choose one the user will recognise.
What happens at presentation time
When a verifier creates a presentation request from a preset, the wallet on the other end uses the preset’s structure directly:- The verifier creates a presentation request (passing
presetId). - The user’s wallet receives the request and reads each entry’s
type,attributes, andtrustedIssuers. - For each entry, the wallet resolves
trustedIssuers(fetching DID documents or validating cert chains) to determine which signing keys are acceptable. - It then only shows the user credentials of the right
typesigned by one of those issuers. Anything else is filtered out before the user sees it. - The user picks the credentials they want to share, consents, and the wallet returns the requested attributes.
- When the verifier receives the response, the issuer chain has already been validated end to end. No re-verification is needed on the verifier’s side.
Two paths
Browse a presentation preset
Find a preset already published by DIDx or another publisher and use it as-is. The trust list comes baked in.
Create a presentation preset
Publish your own request shape (including the trusted issuers) so it can be referenced by name.

