API Reference
This guide covers the Zetrix Verifiable Credential (VC) system API endpoints, organized by the major functions in the VC lifecycle: creating credential templates, issuing credentials, revoking credentials, managing BBS+ issuer accounts, and creating/verifying verifiable presentations. Each endpoint includes its HTTP method and path, a description of its purpose, required request fields, response structure, example requests/responses, and potential error cases.
VC Template APIs
Credential templates define the structure and metadata for credentials that an issuer can later issue. Templates are created and registered on the Zetrix network in two steps: first building a transaction blob, then submitting it after signing. These APIs are typically used by the issuer.
Create Template Blob
Endpoint: POST /cred/vc/template/create
Description: Creates a new credential template and returns a transaction blob that must be signed by the issuer. This blob represents a request to register the template on the blockchain. After obtaining the blob, the issuer should sign it with their Zetrix account private key (Ed25519) and use the Submit Template endpoint to finalize the template registration.
Request Body: (JSON)
templateName
(string): A human-readable name for the credential template (e.g.,"DrivingLicenseTemplate"
).issuerDid
(string): The Decentralized Identifier (DID) of the issuer creating this template. This should correspond to the issuer’s Zetrix DID.signerList
(array of objects): A list of one or more signers (accounts) authorized for this template’s transaction. Typically this will contain one entry for the issuer. Each object includes:signerDid
(string): The DID of an authorized signer (usually the issuer’s DID).publicKey
(string): The signer's public key (Ed25519) in an appropriate encoding (e.g., base58) that will be used to sign the template transaction.
credentialFormat
(array of objects): An array describing each attribute/field in the credential defined by this template. Each object in the array represents one credential field with the following properties:key
(string): A unique key or identifier for the attribute (e.g.,"fullName"
). This will be used as the field name in credential data.attribute
(string): A descriptive name of the attribute (e.g.,"Full Name"
).type
(number): A code or indicator for the data type or category of the attribute. (For example,1
might indicate a text string,2
an image, etc., as defined by the system.)format
(string): The expected format of the attribute’s value (e.g.,"string"
,"date"
,"image/png"
depending on the attribute).mandatory
(boolean): Whether this attribute is mandatory (true
) or optional (false
) for credential issuance.
version
(string): Version identifier for this template (e.g.,"1.0"
). Allows template updates or variations to be tracked.remark
(string): An optional remark or description for the template. This can include any additional information or notes about the template.
Response Body: (JSON)
blobId
(string): An identifier for the created transaction blob (used to reference the blob in the submit call).blob
(string): The transaction blob in hex string or base64 format. This blob encodes the template creation operation and must be signed by the issuer’s private key before submission.
Example Request:
Example Response:
Error Cases:
400 Bad Request
– Missing or invalid fields (e.g., a required field liketemplateName
is empty, or an attribute format is incorrect).401 Unauthorized
– The caller is not authenticated or not allowed to create templates (e.g. invalid API token).409 Conflict
– The template name is already in use or a similar template already exists (if the system enforces unique template names or IDs).500 Internal Server Error
– An unexpected error occurred on the server (e.g., database or blockchain interaction failure).
Submit Template
Endpoint: POST /cred/vc/template/submit
Description: Finalizes the registration of a credential template on the Zetrix blockchain. The issuer must provide the signed transaction blob (from the Create Template Blob step). Upon successful submission, the template becomes available for credential issuance. Use this after signing the blob returned by the create endpoint.
Request Body: (JSON)
blobId
(string): The identifier of the template transaction blob obtained from the create step.signature
(string): The issuer’s digital signature over the blob, typically an Ed25519 signature in hex or base64 format. This is generated by signing theblob
with the issuer’s private key.publicKey
(string): The public key corresponding to the private key used for signing. This should match one of the keys in thesignerList
from the template creation (usually the issuer’s Ed25519 public key).
Response Body: (JSON)
templateId
(string): A unique identifier assigned to the newly created template. This ID will be used to reference the template in subsequent operations (such as credential issuance).templateHash
(string): A hash or transaction ID associated with the template registration on-chain. This can be used for audit or verification purposes to confirm the template was recorded on Zetrix.
Example Request:
Example Response:
Error Cases:
400 Bad Request
– The provided blob or signature is missing or malformed (e.g., wrong length or format).401 Unauthorized
– The signature does not match the issuer’s public key, or the caller is not permitted to submit this template.404 Not Found
– TheblobId
does not correspond to a valid pending template (for example, if it was already submitted or expired).500 Internal Server Error
– An error occurred while processing the transaction (for instance, failure to write to the blockchain).
VC Issuance APIs
Once a template is in place, these APIs manage the issuance of verifiable credentials to holders. The typical flow is: a holder applies for a credential, the issuer creates the credential (generating required signatures and transaction blob), the issuer submits the credential to finalize issuance, and then the credential can be downloaded by the holder or issuer.
Apply VC (by holder)
Endpoint: POST /cred/vc/apply
Description: Initiates a credential issuance request by a holder. The holder (or an application acting on behalf of the holder) calls this to apply for a credential of a given template. This step usually provides the data required for the credential and registers a request that the issuer can review/approve. The output is a VC request ID used to track the issuance process.
Request Body: (JSON)
templateId
(string): The identifier of the credential template the holder is applying for. This should be a valid templateId obtained from the issuer (for example, the ID returned by the template submission).holderDid
(string): The DID of the holder applying for the credential. This identifies the subject who will receive the credential.attributes
(array of objects): The data values for the credential’s attributes, as required by the template. Each entry should provide one attribute’s value:key
(string): The attribute key, exactly as defined in the template’scredentialFormat
.value
(string): The value the holder provides for this attribute. The format/type of this value should conform to what the template specifies (e.g., string, date). For example, if the template requiresfullName
andlicenseNumber
, the holder must provide those values.
holderPublicKey
(string, optional): The holder’s public key (for example, an Ed25519 public key corresponding to the holder’s DID). This may be provided if the system requires associating a specific key with the request (e.g., to later verify the holder’s presentation or for auditing). In many cases, this can be omitted if the holder’s DID document will be used to fetch keys.
Response Body: (JSON)
vcId
(string): A unique identifier for the VC issuance request. This ID represents the pending credential application. It will be used by the issuer to create the credential and can be used by the holder to query status or download the final VC.status
(string): The status of the request. Typically, a new application will be in a status such as"Pending"
(or similar) indicating it is awaiting issuer action. The status may be updated to"Approved"
,"Issued"
,"Rejected"
, etc., depending on the workflow (for this API reference, the initial status is pending issuance).
Example Request:
Example Response:
Error Cases:
400 Bad Request
– Missing required fields or invalid data format (e.g., a mandatory attribute value is not provided or has the wrong type).404 Not Found
– The specifiedtemplateId
does not exist or is not available for issuance.401 Unauthorized
– If authentication is required, this error can occur if the holder is not properly authenticated or not allowed to apply for this credential.409 Conflict
– A duplicate request already exists (for example, the holder already applied for this credential and it’s still pending).500 Internal Server Error
– An unexpected server error occurred while recording the application (database error, etc.).
Create VC (by issuer)
Endpoint: POST /cred/vc/create
Description: Used by the issuer to create (prepare) a verifiable credential in response to a holder’s application. This call will assemble the credential data from the template and the holder’s provided information, and produce the necessary cryptographic elements for the credential. Specifically, it generates the credential’s BBS+ signature (which the issuer must produce) and a blockchain transaction blob for recording the credential status on-chain. The issuer should call this after approving or deciding to issue the credential for a given vcId
. The credential is not yet final until the Submit VC step is completed.
Request Body: (JSON)
vcId
(string): The identifier of the VC request (from the Apply VC step) that the issuer is fulfilling. This links the create operation to the holder’s application and the associated template.bbsBlsSignature
(string): The BBS+ signature over the credential data, generated by the issuer’s BBS+ keys. This signature proves the authenticity of the credential’s contents and is used for privacy-preserving presentations later. Important: The issuer must produce this signature by signing all attribute values (in the order defined by the template) using their BBS+ private key. (See BbsBls Sign Data below for how to generate this signature.) The signature should be provided as a base64 or hex string as specified by the system.Note: The issuer’s BBS+ public key is expected to be associated with the issuer’s DID (so verifiers can retrieve it during presentation verification). The system will validate the signature against the template’s attributes and issuer’s DID. If the issuer has configured the system with their seed (see BbsBls Account APIs), the signature may be generated internally, but typically the caller provides it for security.
Response Body: (JSON)
blobId
(string): The identifier for the credential issuance transaction blob. This blob represents the on-chain operation to mark the credential as issued (and possibly to register its status or revocation entry).blob
(string): The credential issuance transaction blob (hex string or base64). The issuer must sign this blob with their Zetrix account private key (Ed25519) to authorize writing the credential status to the blockchain.bbsBlsSignature
(string): The BBS+ signature in base64/hex format for the credential (same as provided in the request, or regenerated). This is included in the response for reference, confirming the signature that will be embedded in the credential. The issuer should retain this value as it forms part of the credential's proof.
Example Request:
Example Response:
Error Cases:
400 Bad Request
– The request is missing required data or has invalid format (for instance, no BBS+ signature provided, or the signature is the wrong format).404 Not Found
– ThevcId
does not correspond to a valid pending application (e.g., if it was already processed or never existed).403 Forbidden
– The issuer’s DID does not match the template’s issuer or the issuer is not authorized to issue this credential.409 Conflict
– The credential might have already been created or is in a state that cannot be created again (to avoid duplicate issuance).500 Internal Server Error
– A server error occurred while assembling the credential (e.g., issues in retrieving template or holder data, or internal cryptographic failure).
Submit VC (by issuer)
Endpoint: POST /cred/vc/submit
Description: Finalizes the issuance of the verifiable credential. The issuer calls this after signing the transaction blob obtained from Create VC. This will submit the issuance transaction to the Zetrix blockchain (recording the credential’s existence and status) and finalize the credential object. On success, the credential is officially issued and can be delivered to the holder. The response includes the complete VC in a verifiable format.
Request Body: (JSON)
blobId
(string): The identifier of the credential issuance transaction blob (returned from the create step).signature
(string): The issuer’s Ed25519 signature over the blob, authorizing the credential issuance on-chain. This should be provided in the required format (hex/base64).publicKey
(string): The Ed25519 public key corresponding to the signature, used to verify that the blob was signed by the issuer’s account. This should match the issuer’s DID on the blockchain.
Response Body: (JSON)
vcObject
(object): The issued Verifiable Credential, in its full JSON representation. This will typically include standard VC fields such as@context
,id
(which may incorporate thevcId
),type
,issuer
,credentialSubject
(containing the holder’s DID and the attributes with values), andproof
. Theproof
section will include the BBS+ signature (often encoded as a proof value) and related metadata (like the public key or verification method, and type of proof). It may also include acredentialStatus
entry indicating where the credential’s status (e.g., revocation status) is recorded (for example, referencing a blockchain registry or contract).downloadExpiryDate
(string): A timestamp indicating how long the issued credential will be available for download via the Download VC endpoint. The credential might be stored temporarily on the server; this field informs the issuer/holder of the cutoff time to fetch it. After this expiry, the credential might be purged for security, requiring the issuer to re-share if needed.
Example Request:
Example Response (partial):
Error Cases:
400 Bad Request
– The signature is missing or invalid, or the blobId is not provided.401 Unauthorized
– The signature does not match the issuer’s known public key (verification failed), or the issuer is not authorized to submit this credential.404 Not Found
– The blobId is not recognized (e.g., if the create step was not done or the blob has expired), or the corresponding VC request was not found.409 Conflict
– The credential has already been submitted/issued (duplicate submission) or was revoked by the time of submission (unlikely scenario).500 Internal Server Error
– A server or blockchain error occurred during submission (e.g., failure writing to blockchain or assembling the final VC object).
Download VC (by issuer or holder)
Endpoint: GET /cred/vc/download
Description: Retrieves a previously issued verifiable credential. This endpoint can be used by the holder (to download the credential that was issued to them) or by the issuer (to retrieve the credential, for example to send it through another channel). Typically, this would be called after the Submit VC step, using the provided vcId
. The credential must still be available (not expired from temporary storage) for this call to succeed. The response is the VC in JSON format.
Request:
This is a HTTP GET request. The vcId
of the credential to download is usually provided as a query parameter. For example:
If authentication is required, the caller must be either the issuer of the credential or the holder (subject) of the credential. The system will validate that the requesting user has rights to access the specified vcId
. (In an OAuth or token-based setup, this could be implicit; in others, the holderDid
or similar might be required.)
Response Body: (JSON)
The full Verifiable Credential object in JSON, identical to the vcObject
returned in the Submit VC step. This includes all fields of the credential (context, id, type, issuer, credentialSubject, credentialStatus if any, and proof with BBS+ signature). This allows the holder to store or view their credential, and the issuer to archive it if needed.
Example Request:
Example Response (full VC):
Error Cases:
400 Bad Request
– IfvcId
is missing or in an invalid format in the request.401 Unauthorized
– The requester is not authorized to download this credential (for example, thevcId
does not belong to the holder making the request, or no valid auth token provided).404 Not Found
– No credential found for the givenvcId
, or it’s no longer available for download (e.g., if the download window expired or the credential never existed).410 Gone
– The credential was available only temporarily and the period has lapsed (thevcId
was valid but the stored credential has been removed).500 Internal Server Error
– An unexpected error on the server while retrieving the credential.
VC Revocation APIs
These APIs allow an issuer to revoke an issued credential, invalidating it so it will no longer be considered valid by verifiers. Revocation is typically a two-step process (create a revocation transaction blob, then submit it after signing) similar to template creation and credential issuance.
Create Revoke VC Blob
Endpoint: POST /cred/vc/revoke/create
Description: Initiates the revocation of a verifiable credential. The issuer calls this to build a revocation transaction for a given credential, which returns a blob to be signed. Revoking a credential typically updates its status on-chain (for example, updating a revocation registry or marking the credential as revoked in a smart contract). This step does not yet revoke the credential; it only prepares the transaction.
Request Body: (JSON)
vcId
(string): The identifier of the credential to be revoked. This is the same ID used during issuance (and present in the credential’sid
field). The system will use this to locate the credential record or status entry on-chain.reason
(string, optional): A human-readable reason for revocation. This reason might be recorded in logs or off-chain storage for audit purposes (e.g., “Credential revoked due to expiration” or “Holder requested revocation”). It is not typically part of the on-chain transaction (which usually just flips a status), but may be stored in an off-chain database.
Response Body: (JSON)
blobId
(string): The identifier for the revocation transaction blob.blob
(string): The revocation transaction blob (hex/base64 string) that needs to be signed by the issuer’s private key. This blob encodes the action of revoking the credential identified byvcId
.
Example Request:
Example Response:
Error Cases:
400 Bad Request
– MissingvcId
, or the request is malformed.404 Not Found
– The specifiedvcId
does not correspond to an issued credential (perhaps it was never issued or already revoked).403 Forbidden
– The caller is not the issuer of that credential or not authorized to revoke it. Only the original issuer (or an authorized delegate) should revoke a credential.409 Conflict
– The credential is already revoked or a revocation is already in progress for this credential.500 Internal Server Error
– Server error while generating the revocation blob (e.g., inability to fetch credential status from chain).
Submit Revoke VC Blob
Endpoint: POST /cred/vc/revoke/submit
Description: Finalizes the credential revocation by submitting the signed revocation transaction to the blockchain. After this call succeeds, the credential identified by the given vcId
is considered revoked. Verifiers checking the credential’s status will see it as revoked (invalid). This endpoint should be called after the issuer signs the blob from the create step.
Request Body: (JSON)
blobId
(string): The identifier of the revocation transaction blob (obtained from the create step).signature
(string): The issuer’s signature over the revocation blob, using the issuer’s Ed25519 private key. This proves the issuer authorizes the revocation.publicKey
(string): The Ed25519 public key of the issuer corresponding to the signature, to verify the signature. This should match the issuer’s DID and the key that was used in issuance.
Response Body: (JSON)
vcId
(string): The identifier of the credential that was revoked (echoing the input for clarity).status
(string): The new status of the credential. Typically, this will be"Revoked"
to indicate the credential is now revoked. In some implementations, this might also include a transaction hash or confirmation of revocation. For example, the response could include a blockchain transaction ID for the revocation or a timestamp of revocation, but at minimum the status is updated.
Example Request:
Example Response:
Error Cases:
400 Bad Request
– The signature is missing or invalid, or the blobId is not provided.401 Unauthorized
– The signature does not match the issuer’s known public key (signature verification failed), or the caller is not authorized to revoke this credential.404 Not Found
– The blobId is not recognized (e.g., if the create step was not done or already submitted). It could also mean the credential was not found (if an incorrect vcId was somehow used).409 Conflict
– The credential is already revoked (the revocation transaction may have been submitted previously, possibly by another process).500 Internal Server Error
– An error occurred during submission (for example, a blockchain failure or network issue).
BbsBls Issuer Account APIs
The Zetrix VC system uses BBS+ digital signatures (BbsBls) for credentials, enabling zero-knowledge proof presentations. These endpoints help manage the issuer’s BBS+ key pair. Typically, the issuer will derive a BBS+ key from a seed (such as a wallet mnemonic or seed phrase) and use it to sign credential data. These APIs are mostly utilities for issuers: in many cases, issuers may manage keys client-side, but the API provides a way to derive and use keys if needed.
Create Account from Seed
Endpoint: POST /cred/vc/bbsbls/account/create
Description: Derives a BBS+ issuer account (key pair) from a given seed. This is usually used to get the BBS+ public key corresponding to a seed phrase or seed value that the issuer controls. The BBS+ public key is needed to include in DIDs or to share with verifiers so they can verify credentials. The seed is used to deterministically generate the BBS+ private/public key pair. (This does not create an account on the blockchain; it’s purely cryptographic key derivation.)
Request Body: (JSON)
seed
(string): A seed used to generate the BBS+ keys. This can be a mnemonic phrase or a hex string/base64 string representing the seed bytes. The exact format depends on implementation: for example, it could be a 32-byte hex string derived from a 12-word mnemonic. The seed provided should be kept secure, as it determines the private key. (If a mnemonic phrase is used, it should be a single string with words separated by spaces.)
Response Body: (JSON)
publicKey
(string): The derived BBS+ public key in a portable format (e.g., base64 or hex). This is the public key that corresponds to the issuer’s BBS+ private key. The issuer’s DID document should include this public key (or a reference to it) so that verifiers can use it to verify credential signatures. Note: The BBS+ private key is not returned by the API for security reasons. The caller is expected to secure the seed or derive the private key on their side if needed. The same seed will always generate the same key pair, so storing the seed is sufficient to reproduce the keys.
Example Request:
Example Response:
(The publicKey string is truncated for brevity. It would be a long base64 string.)
Error Cases:
400 Bad Request
– The seed is missing or not in a valid format (e.g., wrong number of words in mnemonic, or invalid hex string).401 Unauthorized
– If the API requires authentication (to prevent unauthorized key derivation) and the call is not authenticated.500 Internal Server Error
– The server encountered an error during key generation (for example, if the seed phrase couldn’t be parsed or an internal library error occurred).
Sign Data
Endpoint: POST /cred/vc/bbsbls/sign
Description: Signs an array of data messages using the issuer’s BBS+ secret key. This is used to produce the BBS+ signature that will go into a Verifiable Credential. The messages to sign should correspond to the credential’s attributes (and possibly other fixed fields like a context or nonce, depending on implementation). The output is a BBS+ signature that can later be verified with the issuer’s BBS+ public key. Typically, the issuer will use the same seed as in Create Account to derive the secret key and sign the credential attributes.
Request Body: (JSON)
seed
(string): The seed or secret key material for signing. This should be the same seed used to derive the BBS+ keys (as provided in the create account step). The service will derive the BBS+ private key from this seed internally and use it to sign. (In some cases, the API might accept a rawprivateKey
instead, but generally providing the seed is expected so that it can deterministically derive the key. Ensure this is sent over a secure connection as it is sensitive.)messages
(array of strings): The list of messages (attribute values) to sign. The order of this array is critical – it must match the order of attributes defined in the template’scredentialFormat
. Each entry in this array is a string representation of the corresponding attribute’s value. For example, if the template’s first attribute is fullName = "Alice Chen", second is licenseNumber = "MYDL-987654321", etc., thenmessages
should be["Alice Chen", "MYDL-987654321", "2030-12-31"]
for those values. Note: If any special encoding is required (for example, dates or numbers might need a specific format or zero-padding), the values should be formatted accordingly before signing.
Response Body: (JSON)
signature
(string): The BBS+ signature over the provided messages, encoded as a base64 string (or hex string depending on the system conventions). This signature will be used as thebbsBlsSignature
in the Create VC call. It incorporates all messages in a single compact signature that allows selective disclosure proofs later. The length of this string is typically fixed (for example, 112 bytes in base64 for BBS+ sig).
Example Request:
Example Response:
Error Cases:
400 Bad Request
– Missing seed or messages, or the messages array is empty. Also if a message is in an invalid format (e.g., not a string).401 Unauthorized
– If the API requires auth and the call is not authorized to perform signing (to protect misuse of signing).500 Internal Server Error
– If signing fails due to internal errors (for example, if the seed is incorrect or the cryptographic operation encountered an issue).
Verifiable Presentation APIs
Verifiable Presentations (VPs) allow a credential holder to prove certain information from their credentials to a verifier. In Zetrix’s VC system (using BBS+), a holder can generate a proof that selectively discloses some attributes of their credential (and optionally proves statements about others, like ranges) without revealing the entire credential. The VP APIs help create and verify these presentations. Typically, the holder will use Create VP and Submit VP to produce a presentation, and a verifier will use Verify VP to check its validity.
Create VP Blob
Endpoint: POST /cred/vc/vp/create
Description: Creates a verifiable presentation object (unsigned) from a given credential and disclosure requirements. The holder calls this to prepare a presentation by specifying which credential to present and which attributes to reveal or prove. The endpoint returns a presentation blob that the holder must then sign (to prove possession) or finalize. This step performs the heavy cryptographic computation of generating a selective disclosure proof using the BBS+ signature from the credential.
Request Body: (JSON)
vcObject
(object): The verifiable credential to be presented, provided in JSON format. This should be the full credential that was issued (as obtained from the download or issuance step), including its proof (BBS+ signature). The service will extract the credential’s data and proof from this object. (Alternatively, some implementations might accept avcId
and fetch the credential if it’s stored, but in this context, providing the credential object ensures the holder has it and controls it.)revealedAttributes
(array of strings): A list of attribute keys that the holder wants to reveal in the presentation. Only these attributes from the credential will be visible to the verifier; all other signed attributes will remain hidden but cryptographically proven. For example,["fullName", "expiryDate"]
would reveal the holder’s full name and the expiry date, but not reveal other fields like license number. If this array is empty, it means no attribute values are revealed (which typically is not useful unless combined with a proof like a range).rangeProofs
(array of objects, optional): A list of zero-knowledge range proofs the holder wants to include for certain numeric attributes, instead of revealing their exact values. Each object can specify that an attribute’s value lies within a certain range without disclosing the actual value. If provided, each object should contain:attribute
(string): The key of the numeric attribute for which to prove a range (e.g.,"age"
if the credential had an age field). This attribute’s value will not be revealed directly.domain
(string): A domain separator or identifier for the proof. (This can be a fixed string to avoid proof reuse across contexts or to bind the proof to a specific purpose. It may also identify the unit or context of the attribute; e.g.,"years"
for age.)min
(number): The inclusive lower bound of the range that the attribute’s value is claimed to be in.max
(number): The inclusive upper bound of the range for the attribute’s value.nonce
(integer): A random nonce or salt for the range proof. This ensures the proof is unique and cannot be reused. If not supplied, the system may generate a random nonce internally. The verifier must know this nonce (usually it will be included in the VP proof) to validate the range proof.
Example: To prove a birth year is between 1990 and 2000 without revealing it, use
attribute: "birthYear", min: 1990, max: 2000
. The presentation will show that the birthYear lies in [1990,2000] but not the exact year. Range proofs require the credential to have that attribute signed originally.challenge
(string, optional): A challenge nonce provided by the verifier (or generated by the holder) to include in the presentation proof. This helps prevent replay attacks by tying the VP to a specific verifier’s request. If provided, it will be incorporated into the proof signature. If not provided, the system might generate one or the VP might be considered bearer. Typically, for strongest security, a verifier will give a random challenge that the holder must include and later the verifier will check for it.
Response Body: (JSON)
blobId
(string): An identifier for the presentation blob that was created.blob
(string): The unsigned Verifiable Presentation data in a serialized form (likely JSON, possibly encoded as needed). This blob includes the disclosed information (attributes listed inrevealedAttributes
) and the cryptographic proof data for hidden attributes (including any range proofs). However, it may not yet contain a proof of holder possession (i.e., a signature from the holder’s DID). The holder needs to sign this blob (or a subset of it) with their own key to prove that they are the legitimate holder of the credential. After signing, the holder will use Submit VP Signed Data to complete the VP.The
blob
essentially contains a Verifiable Presentation object with everything except the holder's signature. It will reference the credential (or include a derived proof of it) and list revealed fields. The holder’s signing step will typically add aproof
section indicating the holder’s verification method and signature.
Example Request:
(In the above example, the holder will reveal fullName
and expiryDate
openly. They will not reveal licenseNumber
but instead prove that it lies between 900000000 and 999999999, perhaps to show the license number is within a certain format or range. The challenge
is a random UUID from the verifier.)
Example Response:
(For readability, the blob content is shown as a snippet. In practice, blob
will be a JSON string or structure containing the Verifiable Presentation with the proof of the credential. The proof inside the blob at this stage is likely a BbsBlsSignatureProof2020 (or similar) that contains the derived proof from the BBS+ signature, which shows consistency of hidden attributes and correctness of revealed ones. The holder’s own signature is not yet included.)
Error Cases:
400 Bad Request
– Missing or invalid input (e.g., novcObject
provided, or the credential object is malformed; requesting to reveal an attribute that isn’t in the credential; rangeProof parameters invalid such as min > max).401 Unauthorized
– If the holder is not authorized to create a VP for the given credential (e.g., the credential’s holder DID does not match the authenticated user). Typically, the holder should only present their own credential.404 Not Found
– If avcId
was expected instead ofvcObject
and not found (not applicable in our assumed interface wherevcObject
is given).500 Internal Server Error
– The server encountered an error during proof generation (could be due to cryptographic library issues or memory constraints if the credential is large). This could also happen if the credential’s proof is not valid (e.g., if the BBS+ signature invcObject
failed verification against issuer’s public key, meaning the credential is suspect).
Submit VP Signed Data
Endpoint: POST /cred/vc/vp/submit
Description: Completes the verifiable presentation by incorporating the holder’s signature (or proof of holder) into the presentation blob. The holder calls this after Create VP Blob, providing their signature over the blob (usually covering the digest of the presentation and the verifier’s challenge). This produces the final Verifiable Presentation that can be given to a verifier. Essentially, this step adds a layer of proof that the presentation is furnished by the holder in possession of the credential, preventing anyone else from reusing the presentation.
Request Body: (JSON)
blobId
(string): The identifier of the presentation blob from the create step.signature
(string): The holder’s signature on the presentation data (blob). This is typically an Ed25519 signature using the holder’s DID private key, or another signature corresponding to the holder’s verification method. It proves that the holder (who controls the DID in the credentialSubject) is the one presenting the credential. The signature usually covers the challenge and the derived proof, binding them.publicKey
(string): The public key associated with the holder’s DID that corresponds to the signature. This helps the server verify the signature. It should match a verification method in the holder’s DID Document (for example, the base58 or hex public key of the holder’s DID). If the DID and keys are registered in a DID resolver accessible to the system, this might be used as a cross-check or may be optional if the server can resolve the DID.
Response Body: (JSON)
vpObject
(object): The completed Verifiable Presentation. This is a JSON object containing the Verifiable Presentation data, now including the holder’s proof. It will have a structure like:@context
: including both credentials and security contexts.type
: typically["VerifiablePresentation"]
(and any specific sub-types if defined).verifiableCredential
: containing the proof of the credential (not the full original credential, but the derived proof or reference created in the blob step) along with any revealed attributes.proof
: an array or object that now includes the holder’s proof. For example, one proof might be theBbsBlsSignatureProof2020
from the credential (already in place), and another might be aEd25519Signature2018
or similar from the holder. The holder’s proof will include theverificationMethod
(the holder’s DID key id), thechallenge
(nonce) if any, a timestamp, and the actual signature (proofValue
orjws
depending on the format).
This vpObject
is what the holder will deliver to the verifier (e.g., via QR code or API). It is a complete Verifiable Presentation that can be independently verified.
Example Request:
(In this example, signature
might be an Ed25519 signature in JWS format or raw base64. The publicKey
is a placeholder for the holder’s public key. In practice, the holder’s DID and key could be resolved by the server, but it’s provided here for verification.)
Example Response (partial VP):
(In the vpObject
above, the verifiableCredential
array contains a credential object with only the revealed attributes and a proof that those attributes are valid (BBS+ proof). The final proof
at the presentation level is the holder’s signature, which includes the challenge from the verifier. The combination of these proves that the issuer originally issued a credential to the holder and that the holder is now presenting it with certain info revealed.)
Error Cases:
400 Bad Request
– Missing blobId or signature, or signature format is invalid. This can also occur if the holder’s publicKey is not provided when required or does not match the expected format.401 Unauthorized
– The signature provided does not match the holder’s DID or public key (verification of the holder’s signature failed). The holder might not be the legitimate owner of the credential if this fails.404 Not Found
– The blobId is not found or has expired (perhaps the create step was not done or was done too long ago).500 Internal Server Error
– The server encountered an error combining the proof or verifying the holder’s signature. This could also cover cases where the underlying credential proof is invalid (although that would ideally be caught earlier), or other internal issues.
Verify VP
Endpoint: POST /cred/vc/vp/verify
Description: Verifies a verifiable presentation. A verifier (or any relying party) uses this endpoint to check the authenticity and validity of a presented credential. This involves verifying the holder’s signature, the credential’s BBS+ proof, and checking the credential’s status (whether it’s revoked or expired) and that any disclosed data satisfies requirements (including range proofs). The endpoint returns whether the presentation is valid and may include the disclosed data.
Request Body: (JSON)
vpObject
(object): The Verifiable Presentation to verify, provided as a JSON object. This should be the full presentation as obtained from the holder (for example, exactly what was returned by the Submit VP step or what the holder’s wallet produced). It contains both the credential proof and the holder’s proof. The service will use this object to perform all necessary verifications. (Note: In some contexts, the VP might be passed as a base64 string or a JWT. Here we assume JSON for simplicity, which aligns with the earlier endpoints.)
Response Body: (JSON)
verified
(boolean):true
if the presentation and the credential within it are cryptographically valid and not revoked/expired;false
if any verification step fails.verifiedAttributes
(object): Ifverified
is true, this object contains the attributes from the credential that were revealed and verified. It will map attribute keys to their values as presented. For example:"fullName": "Alice Chen", "expiryDate": "2030-12-31"
. These are the pieces of information the verifier is allowed to see and trust. Attributes that were not revealed will not appear here. For range proofs, the verifier might not get the exact value but knows the range condition was satisfied; the response might include a note like"licenseNumber": "Verified in range 900000000-999999999"
or similar to indicate a successful range check (the exact format may vary, but including the fact of verification is useful).status
(string): Additional status information about the verification. For example,"valid"
if everything is good. Ifverified
is false, this might contain a brief reason such as"revoked"
(if the credential was found revoked) or"signatureMismatch"
(if a signature failed). This field is optional but can help in debugging or audit.errors
(array of strings, optional): If verification failed (verified = false
), this may list the reasons for failure. Possible errors could be"Invalid holder signature"
,"Credential revoked on 2025-01-01"
,"Expired credential"
,"BBS+ proof invalid or not matching issuer key"
, etc. Each error string describes one issue found.
Example Request:
Example Response (verified case):
(In this example, the licenseNumber wasn’t revealed, but the verifier knows it was in the specified range, hence a checkmark or note is given instead of a value.)
Example Response (failure case):
(This example shows a scenario where verification failed. It indicates the credential had been revoked and additionally the holder’s signature didn’t match, either of which would invalidate the VP.)
Error Cases:
400 Bad Request
– The providedvpObject
is missing or not a valid presentation format. For instance, if required fields are missing or the JSON is malformed.500 Internal Server Error
– An unexpected error occurred during verification. This could be due to an inability to reach the DID resolver (to fetch issuer or holder public keys), or a failure in cryptographic verification that didn’t properly set an error message. If this occurs,verified
might be false by default.
During verification, the following checks are performed internally (each must pass for verified
to be true):
Signature Checks: The holder’s signature on the presentation is verified using the holder’s public key (retrieved via
publicKey
provided or via the holder’s DID document). The BBS+ proof inside the VP is verified using the issuer’s BBS+ public key (retrieved from the issuer’s DID document, presumably via the DID Resolver).Data Integrity: It ensures that the revealed attributes in the VP match the values that were originally signed in the credential (the BBS+ proof ties them). Any tampering would break the proof verification.
Non-Disclosure: It confirms that no more information than requested is revealed (i.e., hidden attributes remain hidden except for what the proof inherently reveals, like perhaps the bounds in a range proof).
Status Check: The credential’s status (often indicated by
credentialStatus.id
in the VC) is checked on-chain (or in the relevant registry) to ensure the credential is not revoked or expired. If the VC has an expiry date, that is also checked to ensure it’s still valid at verification time.Challenge Check: If a
challenge
(nonce) was included in the VP, verify that it matches what was expected (this prevents replays – usually the verifier provides the challenge and knows what to expect).
If all checks pass, the presentation is valid and the disclosed information can be trusted by the verifier. Otherwise, the presentation should be rejected.
Last updated