> ## Documentation Index
> Fetch the complete documentation index at: https://crossmint-wallets-docs-2-5.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart ⚡

> Issue and verify a verifiable credential in under 5 minutes

This quickstart will demonstrate the process of defining, issuing, verifying, and revoking a credential. For this
exercise, we will issue a credential from Satoshi University for students who complete the Blockchain 101 course.

## 1. Create a Developer Account

<Snippet file="create-developer-account.mdx" />

## 2. Get an API key

<Snippet file="create-api-key.mdx" />

Within the **Server-side keys** section, click the "Create new key" button in the top right. Then, select the scopes `credentials:template.create`, `credentials.read`, and `credentials.create` under the **Credentials** category and create your key. Save this key for the next step.

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

## 3. Create a Template

Every Verifiable Credential must belong to a template. Verifiable Credentials within a template share the same schema (referred to as "type" in the template definition), default-metadata, encryption, storage, and chain configurations. A credential template is equivalent to an NFT collection.

For the purpose of this quickstart, we will create a template with the following parameters:

* Type: `crossmint:5fe6040e-07a1-48bb-97a3-b588a7e927d2:courseCompletionQuickstart`. Types allow you to specify the attributes you are interested in certifying. They also act as a protective measure, preventing the addition of unauthorized fields and, as a result, the tampering of the Verifiable Credential. You can [define your own](/verifiable-credentials/guides/create-credential-types).

* Encryption: `none`. This means the Verifiable Credential data will be stored in plain text. To encrypt the data, read about the supported [encryption modalities](/verifiable-credentials/advanced/encrypt-credentials).

* Storage: `crossmint`. This means the Verifiable Credential data will be stored by Crossmint. To store the data at the location of your choice, or in decentralized storage, read about the supported [storage modalities](/verifiable-credentials/advanced/store-credentials).

The credential’s revocation state is stored in the chain provided (`polygon-amoy`), along with public (non-confidential) metadata related to your credential’s template.

To get started, copy the `createVCtemplate.js` file below, fill in your API key, and run it in your terminal.

<CodeGroup>
  ```javascript createVCtemplate.js theme={null}
  const myApiKey = ""; // Replace with key from step 2

  const templateParams = {
      credentials: {
          // "type" is set to an example type already created by Crossmint for this quickstart
          type: "crossmint:10d52c58-4f69-48db-b3e6-395e64ec84c6:courseCompletionQuickstart",
          encryption: "none",
          storage: "crossmint",
      },
      metadata: {
          name: "Satoshi University Credentials",
          description: "Credentials accredited by Satoshi University",
          imageUrl: "https://picsum.photos/400",
      },
      chain: "polygon-amoy",
  };

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

  fetch("https://staging.crossmint.com/api/v1-alpha1/credentials/templates/", options)
      .then((response) => response.json())
      .then((response) => console.log(JSON.stringify(response)))
      .catch((err) => console.error(err));
  ```

  ```json Response theme={null}
  {
      "id": "99348eaf-9f37-4b99-b64f-d9dd4372fb33",
      "metadata": {
          "name": "Satoshi University Credentials",
          "description": "Credentials accredited by Satoshi University"
      },
      "fungibility": "non-fungible",
      "onChain": { "chain": "polygon-amoy", "type": "erc-721" },
      "actionId": "99348eaf-9f37-4b99-b64f-d9dd4372fb33"
  }
  ```
</CodeGroup>

```shell theme={null}
node createVCtemplate.js
```

## 4. Issue a Credential

With a template created, we can start issuing credentials. To do this, we need to enter the subject’s email address, or wallet address, if they have one.

Then, we need to specify the exact data required by the Verifiable Credential type, i.e. course name and grade. The credential's contents are identified by the "subject" key within the credential.

<Warning>
  If you don't include an expiration date, the credential will not expire. You can always revoke the credential in the
  future, if necessary.
</Warning>

<Warning>
  The credential subject (credential.subject) must respect the schema of the chosen Verifiable Credential type. You
  cannot add additional fields, nor exclude any that were previously set.
