Skip to main content

Issue your first credential

Get started with the Procivis One Core by issuing your first credential.

This guide walks you through a simple issuance workflow using a selection of available technologies and protocols. You can use the provided curl requests directly (with minor modifications), or you can start the development server and import the API schema into your preferred API client for a more interactive experience.

Prerequisites

  • You've cloned or forked the one-core and setup your development environment following the instructions in the repository.

  • You've downloaded the Procivis One Wallet free from an app store.

    Download links

1

Check the configuration

The configuration determines how major components of the solution work, and many API calls you make must reference specific configuration instances.

Retrieve the configuration through the API to see what's available to use:

curl -L '/api/config/v1' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>'
note

If you're using the development server of the one-core, the bearer token is test.

Here's a sample response from the default configuration of the one-core, edited to highlight only the instances used in this guide. Configuration details such as parameters have been removed:

{
"format": { // Contains all configured credential formats
"SD_JWT": { // Configuration instance; you will reference this later
"type": "SD_JWT" // W3C VC with enveloping SD-JWT proof
}
},
"exchange": { // Contains all configured exchange protocols
"OPENID4VC": { // Configuration instance; you will reference this later
"type": "OPENID4VC" // OpenID4VC exchange protocol
}
},
"transport": { // Contains all configured transport protocols
"HTTP": { // Configuration instance; you will reference this later
"type": "HTTP" // HTTP transport protocol
}
},
"revocation": { // Contains all configured revocation method
"BITSTRINGSTATUSLIST": { // Configuration instance; you will reference this later
"type": "BITSTRINGSTATUSLIST" // Bitstring Status List
},
},
"did": { // Contains all configured DID methods
"WEB": { // Configuration instance; you will reference this later
"type": "WEB" // did:web method
}
},
"datatype": { // Contains all configured datatypes for data validation
"BIRTH_DATE": { // Configuration instance; you will reference this later
"type": "DATE" // ISO 8601 formatted date-time strings
},
"EMAIL": { // Configuration instance; you will reference this later
"type": "STRING" // Text values subject to params
},
"STRING": { // Configuration instance; you will reference this later
"type": "STRING" // Text values subject to params
}
},
"keyAlgorithm": { // Contains all configured key algorithms
"EDDSA": { // Configuration instance; you will reference this later
"type": "EDDSA" // EdDSA
}
},
"keyStorage": { // Contains all configured key storage types
"INTERNAL": { // Configuration instance; you will reference this later
"type": "INTERNAL" // Encrypted internal database
}
},
}
note

If you're working with a different iteration of the one-core your configuration may differ. Check your configuration instances to know what's available.

You will use all of the noted configuration instances to issue your first credential.

2

Create an organization

Everything created in Procivis One is owned by an organization, so get started by creating your first organization:

caution

The system uses the UK spelling of organisation with an 's'. All other system terms and docs use American English spellings.

curl -L -X POST '/api/organisation/v1' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d ''

The system responds with the UUID of your new organization:

{
"id": "{{YOUR-ORG-UUID}}"
}

Store this value for later use.

3

Create a key pair

You'll need a key pair for DID creation and signatures. Make the following curl request, making sure to use your stored organization UUID:

curl -L -X POST '/api/key/v1' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"keyType": "EDDSA",
"name": "My first key pair",
"organisationId": "{{YOUR-ORG-UUID}}",
"storageType": "INTERNAL"
}'

The system responds with the UUID of your new key pair:

{
"id": "{{YOUR-KEY-UUID}}"
}

Store this value for later use.

4

Create a DID

You'll need a Decentralized Identifier (DID) to identify yourself in interactions. Make the following curl request, making sure to use your stored organization and key UUIDs:

curl -L -X POST '/api/did/v1' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"keys": {
"assertionMethod": [
"{{YOUR-KEY-UUID}}"
],
"authentication": [
"{{YOUR-KEY-UUID}}"
],
"capabilityDelegation": [
"{{YOUR-KEY-UUID}}"
],
"capabilityInvocation": [
"{{YOUR-KEY-UUID}}"
],
"keyAgreement": [
"{{YOUR-KEY-UUID}}"
]
},
"method": "WEB",
"name": "My first DID",
"organisationId": "{{YOUR-ORG-UUID}}"
}'

The system responds with the UUID of your new DID:

{
"id": "{{YOUR-DID-UUID}}"
}

