API Reference
Create Credential Offer
Generate a new OID4VCI Pre-Authorized Code credential offer.
This offer can only be used once. Once the offer is successfully claimed and the credential is issued, the pre-authorized code is consumed and the offer becomes invalid. The offer cannot be claimed again, even if the same user attempts to claim it. This is a security measure to prevent unauthorized credential duplication. If you need to issue another credential to the same user, you must generate a new credential offer.
The total size of the request cannot exceed 500KB, including any claims. This is mostly relevant when including large claims such as images. When holders present credentials over Bluetooth Low Energy (BLE), keep payloads as small as practical, as large claims can degrade the transfer experience. Reserve larger payloads for remote presentation flows.
Roles
Analytics Events
bearerAuthAuthorizationBearer <token>application/json- body
credentials*array<string>|The credentials to include in the offer, provided either as an array of mDocs credential configuration identifiers, or as a map of those identifiers to claim set identifiers.
userId?stringUnique system generated identifier to reference the user for this offer. This can be obtained by searching for a user. If not provided, a new user entity will be created.
When credentialBundleId is provided and userId is omitted, the offer is automatically scoped to the userId associated with that bundle.
transactionCodeConfiguration?Configure whether a second-factor transaction code is required for this offer. If a configuration is provided, a code will be generated for the offer, and the end user must submit it during credential retrieval. If an incorrect transaction code is entered three times by the holder, the credential offer is permanently invalidated and the wallet can no longer claim the credential.
credentialBundleId?stringThe identifier of an existing credential bundle. When provided, the issued credential replaces the credential in the specified bundle rather than creating a new bundle, updating the credential in place. The bundle keeps its credentialBundleId and credentialReferenceId, so references you hold against the bundle stay valid.
credentials must still be provided, and must name exactly one credential configuration that resolves to the same credential type as the bundle. A bundle holds a single credential type, so an offer naming more than one configuration cannot target one.
If the bundle was issued for a claim set, credentials must use the map form and name exactly that claim set. Use the array form only for a bundle issued without a claim set. See Update a credential issued for a claim set.
When userId is omitted and credentialBundleId is supplied, the offer is automatically scoped to the bundle's userId. When userId is provided, it must match the bundle's userId.
If the bundle is bound to a wallet instance, only that wallet instance can claim the offer. MATTR VII checks the claiming wallet's client attestation key against the key bound to the bundle, and does not issue a credential if they do not match. To make sure only the wallet instance that holds the credential can claim an update, issue the original credential with Wallet Attestation.
If a prior offer targeting the same bundle has expired or was not claimed, you may call this endpoint again with the same credentialBundleId.
Credential update is offered as an open beta preview feature and is not generally available yet. It is available on all tenants, and its behavior may change in a way that breaks existing integrations before it becomes generally available.
claims?Additional user claims that are available during credential issuance for this offer.
claimSets?The claims for each claim set, keyed by credential configuration identifier and then by claim set identifier.
This property requires the map form of credentials, and every claim set identifier it references must be listed against the same credential configuration in credentials.
Claims provided here are specific to a single claim set. Where the same claim name also appears in the sibling claims object, the claim set value is used for that credential.
claimsToPersist?array<string>This array includes a list of claims that will be persisted against the user object in the MATTR VII database. These claims are then available for any future credential offers or issuance operations for this user. By default no claims are persisted, and it is recommended to consider carefully which claims to persist, if any, as this has implications for data privacy and security. When claimSets is provided, the listed claims are also persisted from each claim set against the user's claimSets.
expiresIn?Specifies when the offer will expire. Once the offer expires, the user can no longer use it to claim a credential, and a new offer must be generated. The expiration period can include any combination of minutes and seconds. By default, the offer expires in 5 minutes, and the maximum allowed duration is 10 minutes.
Credential offer created
application/json- response
id*stringUnique system generated identifier to reference this offer.
userId*stringA unique system-generated identifier used to reference the user for this offer.
uri*stringGenerated offer URI that can be sent to the intended holder embedded in a QR code or deep link. The credential offer payload carries the offered credential configuration identifiers in both credential_configuration_ids and the deprecated credentials element. Wallet clients should read credential_configuration_ids, as credentials is retained for backward compatibility only and will be removed. Refer to the OID4VCI v1.0 alignment changelog entry.
expiresAt*stringOffer expiry time in ISO 8601 format.
date-timetransactionCode?stringThe system-generated transaction code. This property is only present if the transactionCodeConfiguration parameter is provided. The transaction code can be shared with the intended holder through an alternative secure communication channel. The holder must enter this code during the credential retrieval flow to successfully claim the credential. If an incorrect transaction code is entered three times, the offer is permanently invalidated and can no longer be used to claim the credential.
curl -X POST "https://example.com/v1/openid/offers/pre-authorized" \ -H "Content-Type: application/json" \ -d '{ "credentials": [ "707e920a-f342-443b-ae24-6946b7b5033e" ] }'{ "id": "string", "userId": "string", "uri": "openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fexample.com%22%2C%22credentials%22%3A%5B%222edaf985-fcc2-4448-9c8e-a04c6c7351c2%22%5D%2C%22credential_configuration_ids%22%3A%5B%222edaf985-fcc2-4448-9c8e-a04c6c7351c2%22%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22stukD6lg9c9tQ3jUCa32wVi1HI%2BQIVsFK%2FQPvC2CHRs%3D%22%2C%22tx_code%22%3A%7B%22length%22%3A6%2C%22input_mode%22%3A%22numeric%22%2C%22description%22%3A%22Please%20provide%20the%20one-time%20code%20that%20was%20sent%20via%20e-mail%22%7D%7D%7D%7D", "expiresAt": "2025-05-01T00:01:00.000Z", "transactionCode": "493536"}Delete Credential Offer
Delete an OID4VCI Pre-authorized Code credential offer.
Roles
Analytics Events
bearerAuthAuthorizationBearer <token>id*stringPre-authorized credential offer ID
uuidCredential offer deleted
curl -X DELETE "https://example.com/v1/openid/offers/pre-authorized/8241400f-de3b-42c5-ad7c-8a380039e796"Issue a verifiable credential
Issues a credential to a holder upon presentation of a valid access token, as per OID4VCI. Supports encrypted and non-encrypted credential issuance.
For non-encrypted credential issuance the valid access token must be provided in one of the following header formats:
Bearer
- Authorization:
Bearer <access_token>. - Content-Type:
application/json - Body:
<credential request payload>
OR
DPoP Only required when using DPoP-bound access tokens.
- Authorization:
DPoP <access_token>. - DPoP:
<dpop_token> - Content-Type:
application/json - Body:
<credential request payload>
For encrypted credential issuance, contact us to configure how your MATTR VII enforces request and/or response encryption, and then:
- For request encryption,
Content-Typemust be set toapplication/jwtand the payload must be JWE formatted. - For response encryption, include the
credential_response_encryptionproperty in the raw request payload to specify encryption details.
Analytics Events
AuthorizationBearer <token>OID4VCI access token presented by a holder's wallet. Use the format: Authorization: Bearer <access_token>.
The wallet obtains this token from your tenant's token endpoint during a credential issuance flow. This is not the tenant management token used by operations that require bearerAuth.
DPoP?stringDPoP proof JWT. A signed JWT that demonstrates proof-of-possession of a private key.
When to use:
- Token endpoint: Required when
dpop_jktwas provided in the authorization request - Credential endpoint: Required when using DPoP-bound access tokens (Authorization header must use format:
Authorization: DPoP <access_token>)
The DPoP proof must be a signed JWT with the following structure:
Header:
alg: Must beES256typ: Must bedpop+jwtjwk: Public key (JWK format)
Payload:
htu: HTTP URI of the target endpointhtm: HTTP method (e.g.,POST)jti: Unique identifier for this DPoP proofiat: Unix timestamp when the DPoP proof was createdath: Optional base64url-encoded SHA-256 hash of theaccess_token. Required when authenticating with the resource server.htcd: Optional base64-encoded SHA-256 hash (content digest) of the HTTP request payload used to validate integrity.
Each DPoP proof must be unique and cannot be reused across requests.
- body
Exactly one of credential_configuration_id or credential_identifier is required.
credential_configuration_id*stringcredential_identifier?Credential IdentifierOne of the credential_identifiers values returned in the token response authorization_details, selecting the credential to issue for a single claim set.
Treat this value as opaque. It is derived by MATTR VII and does not encode the claim set identifier you supplied.
This property is mutually exclusive with credential_configuration_id, and only resolves while it remains bound to the grant. For mDocs, the same value is returned as credential_bundle_id on the credential response, so you can correlate an issued credential back to the claim set it was requested for.
Claim set identifiers are offered as an open beta preview feature and are not generally available yet. They are available on all tenants, and their behavior may change in a way that breaks existing integrations before they become generally available.
proofs?JSON object containing proof of possession of the key material the issued Credential shall be bound to.
credential_response_encryption?JSON object containing details for encrypting the issued credential in the response.
Credential issued
- response
credentials*array<>curl -X POST "https://example.com/v1/openid/credential" \ -H "Content-Type: application/json" \ -d '{ "credential_configuration_id": "2cdb2c15-39a7-4556-abab-4515ce2d831b", "proofs": { "jwt": [ "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..." ] } }'{ "credentials": [ { "credential": { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "id": "http://example.edu/credentials/3732", "type": [ "VerifiableCredential", "AlumniCredential" ], "issuer": "https://example.edu/issuers/14", "issuanceDate": "2020-03-10T04:24:12.164Z", "credentialSubject": { "id": "did:example:123", "alumniOf": "Example University" }, "proof": { "type": "RsaSignature2018", "created": "2020-03-10T04:24:12Z", "proofPurpose": "assertionMethod", "verificationMethod": "https://example.edu/issuers/keys/1", "jws": "EXAMPLE_JWS_TOKEN_eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9aH0..." } } } ]}Retrieve issuer metadata
Returns OID4VCI issuer metadata. This is the standard OID4VCI Well Known endpoint for your tenant.
This endpoint is unprotected, public facing and can be deterministically found at the root of the tenant subdomain or alias by any party wishing to discover the OID4VCI capabilities.
OID4VCI credential issuer metadata retrieved
application/json- response
issuer?stringuriauthorization_endpoint?stringurijwks_uri?stringuritoken_endpoint?stringuriscopes_supported?array<string>response_types_supported?array<string>response_modes_supported?array<string>grant_types_supported?array<string>code_challenge_methods_supported?array<string>credential_issuer?stringuricredential_endpoint?stringuricredentials_supported?array<|||>DeprecatedThis field is deprecated and maintained only for backward compatibility.
Use credential_configurations_supported instead to discover supported credentials.
Refer to the OID4VCI v1.0 alignment changelog entry.
credential_configurations_supported?Supported credential configurations.
mdoc_iacas_uri?stringuricredential_response_encryption?Declares the issuer's ability to encrypt credential responses. When configured, MATTR VII can encrypt credential responses to specific wallet instances using encryption keys provided by the wallet application. This provides end-to-end encryption ensuring that credential data remains confidential and unreadable to intermediary backend servers.
credential_request_encryption?Declares the issuer's ability to receive and decrypt credential requests. When configured, wallet applications can encrypt credential requests to ensure sensitive information in the request is protected in transit. MATTR VII will decrypt the request as part of the issuance flow and enforce the configured encryption policies.
curl --request GET \ --url https://{tenantName}.{region}.mattr.global/.well-known/openid-credential-issuer \ --header 'Accept: application/json'{ "issuer": "http://example.com", "authorization_endpoint": "http://example.com", "jwks_uri": "http://example.com", "token_endpoint": "http://example.com", "scopes_supported": [ "ldp_vc:ExampleCredential" ], "response_types_supported": [ "code" ], "response_modes_supported": [ "query" ], "grant_types_supported": [ "authorization_code" ], "code_challenge_methods_supported": [ "S256" ], "credential_issuer": "http://example.com", "credential_endpoint": "http://example.com", "credentials_supported": [ { "format": "ldp_vc", "id": "string", "scope": "string", "@context": [ "string" ], "type": [ "string" ], "credentialSubject": {}, "cryptographic_binding_methods_supported": [ "did:key", "mso" ], "cryptographic_suites_supported": [ "Ed25519Signature2018", "ES256" ] } ], "credential_configurations_supported": { "2cdb2c15-39a7-4556-abab-4515ce2d831b": { "format": "ldp_vc", "id": "2cdb2c15-39a7-4556-abab-4515ce2d831b", "scope": "ldp_vc:TestCredential", "credential_definition": { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://schema.org" ], "type": [ "VerifiableCredential", "TestCredential" ] }, "credential_signing_alg_values_supported": [ "Ed25519Signature2018", "BbsSignatureProof2022" ], "cryptographic_binding_methods_supported": [ "did:key" ], "proof_types_supported": { "jwt": { "proof_signing_alg_values_supported": [ "EdDSA" ] } }, "credential_metadata": { "display": [ { "name": "Test Credential", "logo": { "uri": "https://example.com/logo.png", "alt_text": "Example Logo" }, "locale": "en-US", "background_color": "#FFFFFF", "text_color": "#000000" } ], "claims": [ { "path": [ "credentialSubject", "firstName" ], "mandatory": true, "display": [ { "name": "First Name", "locale": "en-US" } ] } ] } }, "3dfe1c4a-5b6c-4e2f-9f3a-2b1c4d5e6f7g": { "format": "cwt_vc", "id": "3dfe1c4a-5b6c-4e2f-9f3a-2b1c4d5e6f7g", "scope": "cwt_vc:TestCredential", "types": [ "VerifiableCredential", "TestCredential" ], "cryptographic_binding_methods_supported": [], "credential_signing_alg_values_supported": [ -7 ], "credential_metadata": { "claims": [ { "path": [ "vc", "credentialSubject", "firstName" ], "mandatory": true, "display": [ { "name": "First Name", "locale": "en-US" } ] } ] } }, "b068c060-cc72-4758-9526-92d29edb821f": { "format": "cwt", "id": "b068c060-cc72-4758-9526-92d29edb821f", "scope": "cwt:TestCredential", "type": "TestCredential", "cryptographic_binding_methods_supported": [], "credential_signing_alg_values_supported": [ -7 ], "credential_metadata": { "claims": [ { "path": [ "firstName" ], "mandatory": true, "display": [ { "name": "First Name", "locale": "en-US" } ] } ] } }, "a1b2c3d4-e5f6-4789-abcd-ef0123456789": { "format": "mso_mdoc", "doctype": "org.iso.18013.5.1.mDL.T", "scope": "mso_mdoc:TestCredential", "id": "a1b2c3d4-e5f6-4789-abcd-ef0123456789", "cryptographic_binding_methods_supported": [ "mso" ], "credential_signing_alg_values_supported": [ -7 ], "proof_types_supported": { "jwt": { "proof_signing_alg_values_supported": [ "ES256" ] } }, "credential_metadata": { "claims": [ { "path": [ "org.iso.18013.5.1", "firstName" ], "mandatory": true, "display": [ { "name": "First Name", "locale": "en-US" } ] } ], "display": [ { "name": "Test Mobile Credential", "logo": { "uri": "https://example.com/logo.png", "alt_text": "Example Logo" }, "locale": "en-US", "background_color": "#FFFFFF", "text_color": "#000000" } ] } } }, "mdoc_iacas_uri": "http://example.com", "credential_response_encryption": { "alg_values_supported": [ "HPKE-7" ], "enc_values_supported": [ "A256GCM" ], "encryption_required": false }, "credential_request_encryption": { "jwks": { "keys": [ { "kty": "EC", "kid": "kid", "use": "enc", "crv": "P-256", "alg": "HPKE-7", "x": "YO4epjifD-KWeq1sL2tNmm36BhXnkJ0He-WqMYrp9Fk", "y": "Hekpm0zfK7C-YccH5iBjcIXgf6YdUvNUac_0At55Okk" } ] }, "enc_values_supported": [ "A256GCM" ], "encryption_required": false }}How would you rate this page?
Last updated on