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

# Semi-Fungible Tokens (SFTs)

> Mint and send limited sets of identical digital assets in under 5 minutes

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.

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

## Integration steps

### 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, 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.

```javascript createCollection.js theme={null}
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));
```

<Accordion title="Example response">
  ```json JSON theme={null}
  {
    "id": "5263650e-6d43-4ed3-9e31-0cf593d076a4",
    "metadata": {
      "name": "My SFT Collection",
      "description": "A new collection with its own dedicated smart contract",
      "imageUrl": "https://www.crossmint.com/assets/crossmint/logo.png",
      "symbol": "XMINT"
    },
    "fungibility": "semi-fungible",
    "onChain": {
      "chain": "polygon-amoy",
      "type": "erc-1155"
    },
    "actionId": "5263650e-6d43-4ed3-9e31-0cf593d076a4"
  }
  ```
</Accordion>

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:

```javascript createTemplate.js theme={null}
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));
```

<Accordion title="Example response">
  ```json JSON theme={null}
  {
    "templateId": "58b0c1aa-e457-48dd-bb55-5a27e6a92f74",
    "metadata": {
      "name": "My template",
      "image": "ipfs://bafkreigbqsmxzkbjgbwtj6exfdt5z3t3swgoysf7hr6vjzddqnmykj6x2u",
      "description": "A new token template for my ERC1155 collection"
    },
    "onChain": {
      "tokenId": "1"
    },
    "supply": {
      "limit": "10",
      "minted": "0"
    }
  }
  ```
</Accordion>

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:

```javascript mintSFT.js theme={null}
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));
```

<Accordion title="Example response">
  ```json JSON theme={null}
  {
    "actionId": "a91c15e3-60f2-4a45-bf1a-cee508981667",
    "action": "nfts.create",
    "status": "pending",
    "data":
    {
      "chain": "polygon-amoy",
      "collection":
      {
        "id": "84e3d617-9c1b-4e7a-9686-522a9ea7c520",
        "contractAddress": "0x9b8ab8949bd7E73E61945b88F7fe12151f98ad3C"
      },
      "recipient":
      {
        "walletAddress": "0xcFDc00Cf926A5053f9Cdf004e6DF17e6dEB2E146",
        "email": "test@example.com"
      },
      "token":
      {
        "id": "a91c15e3-60f2-4a45-bf1a-cee508981667"
      }
    },
    "startedAt": "2024-01-02T22:05:01.000Z",
    "resource": "https://staging.crossmint.com/api/2022-06-09/actions/a91c15e3-60f2-4a45-bf1a-cee508981667"
  }
  ```
</Accordion>

### 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.

<CodeGroup>
  ```javascript mintStatus.js theme={null}
  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));
  ```

  ```bash cURL theme={null}
  # Replace "staging" with "www" for production, and fill in your api key and mint action id
  ENV="staging"
  API_KEY="<YOUR_API_KEY>"
  MINT_ACTION_ID="<MINT_ACTION_ID>"
  curl --header "x-api-key: $API_KEY" \
    -X GET \
    https://${ENV}.crossmint.com/api/2022-06-09/actions/${MINT_ACTION_ID}
  ```
</CodeGroup>

<br />

<Accordion title="Example response">
  Here is an example response from calling the status API:

  ```json JSON theme={null}
  {
    "actionId": "a91c15e3-60f2-4a45-bf1a-cee508981667",
    "action": "nfts.create",
    "status": "success",
    "data": {
      "collection": {},
      "recipient": {},
      "token": {}
    },
    "startedAt": "2024-01-02T22:05:01.000Z",
    "completedAt": "2024-01-02T22:06:04.000Z", 
    "resource": "https://staging.crossmint.com/api/2022-06-09/actions/a91c15e3-60f2-4a45-bf1a-cee508981667"
  }
  ```
</Accordion>

Pay attention to the "status" field. Once it says "success": <br /><br />
**Congratulations. You have minted your first SFT** 🥷 🎉

<Note>
  For scalable production applications, consider using [webhooks](/minting/nfts/integrate/webhooks-and-status-apis) to
  determine when your SFT has been minted, instead of periodically polling for its status via the API.
</Note>

## View your SFTs

1. If the SFTs were delivered to an <Tooltip tip="Crossmint creates a wallet for the user on-the-fly. This wallet is unique to your project and can optionally be displayed on your site. Users can also see these all their wallets, across developers, from a single interface on Crossmint's website.">**email address**</Tooltip>, the recipient can see them by:

   * Logging into their wallet from Crossmint's [website](https://www.crossmint.com). For staging, they must use [https://staging.crossmint.com](https://staging.crossmint.com).
   * From your website if you use [embedded wallets](/wallets/overview). See the API for [getting the NFTs](/api-reference/wallets/get-nfts-from-wallet) in a wallet.

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](https://www.crossmint.com/console).
2. Add credits to your account from [Billing & Usage](https://www.crossmint.com/console/billing).
3. Then, create a production key on the [API Keys](https://www.crossmint.com/console/projects/apiKeys) 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](/minting/advanced/best-practices)

## Learn More

<CardGroup cols={2}>
  <Card title="Create collections" icon="FILE" iconType="duotone" href="/minting/nfts/integrate/create-collections">
    Learn how to create and manage SFT collections.
  </Card>

  <Card title="Mint NFTs and other tokens" icon="cloud" iconType="duotone" color="1A5785" href="/minting/nfts/integrate/mint-tokens">
    Check out more advanced options for minting.
  </Card>

  <Card title="Edit & Burn NFTs" icon="file-pen" iconType="duotone" color="BFB218" href="/minting/guides/edit-and-burn-nfts">
    Update and delete tokens after minting.
  </Card>
</CardGroup>