</Warning>

To issue your first credential, copy the `issueCredential.js` file from below, add your API key, and templateId (that was returned from the previous step), and run the file from your terminal.

<CodeGroup>
  ```javascript issueCredential.js theme={null}
  const userEmail = "user@email.com"; // Replace with recipient email
  const templateId = "YOUR_TEMPLATE_ID"; // Replace with ID from previous step

  const credentialParams = {
      recipient: `email:${userEmail}:polygon-amoy`,
      credential: {
          // The courseCompletionQuickstart credential type requires course and grade declarations
          subject: {
              course: "Blockchain 101",
              grade: "A",
          },
          expiresAt: "2034-02-02",
      },
  };

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

  fetch(`https://staging.crossmint.com/api/v1-alpha1/credentials/templates/${templateId}/vcs`, options)
      .then((response) => response.json())
      .then((response) => console.log(JSON.stringify(response)))
      .catch((err) => console.error(err));
  ```

  ```json Response theme={null}
  {
      "id": "d7eb777b-e9b4-4f34-ab5f-ce199111166a",
      "onChain": {
          "status": "pending",
          "chain": "polygon-amoy",
          "contractAddress": "0xdC444A3F4768185497Dae6250E2F348b99bE89F3"
      },
      "credentialId": "urn:uuid:64f9877d-a19a-4205-8d61-f8c2abed5766",
      "actionId": "d7eb777b-e9b4-4f34-ab5f-ce199111166a"
  }
  ```
</CodeGroup>

```shell theme={null}
node issueCredential.js
```

**Congrats 🎉** you have issued your first credential.

You can [set up a webhook](/verifiable-credentials/advanced/webhooks) to know when the Verifiable Credential NFT minting is completed, or call the
[action status API](/api-reference/common/get-action-status) with the returned `actionId`.

## 5. Retrieve a Credential

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

* [Get Verifiable Credential by ID](/api-reference/verifiable-credentials/credentials/retrieve-credential-by-id) uses the format: `urn:uuid:<UUID>`
* [Get Verifiable Credential by NFT Locator](/api-reference/verifiable-credentials/credentials/retrieve-credential-by-nft-locator) uses the format: `<chain>:<contractAddress>:<tokenId>`
* [Get Verifiable Credential by NFT ID](/api-reference/verifiable-credentials/credentials/retrieve-credential-by-nft) uses crossmint's internal NFT ID

<Warning>
  There is no access control on credential retrieval, credential data is public and can be retrieved by anyone, use
  [encrypted credentials](/verifiable-credentials/advanced/encrypt-credentials) if you need to protect the data.
</Warning>

To retrieve the credential, copy the `retrieveCredential.js` file from below, use your API key, the `credentialId`, and run the file from your terminal.

<CodeGroup>
  ```javascript retrieveCredential.js theme={null}
  const options = {
      method: "GET",
      headers: {
          "X-API-KEY": "YOUR_API_KEY",
      },
  };

  fetch(`https://staging.crossmint.com/api/v1-alpha1/credentials/${credentialId}`, options)
      .then((response) => response.json())
      .then((response) => console.log(JSON.stringify(response)))
      .catch((err) => console.error(err));
  ```

  ```json Response theme={null}
  {
      "unencryptedCredential": {
          "id": "urn:uuid:4c9c41af-8410-4265-9fe4-3674d74e80d9",
          "credentialSubject": {
              "course": "Blockchain 101",
              "grade": "A",
              "id": "did:polygon-amoy:0xbFB0d0F9d49d80062103199c5aD309CE7a808039"
          },
          "validUntil": "2034-02-02",
          "nft": {
              "tokenId": "1",
              "chain": "polygon-amoy",
              "contractAddress": "0x288AAbb7D72A041Ea10719d2d676B65D2E9689F5"
          },
          "issuer": { "id": "did:polygon-amoy:0xB658f974Fe3744A6F9344810BC88e021E31B4d3e" },
          "type": ["VerifiableCredential", "crossmint:5fe6040e-07a1-48bb-97a3-b588a7e927d2:courseCompletionQuickstart"],
          "validFrom": "2024-09-14T13:59:34.918Z",
          "@context": ["https://www.w3.org/2018/credentials/v1"],
          "proof": {
              "verificationMethod": "did:polygon-amoy:0xB658f974Fe3744A6F9344810BC88e021E31B4d3e#evmAddress",
              "created": "2024-09-14T13:59:34.918Z",
              "proofPurpose": "assertionMethod",
              "type": "EthereumEip712Signature2021",
              "proofValue": "0x80587c5e9a801f4eed5bca95c48083277fc2ffe2fc1254f230f1b8c11cab59f63afaaa29bf29007129068243feb0069c46a8e583a64e64ff2517a2e3babd18101b",
              "eip712": {
                  "domain": {
                      "name": "Crossmint",
                      "version": "0.1",
                      "chainId": 4,
                      "verifyingContract": "0xD8393a735e8b7B6E199db9A537cf27C61Aa74954"
                  },
                  "types": {
                      "VerifiableCredential": [
                          { "name": "@context", "type": "string[]" },
                          { "name": "type", "type": "string[]" },
                          { "name": "id", "type": "string" },
                          { "name": "issuer", "type": "Issuer" },
                          { "name": "credentialSubject", "type": "CredentialSubject" },
                          { "name": "validFrom", "type": "string" },
                          { "name": "validUntil", "type": "string" },
                          { "name": "nft", "type": "Nft" }
                      ],
                      "CredentialSubject": [
                          { "name": "id", "type": "string" },
                          { "name": "course", "type": "string" },
                          { "name": "grade", "type": "string" }
                      ],
                      "Issuer": [{ "name": "id", "type": "string" }],
                      "Nft": [
                          { "name": "tokenId", "type": "string" },
                          { "name": "contractAddress", "type": "string" },
                          { "name": "chain", "type": "string" }
                      ]
                  },
                  "primaryType": "VerifiableCredential"
              }
          }
      }
  }
  ```
</CodeGroup>

```shell theme={null}
node retrieveCredential.js
```

## 6. Verify a Credential

Verifying a credential can be done in [different ways](/verifiable-credentials/guides/verify-credentials), the easiest one is to call
the [verify-credential](/api-reference/verifiable-credentials/credentials/verify-credential) API. You can also accomplish this with the SDK.

To verify the credential, copy the `verifyCredential.js` file from below, use your API key, the credentialId, and run the file from your terminal.

<CodeGroup>
  ```javascript verifyCredential.js theme={null}
  const options = {
      method: "POST",
      headers: {
          "X-API-KEY": "YOUR_API_KEY",
          "Content-Type": "application/json",
      },
      body: `{"credential": ${JSON.stringify(credential.unencryptedCredential)}}`,
  };

  fetch("https://staging.crossmint.com/api/v1-alpha1/credentials/verification/verify", options)
      .then((response) => response.json())
      .then((response) => console.log(JSON.stringify(response)))
      .catch((err) => console.error(err));
  ```

  ```json Response theme={null}
  {
      "isValid": true
  }
  ```
</CodeGroup>

```shell theme={null}
node verifyCredential.js
```

## 7. Revoke a Credential

To revoke a credential, you can directly use the [revoke credential API](/api-reference/verifiable-credentials/credentials/revoke-credential). Copy the `revokeCredential.js` file from below, use your API key, the credentialId, and run the file from your terminal.

```javascript revokeCredential.js theme={null}
const options = {
    method: "DELETE",
    headers: {
        "X-API-KEY": "YOUR_API_KEY",
    },
};

fetch(`https://staging.crossmint.com/api/v1-alpha1/credentials/${credentialId}`, options)
    .then((response) => response.json())
    .then((response) => console.log(JSON.stringify(response)))
    .catch((err) => console.error(err));
```

```shell theme={null}
node revokeCredential.js
```