Store this value for later use.

5

Create a credential schema

Next, you'll need to define what kind of credential you want to issue. You do this by creating a credential schema - a reusable template that lets you define the kind of claims you want to make and the credential format you want to produce.

  1. Make the following curl request, making sure to use your stored organization UUID:

curl -L -X POST '/api/credential-schema/v1' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"claims": [
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "Name",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "BIRTH_DATE",
"key": "Birthdate",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "EMAIL",
"key": "Email",
"required": true
}
],
"format": "SD_JWT", // Value from the configuration
"allowSuspension": true,
"name": "My first credential schema",
"organisationId": "{{YOUR-ORG-UUID}}",
"revocationMethod": "BITSTRINGSTATUSLIST" // Value from the configuration
}'

The system responds with the UUID of your new credential schema:

{
"id": "{{YOUR-CREDENTIAL-SCHEMA-UUID}}"
}

Store this value for later use.

  1. When you created your credential schema, the system gave each claim a UUID. You'll need to retrieve and store these UUIDs so you can reference them when assigning claim values during issuance. Make the following request:

curl -L '/api/credential-schema/v1/{{YOUR-CREDENTIAL-SCHEMA-UUID}}' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>'

Here's the (edited) response:

{
"name": "My first credential schema",
"format": "SD_JWT",
"revocationMethod": "BITSTRINGSTATUSLIST",
"allowSuspension": true,
"claims": [
{
"key": "Name",
"required": true,
"datatype": "STRING",
"claims": [],
"createdDate": "2025-03-10T11:41:50.660Z",
"lastModified": "2025-03-10T11:41:50.660Z",
"id": "{{NAME-CLAIM-UUID}}", // Store this value
"array": false
},
{
"key": "Birthdate",
"required": true,
"datatype": "BIRTH_DATE",
"claims": [],
"createdDate": "2025-03-10T11:41:50.660Z",
"lastModified": "2025-03-10T11:41:50.660Z",
"id": "{{BIRTHDATE-CLAIM-UUID}}", // Store this value
"array": false
},
{
"key": "Email",
"required": true,
"datatype": "EMAIL",
"claims": [],
"createdDate": "2025-03-10T11:41:50.660Z",
"lastModified": "2025-03-10T11:41:50.660Z",
"id": "{{EMAIL-CLAIM-UUID}}", // Store this value
"array": false
}
],
"createdDate": "2025-03-10T11:41:50.660Z",
}

Store the claim UUIDs for later use.

6

Issue a credential

  1. You'll need to create a credential, making claims about a subject. Make the following curl request, making sure to use your stored UUIDs:

curl -L -X POST '/api/credential/v1' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>' \
-d '{
"claimValues": [
{
"claimId": "{{NAME-CLAIM-UUID}}",
"path": "Name",
"value": "Alice Smith"
},
{
"claimId": "{{BIRTHDATE-CLAIM-UUID}}",
"path": "Birthdate",
"value": "1999-12-31T23:00:00.000Z"
},
{
"claimId": "{{EMAIL-CLAIM-UUID}}",
"path": "Email",
"value": "alice.smith@example.com"
}
],
"credentialSchemaId": "{{YOUR-CREDENTIAL-SCHEMA-UUID}}",
"exchange": "OPENID4VC",
"issuerDid": "{{YOUR-DID-UUID}}"
}'

The system responds with the UUID of your new credential:

{
"id": "{{YOUR-CREDENTIAL-UUID}}"
}

Store this value for later use.

  1. With your credential created, you can now issue it. The share endpoint creates a URL that can be encoded as a QR code for the wallet to connect to. Make the following curl request:

curl -L -X POST '/api/credential/v1/{{YOUR-CREDENTIAL-UUID}}/share' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <TOKEN>'

The system responds with the issuance URL:

{
"url": "{{YOUR-ISSUANCE-URL}}",
}
  1. Encode the URL as a QR code.

  2. Scan the QR code with your wallet and accept issuance.

tip

If you want to continue to the next guide, keep all the values you stored (such as your organization, DID, and other UUIDs) handy as you will use them during verification.

Next guide: Verify your first credential.


Apple and the Apple logo are trademarks of Apple, Inc., registered in the U.S. and other countries. App Store is a service mark of Apple, Inc, registered in the U.S. and other countries.

Google Play and the Google Play logo are trademarks of Google LLC.