Issue a Verifiable Credential

Issue a JSON-LD Verifiable Credential, signed by a did:cheqd Decentralized Identifier (DID), using the ACA-Py API endpoints.

Using the /issue-credential-2.0 API endpoints, it is possible to issue Verifiable Credentials, signed by a cheqd DID, in a few clicks or lines of code. By following the following steps, you can effectively issue verifiable credentials using ACA-Py integrated with the cheqd ecosystem.

Pre-requisite

For JSON-LD Credential Issuance, the Issuer DID must have assertionMethod set to the verificationMethod.id . If your DID does not have assertionMethod, execute POST /did/cheqd/update API call to add new assertion method matching the verificationMethod.id.

Step 1: Create a Connection with Holder

Use any supported method to create a connection with the Holder of the credential. Automated out-of-band protocol is recommended.

1a: Issuer Creates Connection Invite

The Issuer agent will create a new connection invite for the Holder. This is needed to securely communicate between the Issuer and the Holder agents.

Create a new connection invitation

post
Query parameters
auto_acceptanyOptional

Auto-accept connection (defaults to configuration)

create_unique_didanyOptional

Create unique DID for this invitation (default false)

multi_useanyOptional

Create invitation for multiple use (default false)

Body
acceptstring[]Optional

List of mime type in order of preference that should be use in responding to the message

Example: ["didcomm/aip1","didcomm/aip2;env=rfc19"]
aliasstringOptional

Alias for connection

Example: Barry
goalstringOptional

A self-attested string that the receiver may want to display to the user about the context-specific goal of the out-of-band message

Example: To issue a Faber College Graduate credential
goal_codestringOptional

A self-attested code the receiver may want to display to the user or use in automatically deciding what to do with the out-of-band message

Example: issue-vc
handshake_protocolsstring[]Optional

Handshake protocol to specify in invitation

mediation_idstringOptional

Identifier for active mediation record to be used

