In this quickstart you will learn how to create semi-fungible tokens (SFTs) and deliver them to a wallet or email address.

What are SFTs?

SFTs (semi-fungible tokens) follow the ERC-1155 standard. Each token is a replica of a predefined template. Each collection (smart contract) can contain multiple templates, which can contain many tokens.

This API only supports EVM chains self-serve. Contact us if you need support for another chain.

Integration steps

1. Create a Developer Account

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

Crossmint offers two consoles: staging, for development and testing, and production.

2. Get an API Key

Once you log in to the console, the next step is to create an .

Click the "Integrate" tab and click on the "API Keys" option on top.

Within the “Server-side keys” section, click the “Create new key” button in the top right. Then, check the scopes nfts.create, nfts.read, and collections.create under the “Minting API” category and create your key. Save this key for the next step.

3. Create an SFT collection

With our key created, we’re now going to create an SFT collection to hold our templates.

createCollection.js
const apiKey = "YOUR_API_KEY";
const env = "staging"; // or "www"

const url = `https://${env}.crossmint.com/api/2022-06-09/collections`;
const options = {
    method: "POST",
    headers: {
        accept: "application/json",
        "content-type": "application/json",
        "x-api-key": apiKey,
    },
    body: JSON.stringify({
        chain: "polygon-amoy",
        fungibility: "semi-fungible",
        metadata: {
            name: "My SFT Collection",
            imageUrl: "https://www.crossmint.com/assets/crossmint/logo.png",
            description: "A new collection with its own dedicated smart contract",
        },
    }),
};

fetch(url, options)
    .then((res) => res.json())
    .then((json) => console.log(json))
    .catch((err) => console.error("error:" + err));

Save the id from the response as your COLLECTION_ID for the next steps.

4. Create a template within that collection

Now, let’s create a template within our collection:

createTemplate.js
const apiKey = "YOUR_API_KEY";
const env = "staging"; // or "www"
const collectionId = "YOUR_COLLECTION_ID";

const url = `https://${env}.crossmint.com/api/2022-06-09/collections/${collectionId}/templates`;
const options = {
    method: "POST",
    headers: {
        accept: "application/json",
        "content-type": "application/json",
        "x-api-key": apiKey,
    },
    body: JSON.stringify({
        onChain: {
            tokenId: "1",
        },
        supply: {
            limit: 10,
        },
        metadata: {
            name: "My template",
            image: "https://www.crossmint.com/assets/crossmint/logo.png",
            description: "A new token template for my ERC1155 collection",
        },
    }),
};

fetch(url, options)
    .then((res) => res.json())
    .then((json) => console.log(json))
    .catch((err) => console.error("error:" + err));

Save the templateId from the response for the next step.

5. Mint an SFT from a template

Now, let’s mint an SFT from our template and send it to a wallet or email address:

mintSFT.js
const apiKey = "YOUR_API_KEY";
const env = "staging"; // or "www"
const collectionId = "YOUR_COLLECTION_ID";
const templateId = "YOUR_TEMPLATE_ID";
const recipientEmail = "TEST_EMAIL_ADDRESS";

const url = `https://${env}.crossmint.com/api/2022-06-09/collections/${collectionId}/sfts`;
const options = {
    method: "POST",
    headers: {
        accept: "application/json",
        "content-type": "application/json",
        "x-api-key": apiKey,
    },
    body: JSON.stringify({
        templateId: templateId,
        recipient: `email:${recipientEmail}:polygon-amoy`,
        amount: 1,
    }),
};

fetch(url, options)
    .then((res) => res.json())
    .then((json) => console.log(json))
    .catch((err) => console.error("error:" + err));

6. Confirm Delivery of the SFT

The mint has started processing. However, blockchains can take a few seconds (or, at times of extreme network congestion, even minutes) to confirm the operation.

Before showing the user a success screen, the next step is checking the status of the mint.

To do this, grab the actionId received at the end of step 5 and use it alongside your API key in one of the snippets below.

const apiKey = "<YOUR_API_KEY>";
const env = "staging"; // or "www"
const actionId = "<MINT_ACTION_ID>";

const url = `https://${env}.crossmint.com/api/2022-06-09/actions/${actionId}`;
const options = {
method: "GET",
headers: { "X-API-KEY": apiKey },
};

fetch(url, options)
.then((response) => response.json())
.then((response) => console.log(response))
.catch((err) => console.error(err));

Pay attention to the “status” field. Once it says “success”:

Congratulations. You have minted your first SFT 🥷 🎉

For scalable production applications, consider using webhooks to determine when your SFT has been minted, instead of periodically polling for its status via the API.

View your SFTs

  1. If the SFTs were delivered to an , the recipient can see them by:

  2. If the SFTs were delivered to a wallet address, the user will be able to see them there directly, connecting to testnet if needed, or on the testnet blockchain explorer.

And voilá, there’s your SFT! Now think of all the cool things you can build with this, at scale :)

Launching in Production

For production, the steps are almost identical, but some changes are required:

  1. Create a developer account on the production console.
  2. Add credits to your account from Billing & Usage.
  3. Then, create a production key on the API Keys page with the same API scopes.
  4. Modify all code snippets with const env = "www", so they use the production APIs. You may also need to change the chain variable to match your production blockchain.
  5. Check the guide with best practices

Learn More