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

# Music Quickstart ⚡

> Register your music on Story in under 5 minutes

In this quickstart, you will:

* Register a music album as an IP collection
* Register a music track as an IP asset

<Note> This quickstart is under development as new features are added to the Story Protocol daily. </Note>

## Preparation Steps

<Steps>
  <Step title="Create a Developer Account and Project">
    <Snippet file="create-developer-account.mdx" />
  </Step>

  <Step title="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.
  </Step>
</Steps>

## Register Music Album

<Steps>
  <Step title="Create an IP Collection">
    <CodeGroup>
      ```typescript createCollection.ts theme={null}
      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);
      ```

      ```typescript response theme={null}
      {
          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' }
      }
      ```
    </CodeGroup>

    Additional metadata can be added to the collection to help with discovery, such as a cover image. Check out the [API reference](/api-reference/ip/create-ip-collection) for more information.

    To create the album, run the script:

    <CodeGroup>
      ```bash TypeScript theme={null}
      npx tsx createCollection.ts
      ```
    </CodeGroup>
  </Step>
</Steps>

## Register Song

<Steps>
  <Step title="Create a Song">
    Go to [Suno](https://suno.ai/), 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
  </Step>

  <Step title="Register Song on Story">
    <CodeGroup>
      ```typescript registerIPAsset.ts theme={null}
      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);
      ```

      ```typescript response theme={null}
      {
          "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"
          }
      }
      ```
    </CodeGroup>

    Run the script to register the song:

    <CodeGroup>
      ```bash TypeScript theme={null}
      npx tsx registerIPAsset.ts
      ```
    </CodeGroup>
  </Step>
</Steps>

## Retrieve Your IP Asset

<Steps>
  <Step title="Get IP Asset Details">
    After registering your IP asset, you can retrieve its details to verify the information or display it in your application.

    <CodeGroup>
      ```typescript getIPAsset.ts theme={null}
      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);
      ```

      ```typescript response theme={null}
      {
          "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"
          }
      }
      ```
    </CodeGroup>

    Replace `{collectionId}` with your collection ID and `{ipAssetId}` with the IP asset ID returned when you registered the asset. Then run the script:

    <CodeGroup>
      ```bash TypeScript theme={null}
      npx tsx getIPAsset.ts
      ```
    </CodeGroup>
  </Step>
</Steps>

## Confirm Song Registration

<Steps>
  <Step title="Get Action Status">
    You can easily check the IP asset registration status to ensure the action has completed before proceeding.

    <CodeGroup>
      ```typescript getAction.ts theme={null}
      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);
      ```

      ```typescript response theme={null}
      {
          id: '1ffb0fc3-b652-4a0e-b748-3e09c3608826',
          status: 'success'
      }
      ```
    </CodeGroup>

    Use the action ID returned in any of the previous steps and run the script:

    <CodeGroup>
      ```bash TypeScript theme={null}
      npx tsx getAction.ts
      ```
    </CodeGroup>
  </Step>
</Steps>
