This quickstart will demonstrate the process of defining, issuing, verifying, and revoking a credential.

1. Create a Developer Account

To get started, create an developer account in the staging Crossmint Console. Open that link, sign in, and accept the dialog to continue.

Crossmint offers two consoles: staging, for development and testing, and prod, for production. This quickstart uses staging, and contains instructions at the end for switching to production.

2. Get an API key

Once you log in to the console, the next step is to create an API key: a secret credential required to call the API.

Go to the API Keys tab, click on New API Key, and select the scopes collections.create, wallets:nfts.read, nfts.read, and nfts.create. Once you’re done, copy your API KEY. You will need it in the next step.

These keys are server-side only and should not be exposed in the frontend of a web application.

3. Define the Schema

For this sample credential need to define a custom schema as defined below. When using a custom defined schema you must call the create-type API first.

const schema = {
  credentialSubjectSchema: [
    { name: "course", type: "string" },
    { name: "passed", type: "bool" },
  ],
};
const options = {
  method: "POST",
  headers: {
    "X-API-KEY": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify(schema),
};

fetch("https://staging.crossmint.com/api/unstable/credentials/types", options)
  .then((response) => response.json())
  .then((response) => console.log(response))
  .catch((err) => console.error(err));

Copy the createType.js file in the tab above, add your API key generated in previous step to the X-API-KEY header and run via node.

node createType.js

You can also use a tool like Postman or even our API playground for these API calls.

You’ll get back a response that includes an id value. This represents your custom type that will be used when you create your collection in the next step.

4. Create a VC Collection

Verfiable Credentials are associated with an NFT. Before issuing a VC, the related NFT must be minted. The next step will create the special type of collection used to mint NFTs and their associated credentials. A default type is available that will not contain any field.

Copy the createVCCollection.js file in the tab below, fill in your API key, and run in your terminal to create the collection.

const collectionParams = {
  chain: "polygon",
  credentials: { type: "ID_FROM_PREVIOUS_STEP" },
  metadata: { name: "VC Collection Name QS", description: "Test" },
};

const options = {
  method: "POST",
  headers: {
    "X-API-KEY": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify(collectionParams),
};

fetch("https://staging.crossmint.com/api/unstable/collections/", options)
  .then((response) => response.json())
  .then((response) => console.log(response))
  .catch((err) => console.error(err));
node createVCCollection.js

5. Issue a Credential

To issue a credential copy the issueCredential.js file below, add your API key, and collectionID (that was returned in previous step). Then run the file from your terminal.

const credentialParams = {
  recipient: "email:user@email.com:polygon",
  credential: {
    subject: { course: "Blockchain 101", passed: true },
    expiresAt: "2034-02-02",
  },
  metadata: {
    name: "Blockchain 101 Course Credential",
    image: "ipfs://QmUGeWerAfyKVVdAjaxYdAhK74oJmBvusPdKtNDN3e1bYN",
    description: "Credentials for people who passed the Blockchain 101 course",
  },
};

const options = {
  method: "POST",
  headers: {
    "X-API-KEY": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify(credentialParams),
};

const collectionId = "YOUR_COLLECTION_ID";

fetch(
  `https://staging.crossmint.com/api/unstable/collections/${collectionId}/credentials`,
  options
)
  .then((response) => response.json())
  .then((response) => console.log(response))
  .catch((err) => console.error(err));
node issueCredential.js

Congrats 🎉 you have issued your first credential.

If you do not include an expiration date you must revoke the credential via burning to invalidate it

The credential subject must respect the schema of the chosen type. For example, you cannot add additional fields to the credential.subject not exclude any that were previously set.

You can set up a webhook to know when the VC NFT minting is completed, or call the action status API with the returned actionId.

6. Retrieve a Verifiable Credential

You can retrieve a credential using different identifiers associated with credential itself or the associated NFT.

IMPORTANT: There is not access control on credential retrieval, credential data is public and can be retrieved by anyone, use encrypted credentials if you need to protect the data.

Here is an example of retrieving a credential using the credentialRetrievalId:

const retrievalID = "credentialRetrievalId_from_previous_step";
const options = {
  method: "GET",
  headers: {
    "X-API-KEY": "YOUR_API_KEY",
  },
};

fetch(
  `https://staging.crossmint.com/api/unstable/credentials/${retrievalID}`,
  options
)
  .then((response) => response.json())
  .then((response) => console.log(JSON.stringify(response)))
  .catch((err) => console.error(err));
node retrieveCredential.js

7. Verify a Credential

Verifying a credential can be done in different ways, the easiest one is to call the verify-credential API. You can also accomplish this with the SDK.

const options = {
  method: "POST",
  headers: {
    "X-API-KEY": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: `{"credential": ${JSON.stringify(credential)}}`,
};

fetch("https://staging.crossmint.com/api/unstable/credentials/verify", options)
  .then((response) => response.json())
  .then((response) => console.log(response))
  .catch((err) => console.error(err));
node verifyCredential.js

8. Revoke a Credential

To revoke a credential, you simply burn the associated NFT. You can use the burn-nft API to accomplish this.

revokeCredential.js
const collectionId = "YOUR_VC_COLLECTION_ID";
const nftId = "YOUR_NFT_UUID";
const options = { method: "DELETE", headers: { "X-API-KEY": "YOUR_API_KEY" } };

fetch(
  `https://staging.crossmint.com/api/2022-06-09/collections/${collectionId}/nfts/${nftId}`,
  options
)
  .then((response) => response.json())
  .then((response) => console.log(response))
  .catch((err) => console.error(err));
node revokeCredential.js