mdoc/mDL
Proven and the Holdr SDK provide the capability to issue, hold, and verify credentials in the mdoc/mDL format over a variety of protocols. The following documentation describes how to use Proven for the server portions of mdoc/mDL workflows.
There are currently four categories of APIs for working with mdoc/mDL credentials over OID4VC: Keys, Schemas, Issuance, and Verification. These categories of APIs should be approached sequentially, e.g. it doesn't work to use the verification APIs if you haven't configured keys.
Keys
Key Initialization
Provision mDoc issuer key material so that you can securely issue mdoc and mDL credentials.
Example curl Command:
curl --location 'https://buckets4life.share.zrok.io/api/v1/oid4vci/setup/mdoc' \
--header 'x-api-key: HuNsaIP9w0LsM5vqRhWprqLShgWLvb2yMAyuYUjWqd4=' \
--header 'Content-Type: application/json' \
--header 'Cookie: sessionId=s%3AIxantPaS5ZGMmrHZDetRQHQIVTRBiNBL.DAjBpQO8pxrjJdM4jQUYJU%2FlxzGAGIJcUzM%2FM7zltk0' \
--data '{
"force": false
}'Request (POST)
force{boolean}: Whether to force the creation of a new key or not. Use false for first-time initialization or in case you don't want to overwrite the key (if one exists). Use true to rotate the key.
Response
key_id{string}: This string will allow you to identify the key that the system is using for mdoc, allowing you assess the state of the system (e.g., are we still using the same key as 6 months ago?). Useful to save. Sample:8d3e8f18-5e7d-4f1a-a72b-1db2f1d0c001cert_id{string}: This string will allow you to identify the certificate that the system is using to identify itself to other entities, allowing you to assess the state of the system (e.g. is this the endpoint or agent I think it is?). Useful to save. Sample:6af84a3c-b6e9-4b1c-844a-6ce6a1f2d002message{string}: Human readable text that describes the result of the operation (e.g., mDoc issuer keys provisioned successfully). Sample:mDoc issuer keys provisioned successfully.
Key Status
Use this API to check whether the agent has been initialized with mdoc issuer key material and is ready to issue credentials.
Example curl Command:
Request
No request body or parameters.
Response
keys{array of objects}: The key(s) currently provisioned for mdoc issuance. Each object contains:key_id{string}: The identifier of the provisioned key. Sample:8d3e8f18-5e7d-4f1a-a72b-1db2f1d0c001cert_id{string}: The identifier of the certificate associated with this key. Sample:6af84a3c-b6e9-4b1c-844a-6ce6a1f2d002
defaultCertificate{object}: The certificate currently designated as the default for mdoc issuance.cert_id{string}: The identifier of the default certificate. Sample:6af84a3c-b6e9-4b1c-844a-6ce6a1f2d002key_id{string}: The identifier of the key associated with this certificate. Sample:8d3e8f18-5e7d-4f1a-a72b-1db2f1d0c001subject_dn{string}: The subject distinguished name of the certificate. Sample:CN=Proven mDoc Issuerissuer_dn{string}: The issuer distinguished name of the certificate. Sample:CN=Proven mDoc Issuer
trustAnchors{array}: The trust anchors configured for this issuer. Empty if none have been configured.
Schemas
Setup a Schema
Use this API to configure the system to issue credentials of a particular schema, i.e. set things up so you can issue mDLs, passports, national IDs, etc.
Example curl Command:
Request (POST)
doctype{string} Required: The mdoc document type identifier (e.g.,org.iso.18013.5.1.mDL).label{string}: A human-readable name for this credential type (e.g.,Mobile Driver's License).description{string}: A human-readable description of this credential type (e.g.,ISO 18013-5 Mobile Driver's License).display{array of objects}: Display metadata for the credential type, used for rendering in wallets and verifier UIs.verification_method{string}: The verification method to use when signing credentials of this type.issuer_id{string}: The DID or identifier of the issuer for this credential type.claims_schema{object}: An object defining the namespaces and claims this credential type supports.vc_additional_data{object}: Additional data to include in the credential.cryptographic_binding_methods_supported{array of strings}: Cryptographic binding methods supported for this credential type.cryptographic_suites_supported{array of strings}: Cryptographic suites supported for this credential type.proof_types_supported{object}: Proof types supported for this credential type.
Response
agentRecord{object}: The record created in the agent.supported_cred_id{string}: Unique identifier for this credential type in the agent. Sample:9fd5ef9d-b8b8-4f52-b6a9-95b9ce4f6f8aidentifier{string}: The doctype string used as the credential type identifier. Sample:org.iso.18013.5.1.mDLformat{string}: The credential format. Alwaysmso_mdocfor mdoc credentials.display{array of objects}: Display metadata as stored in the agent.format_data{object}: The doctype and claims as stored in the agent.
dbConfig{object}: The configuration record stored in the Proven database.config_id{string}: Unique identifier for this configuration record. Sample:c4d8f7f2-f8d0-4d0b-93d0-9f9f31a5c003wallet_id{string}: The wallet this configuration is associated with. Sample:wallet-123doctype{string}: The document type identifier as provided in the request.supported_cred_id{string}: Matches thesupported_cred_idinagentRecord.format{string}: The credential format. Alwaysmso_mdoc.label{string}: The human-readable label as provided in the request.description{string}: The human-readable description as provided in the request.created_at{string}: ISO 8601 timestamp of when the record was created.updated_at{string}: ISO 8601 timestamp of when the record was last updated.
List Schemas
Example curl Command:
Request (GET)
Optional query parameters:
doctype{string}: Filter results to a specific document type.config_id{string}: Filter results to a specific configuration record.
Response
Returns an array of configuration objects, each with the same fields as the dbConfig object in the POST response above.
Issuance
Use this API to create a credential exchange and generate an offer that can be delivered to a holder's wallet.
Example curl Command:
Request (POST)
supported_cred_id{string}: The ID of the registered credential type to issue, obtained from the Schema Setup step. Sample:9fd5ef9d-b8b8-4f52-b6a9-95b9ce4f6f8acredential_subject{object}: The claims to include in the credential. Keys should match the claims defined when the credential type was registered. For an mDL, common fields includefamily_name,given_name,birth_date,issue_date,expiry_date,issuing_country,issuing_authority,document_number,driving_privileges,un_distinguishing_sign, andportrait.did{string}: The DID to associate with the credential subject.verification_method{string}: The verification method to use for signing this credential. If omitted, the system uses the verification method configured for the credential type.pin{string}: An optional user PIN for the credential offer, adding an extra layer of security to the issuance flow.label{string}: A human-readable label for this credential exchange.connection_id{string}: The connection ID to associate with this credential exchange.
Response
offer{object}: The credential offer object, suitable for delivery to a holder's wallet.credential_issuer{string}: The URL of the credential issuer. Sample:https://example/oid4vc/tenant/c286d1c7-c548-48d1-8580-76d3fe317bffcredentials{array of strings}: The credential type identifiers included in this offer. For an mDL this will be["org.iso.18013.5.1.mDL"].grants{object}: The grant types available for this offer. For mdoc/mDL issuance, this will contain a pre-authorized code grant.urn:ietf:params:oauth:grant-type:pre-authorized_code{object}: The pre-authorized code grant.pre-authorized_code{string}: The pre-authorized code the holder's wallet uses to retrieve the credential. Sample:iQ7DWmf2vjogMtQ_bdrDQguser_pin_required{boolean}: Whether the holder is required to supply a PIN to redeem the offer.
credential_offer{string}: A URL-encodedopenid-credential-offer://URI. This is typically rendered as a QR code or deep link for the holder's wallet to scan or tap.exchange{object}: The credential exchange record created by this request.exchange_id{string}: Unique identifier for this exchange. Sample:921786c9-dd65-473a-bebf-e5283d689c96supported_cred_id{string}: The credential type ID used for this exchange, matching the value from the request.credential_subject{object}: The claims as provided in the request.verification_method{string}: The verification method that will be used to sign the credential. Sample:did:key:zDnaevgeiLuxFHYTHCHb1eAr489xPuCy3pDamtiGe5pWPvU41#zDnaevgeiLuxFHYTHCHb1eAr489xPuCy3pDamtiGe5pWPvU41issuer_id{string}: The DID of the issuer. Sample:did:key:zDnaevgeiLuxFHYTHCHb1eAr489xPuCy3pDamtiGe5pWPvU41state{string}: The current state of the exchange. Will becreatedimmediately after issuance is initiated.created_at{string}: ISO 8601 timestamp of when the exchange was created.updated_at{string}: ISO 8601 timestamp of when the exchange was last updated.
Verification
Verification is a multi-step process. First, you create a presentation definition that describes what claims you want to verify. Then, you use that definition to create a presentation request, which generates a URI that can be delivered to a holder's wallet (e.g., as a QR code). Finally, after the holder responds, you retrieve the presentation results.
Create a Presentation Definition
Use this API to define what credentials and claims you want to request from a holder.
Example curl Command:
Request (POST)
pres_def {object}: The presentation definition object, following the DIF Presentation Exchange specification.
id{string}: An optional identifier for the presentation definition. If omitted, the system will generate one.purpose{string}: A human-readable string describing the purpose of the verification request.input_descriptors{array of objects}: One or more descriptors specifying what credentials and claims are required.id{string}: An identifier for this input descriptor. For mdoc, typically the doctype (e.g.,org.iso.18013.5.1.mDL).format{object}: Specifies the credential format. For mdoc verification, use"mso_mdoc": { "alg": ["ES256"] }.constraints{object}: Defines the constraints on the requested claims.limit_disclosure{string}: Set to"required"to ensure only the requested claims are disclosed.fields{array of objects}: The specific claims to request. Each field has apatharray using JSONPath notation. For mdoc claims, use the namespace-qualified syntax:$['org.iso.18013.5.1']['claim_name'].
Response
pres_def_id{string}: The system-generated identifier for this presentation definition. Save this — you will need it to create a presentation request. Sample:42c870ae-b605-4121-b5e3-1e6bb3a00c6fpres_def{object}: The presentation definition as stored, including any system-generated fields such asid.wallet_id{string}: The wallet associated with this definition. Sample:c286d1c7-c548-48d1-8580-76d3fe317bffcreated_at{string}: ISO 8601 timestamp of when the record was created.updated_at{string}: ISO 8601 timestamp of when the record was last updated.
List Presentation Definitions
Retrieve all presentation definitions registered for your wallet.
Example curl Command:
Request (GET)
No request body or parameters.
Response
Returns an array of presentation definition objects, each with the same fields as the POST response for creating a presentation definition above.
Get a Single Presentation Definition
Example curl Command:
Request (GET)
pres_def_id{string} (path parameter, required): The identifier of the presentation definition to retrieve.
Response
Returns a single presentation definition object with the same fields as the POST response for creating a presentation definition above.
Delete a Presentation Definition
Example curl Command:
Request (DELETE)
pres_def_id{string} (path parameter, required): The identifier of the presentation definition to delete.
Response
Only an HTTP status response code is returned.
Create a Presentation Request
Use this API to generate a presentation request from a previously created presentation definition. The response includes a URI that can be rendered as a QR code or delivered as a deep link for the holder's wallet to scan.
Example curl Command:
Request (POST)
pres_def_id{string}: The identifier of the presentation definition to use, obtained from Step 1. Sample:42c870ae-b605-4121-b5e3-1e6bb3a00c6fvp_formats{object}: The verifiable presentation formats to accept. For mdoc verification, use"mso_mdoc": { "alg": ["ES256"] }.
Response
request_uri{string}: A URL-encodedopenid4vp://URI. This is typically rendered as a QR code or deep link for the holder's wallet to scan or tap. Sample:openid4vp://?client_id=did%3Ajwk%3A...&request_uri=https%3A//example/oid4vc/tenant/.../oid4vp/request/43050ce4-bfb4-4454-b5de-9bbd1c564a85request{object}: The presentation request record.request_id{string}: Unique identifier for this request. Sample:43050ce4-bfb4-4454-b5de-9bbd1c564a85pres_def_id{string}: The presentation definition used for this request.vp_formats{object}: The verifiable presentation formats as provided in the request.created_at{string}: ISO 8601 timestamp of when the request was created.updated_at{string}: ISO 8601 timestamp of when the request was last updated.
presentation{object}: The presentation exchange record created by this request.presentation_id{string}: Unique identifier for this presentation exchange. Use this to poll for results. Sample:5e871b45-3821-4a94-8695-303517939afbpres_def_id{string}: The presentation definition used.request_id{string}: The request that initiated this presentation exchange.state{string}: The current state of the presentation. Will berequest-createdimmediately after the request is made.created_at{string}: ISO 8601 timestamp of when the presentation exchange was created.updated_at{string}: ISO 8601 timestamp of when the presentation exchange was last updated.
Retrieve Presentation Results
After the holder's wallet responds to the presentation request, use this API to retrieve all of the results.
Example curl Command:
Request (GET)
Optional query parameters:
sort-field{string}: The field to sort by (defaultupdated_at).sort-direction{string}: Sort direction,ASCorDESC(defaultDESC).page-size{integer}: Number of results per page (default20).current-page{integer}: The page number to retrieve (default1).item-count{integer}: The total number of items.state-filter{string}: Filter results to a specific state (e.g.,done,request-created).contact-id{string}: Filter results to a specific contact.
Response
params{object}: The pagination and filter parameters applied to the query.rows{array of objects}: The presentation records. Key fields on each record include:presentation_exchange_id{string}: Unique identifier for the presentation exchange.state{string}: The current state (e.g.,request-created,done).verified{boolean}: Whether the presented credentials were successfully verified.role{string}: The role in the exchange (e.g.,verifier).presentation{object}: The presented credentials, if available.created_at{string}: ISO 8601 timestamp of when the record was created.updated_at{string}: ISO 8601 timestamp of when the record was last updated.
count{integer}: The total number of presentation records.
Get a Single Presentation
After the holder's wallet responds to the presentation request, use this API to retrieve a specific result.
Example curl Command:
Request (GET)
presentation_exchange_id{string} (path parameter, required): The identifier of the presentation exchange to retrieve.
Response
Returns a single presentation record with the same fields as described in the list response above.
Last updated
Was this helpful?