Example: 3fa85f64-5717-4562-b3fc-2c963f66afa6Pattern: [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
metadataobjectOptional

Optional metadata to attach to the connection created with the invitation

my_labelstringOptional

Label for connection invitation

Example: Invitation to Barry
protocol_versionstringOptional

OOB protocol version

Example: 1.1
use_didstringOptional

DID to use in invitation

Example: did:example:123
use_did_methodstring · enumOptional

DID method to use in invitation

Example: did:peer:2Possible values:
use_public_didbooleanOptional

Whether to use public DID in invitation

Responses
200Success
application/json
post
/out-of-band/create-invitation
200Success

Parameters and Request Body

For automated acceptance, pass the following parameters:

auto_accept

Set this to true

A simple request body is below:

1b: Holder receives invitation

The above request will have an invitation in the response. Holder will have to copy that invitation and pass in the body of the following API call.

Receive a new connection invitation

post
Query parameters
aliasanyOptional

Alias for connection

Example: {"value":"Barry"}
auto_acceptanyOptional

Auto-accept connection (defaults to configuration)

mediation_idanyOptional

Identifier for active mediation record to be used

Example: {"value":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}
use_existing_connectionanyOptional

Use an existing connection, if possible

Body
@idstringOptional

Message identifier

Example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
@typestringOptional

Message type

Example: https://didcomm.org/my-family/1.0/my-message-type
acceptstring[]Optional

List of mime type in order of preference

Example: ["didcomm/aip1","didcomm/aip2;env=rfc19"]
goalstringOptional

A self-attested string that the receiver may want to display to the user about the context-specific goal of the out-of-band message

Example: To issue a Faber College Graduate credential
goal_codestringOptional

A self-attested code the receiver may want to display to the user or use in automatically deciding what to do with the out-of-band message

Example: issue-vc
handshake_protocolsstring[]Optional

Handshake protocol

imageUrlstring · urlOptional

Optional image URL for out-of-band invitation

Example: http://192.168.56.101/img/logo.jpg
labelstringOptional

Optional label

Example: Bob
Responses
200Success
application/json
post
/out-of-band/receive-invitation
200Success

Parameters and Request Body

auto_accept

Set this to true

alias

Pass an alias for the connection

use_existing_connection

Set this to true

The request body should be the invitation value from the /create-invitation call by the Issuer.

Step 2: Holder creates local DID

For JSON-LD Credentials, the verification needs a Holder did as well. The Holder DID can be created locally by using the following API Call.

Create a local DID

post
Body
methodstringOptional

Method for the requested DID.Supported methods are 'key', 'sov', and any other registered method.

Example: sov
seedstringOptional

Optional seed to use for DID, Must be enabled in configuration before use.

Example: 000000000000000000000000Trustee1
Responses
200Success
application/json
post
/wallet/did/create
200Success

Request Body

You can use the following request body to create the local did. Ensure the key_type matches the Issuer DID Key Type.

Step 3: Request Credential from Issuer

For this example, the Credential is requested from the Holder to the Issuer using the /issue-credential-2.0/send-request API. This request is sent to the Issuer, informing them about the credential request and its attributes in a JSON format.

Send issuer a credential request not bound to an existing thread. Indy credentials cannot start at a request

post
Body
auto_removebooleanOptional

Whether to remove the credential exchange record on completion (overrides --preserve-exchange-records configuration setting)

commentstringOptional

Human-readable comment

connection_idstringRequired

Connection identifier

Example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
holder_didstringOptional

Holder DID to substitute for the credentialSubject.id

Example: did:key:ahsdkjahsdkjhaskjdhakjshdkajhsdkjahs
tracebooleanOptional

Whether to trace event (default false)

Responses
200Success
application/json
post
/issue-credential-2.0/send-request
200Success

Request Body

The following request is a sample for creating a Citizenship credential.

Step 4: Issuer accepts and issues credential

After the Issuer received and validated the request, they can issue the credential using the /issue-credential-2.0/records/<credential-exchange-id>/issue API endpoint. The credential-exchange-id can be retrieved by calling GET /issue-credential-2.0/records?state=request-received API.

Send holder a credential

post
Path parameters
cred_ex_idanyRequired

Credential exchange identifier

Example: {"value":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}
Body
commentstringOptional

Human-readable comment

Responses
200Success
application/json
post
/issue-credential-2.0/records/{cred_ex_id}/issue
200Success

Step 5: Holder stores Credential

The Holder has to store the issued credential into their wallet using the following API. The cred_ex_id can be retrieved by running API GET /issue-credential-2.0/records?state=credential-received on the Holder side.

Store a received credential

post
Path parameters
cred_ex_idanyRequired

Credential exchange identifier

Example: {"value":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}
Body
credential_idstringOptional
Responses
200Success
application/json
post
/issue-credential-2.0/records/{cred_ex_id}/store
200Success

Step 6: Check the received Credential

As this is a JSON-LD Credential, Holder must use POST /credentials/w3c API to check the credential.

Fetch W3C credentials from wallet

post
Query parameters
countanyOptional

Maximum number to retrieve

Example: {"value":"1"}
startanyOptional

Start index

Example: {"value":"0"}
wqlanyOptional

(JSON) WQL query

Example: {"value":"{\"attr::name::value\": \"Alex\"}"}
Body
contextsstring[]Optional

Credential context to match

given_idstringOptional

Given credential id to match

issuer_idstringOptional

Credential issuer identifier to match

max_resultsintegerOptional

Maximum number of results to return

proof_typesstring[]Optional

Signature suite used for proof

schema_idsstring[]Optional

Schema identifiers, all of which to match

subject_idsstring[]Optional

Subject identifiers, all of which to match

typesstring[]Optional

Credential type to match

Responses
200Success
application/json
post
/credentials/w3c
200Success

Request Body

For our citizenship credential example, the following request can be used

Last updated

Was this helpful?