Skip to main content
In this quickstart, you will:
  • Register a music album as an IP collection
  • Register a music track as an IP asset
This quickstart is under development as new features are added to the Story Protocol daily.

Preparation Steps

1

Create a Developer Account and Project

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

Create a server-side API key with these scopes: collection.create, collection.update, collection.read, nfts.create, nfts.read.This allows your API key to perform any kind of asset registration action.

Register Music Album

1

Create an IP Collection

const response = await fetch("https://staging.crossmint.com/api/v1/ip/collections", {
    method: "POST",
    headers: {
        "X-API-KEY": "<YOUR_API_KEY>",
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        metadata: {
            description: "My first music album",
            name: "My First Album",
            symbol: "MFA"
        },
        chain: "story-testnet"
    })
});

const collection = await response.json();
console.log("Collection created:", collection);
{
    id: '1ffb0fc3-b652-4a0e-b748-3e09c3608826',
    actionId: '1ffb0fc3-b652-4a0e-b748-3e09c3608826',
    metadata: {
        name: 'My First Album',
        symbol: 'MFA',
        description: 'My first music album'
    },
    onChain: { chain: 'story-testnet' }
}
Additional metadata can be added to the collection to help with discovery, such as a cover image. Check out the API reference for more information.To create the album, run the script:
npx tsx createCollection.ts

Register Song

1

Create a Song

Go to Suno, a music platform for AI-generated music, to create a song:
  • Input a prompt to create a song
  • Click on the final result to get the song’s URL (i.e. https://suno.com/song/c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515)
  • Copy the song ID in the URL (i.e. c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515)
  • Copy the following URL: https://cdn1.suno.ai/${SONG_ID}.mp3, making sure to replace SONG_ID with your own
2

Register Song on Story

const response = await fetch("https://staging.crossmint.com/api/v1/ip/collections/{collectionId}/ipassets", {
    method: "POST",
    headers: {
        "X-API-KEY": "<YOUR_API_KEY>",
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        owner: 'email:creator@example.com:story-testnet',
        nftMetadata: {
            name: 'Snowflake Funk',
            description: 'A disco groovy song for a house party during the winter time',
            image: 'https://cdn2.suno.ai/image_large_c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.jpeg'
        },
        ipAssetMetadata: {
            title: 'Snowflake Funk',
            createdAt: '2025-02-11T11:13:00',
            ipType: 'music',
            image: 'https://cdn1.suno.ai/c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.mp3',
            imageHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
            mediaUrl: 'https://cdn1.suno.ai/c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.mp3',
            mediaHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
            mediaType: 'audio/mpeg',
            creators: [
                {
                    name: 'John Doe',
                    email: 'john.doe@example.com',
                    crossmintUserLocator: 'email:john.doe@example.com:story-testnet',
                    contributionPercent: 100
                },
            ],
            media: [
                {
                    name: 'Snowflake Funk',
                    url: 'https://cdn1.suno.ai/c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.mp3',
                    mimeType: 'audio/mpeg'
                },
            ],
            attributes: [
                {
                    key: 'Suno Artist',
                    value: 'InfluentialCoda427'
                },
                {
                    key: 'Source',
                    value: 'Suno.com'
                }
            ]
        }
    })
});

const ipAsset = await response.json();
console.log("IP Asset:", ipAsset);
{
    "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "actionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "nftMetadata": {
        "name": "Snowflake Funk",
        "description": "A disco groovy song for a house party during the winter time",
        "image": "https://cdn2.suno.ai/image_large_c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.jpeg"
    },
    "ipAssetMetadata": {
        "title": "Snowflake Funk",
        "createdAt": "2025-02-11T11:13:00",
        "ipType": "music",
        "creators": [
            {
                "name": "John Doe",
                "email": "email:user@example.com",
                "contributionPercent": 100
            }
        ],
        "media": [
            {
                "name": "Snowflake Funk",
                "url": "https://cdn1.suno.ai/c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.mp3",
                "mimeType": "audio/mpeg"
            }
        ],
        "attributes": [
            {
                "key": "Suno Artist",
                "value": "InfluentialCoda427"
            },
            {
                "key": "Source",
                "value": "Suno.com"
            }
        ]
    },
    "onChain": {
        "status": "success",
        "chain": "story-testnet",
        "contractAddress": "0x123",
        "ipAssetId": "0xAC6062FF53fa41e61Fe01B89B83d9dB96b5F9280",
        "tokenId": "1",
        "txId": "0x123",
        "explorerLink": "https://explorer.story.foundation/ipa/0xAC6062FF53fa41e61Fe01B89B83d9dB96b5F9280"
    }
}
Run the script to register the song:
npx tsx registerIPAsset.ts

Retrieve Your IP Asset

1

Get IP Asset Details

After registering your IP asset, you can retrieve its details to verify the information or display it in your application.
const response = await fetch("https://staging.crossmint.com/api/v1/ip/collections/{collectionId}/ipassets/{ipAssetId}", {
    method: "GET",
    headers: {
        "X-API-KEY": "<YOUR_API_KEY>",
        "Content-Type": "application/json"
    }
});

const ipAsset = await response.json();
console.log("IP Asset:", ipAsset);
{
    "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "nftMetadata": {
        "name": "Snowflake Funk",
        "description": "A disco groovy song for a house party during the winter time",
        "image": "https://cdn2.suno.ai/image_large_c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.jpeg"
    },
    "ipAssetMetadata": {
        "title": "Snowflake Funk",
        "createdAt": "2025-02-11T11:13:00",
        "ipType": "music",
        "creators": [
            {
                "name": "John Doe",
                "email": "email:user@example.com",
                "contributionPercent": 100
            }
        ],
        "media": [
            {
                "name": "Snowflake Funk",
                "url": "https://cdn1.suno.ai/c001fd6e-d6cd-474f-a7b6-6e6a9b3e2515.mp3",
                "mimeType": "audio/mpeg"
            }
        ],
        "attributes": [
            {
                "key": "Suno Artist",
                "value": "InfluentialCoda427"
            },
            {
                "key": "Source",
                "value": "Suno.com"
            }
        ]
    },
    "onChain": {
        "status": "success",
        "chain": "story-testnet",
        "contractAddress": "0x123",
        "ipAssetId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
        "tokenId": "1",
        "txId": "0x123",
        "explorerLink": "https://explorer.story.foundation/ipa/0xAC6062FF53fa41e61Fe01B89B83d9dB96b5F9280"
    }
}
Replace {collectionId} with your collection ID and {ipAssetId} with the IP asset ID returned when you registered the asset. Then run the script:
npx tsx getIPAsset.ts

Confirm Song Registration

1

Get Action Status

You can easily check the IP asset registration status to ensure the action has completed before proceeding.
const response = await fetch("https://staging.crossmint.com/api/v1/ip/actions/{actionId}", {
    method: "GET",
    headers: {
        "X-API-KEY": "<YOUR_API_KEY>",
        "Content-Type": "application/json"
    }
});

const action = await response.json();
console.log("Action:", action);
{
    id: '1ffb0fc3-b652-4a0e-b748-3e09c3608826',
    status: 'success'
}
Use the action ID returned in any of the previous steps and run the script:
npx tsx getAction.ts