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.
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>'
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
}
},
}
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:
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.
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.
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
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.
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}}",
}
-
Encode the URL as a QR code.
-
Scan the QR code with your wallet and accept issuance.
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.