OpenSea

Build your own marketplace in minutes

OpenSea provides a one-stop shop for creating your own customizable marketplace for your non-fungible token (NFT) project. Allow users to smoothly buy and sell your items, get custom stats and analytics, and earn revenue when your items get traded.

Guides

Metadata Standards

How to add rich metadata to your ERC721 or ERC1155 NFTs

Providing asset metadata allows applications like OpenSea to pull in rich data for digital assets and easily display them in-app. Digital assets on a given smart contract are typically represented solely by a unique identifier (e.g., the token_id in ERC721), so metadata allows these assets to have additional properies, such as a name, description, and image.

Implementing token URI

For OpenSea to pull in off-chain metadata for ERC721 and ERC1155 assets, your contract will need to return a URI where we can find the metadata. To find this URI, we use the tokenURI method in ERC721 and the uri method in ERC1155. First, let's look closely at the tokenURI method in the Creature contract.

  /**
   * @dev Returns an URI for a given token ID
   */
  function tokenURI(uint256 _tokenId) public view returns (string) {
    return Strings.strConcat(
        baseTokenURI(),
        Strings.uint2str(_tokenId)
    );
  }

The tokenURI function in your ERC721 or the uri function in your ERC1155 contract should return an HTTP or IPFS URL, such as https://opensea-creatures-api.herokuapp.com/api/creature/3. When queried, this URL should in turn return a JSON blob of data with the metadata for your token. You can see an example of a simple Python server for serving metadata in the OpenSea creatures repo here.

If you use IPFS to host your metadata, your URL should be in the format ipfs://ipfs/<hash>. For example, ipfs://ipfs/QmTy8w65yBXgyfG2ZBg5TrfB2hPjrDQH3RCQFJGkARStJb.

Metadata structure

OpenSea supports metadata that is structured according to the official ERC721 metadata standard or the Enjin Metadata suggestions.

Additionally, we support several other properties that allow for multimedia attachments -- including audio, video, and 3D models -- plus interactive traits for your items, giving you all the sorting and filtering capabilities on the OpenSea marketplace.

Here's an example of metadata for one of the OpenSea creatures:

{
  "description": "Friendly OpenSea Creature that enjoys long swims in the ocean.", 
  "external_url": "https://openseacreatures.io/3", 
  "image": "https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png", 
  "name": "Dave Starbelly",
  "attributes": [ ... ], 
}

Here's how each of these properties work:

image

This is the URL to the image of the item. Can be just about any type of image (including SVGs, which will be cached into PNGs by OpenSea, and even MP4s), and can be IPFS URLs or paths. We recommend using a 350 x 350 image.

image_data

Raw SVG image data, if you want to generate images on the fly (not recommended). Only use this if you're not including the image parameter.

external_url

This is the URL that will appear below the asset's image on OpenSea and will allow users to leave OpenSea and view the item on your site.

description

A human readable description of the item. Markdown is supported.

name

Name of the item.

attributes

These are the attributes for the item, which will show up on the OpenSea page for the item. (see below)

background_color

Background color of the item on OpenSea. Must be a six-character hexadecimal without a pre-pended #.

animation_url

A URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, and OGG are supported, along with the audio-only extensions MP3, WAV, and OGA.

youtube_url

A URL to a YouTube video.

Attributes

To give your items a little more pizazz, we also allow you to add custom "attributes" to your metadata that will show up underneath each of your assets. For example, here are the attributes for one of the OpenSea creatures.

To generate those attributes, the following array of attributes was included in the metadata:

...
{
"attributes": [
    {
      "trait_type": "Base", 
      "value": "Starfish"
    }, 
    {
      "trait_type": "Eyes", 
      "value": "Big"
    }, 
    {
      "trait_type": "Mouth", 
      "value": "Surprised"
    }, 
    {
      "trait_type": "Level", 
      "value": 5
    }, 
    {
      "trait_type": "Stamina", 
      "value": 1.4
    }, 
    {
      "trait_type": "Personality", 
      "value": "Sad"
    }, 
    {
      "display_type": "boost_number", 
      "trait_type": "Aqua Power", 
      "value": 40
    }, 
    {
      "display_type": "boost_percentage", 
      "trait_type": "Stamina Increase", 
      "value": 10
    }, 
    {
      "display_type": "number", 
      "trait_type": "Generation", 
      "value": 2
    }
  ]
}

Here trait_type is the name of the trait, value is the value of the trait, and display_type is a field indicating how you would like it to be displayed. For string traits, you don't have to worry about display_type.

Numeric Traits

For numeric traits, OpenSea currently supports three different options, number (lower right in the image below), boost_percentage (lower left in the image above), and boost_number (similar to boost_percentage but doesn't show a percent sign). If you pass in a value that's a number and you don't set a display_type, the trait will appear in the Rankings section (top right in the image above).

Adding an optional max_value sets a ceiling for a numerical trait's possible values. It defaults to the maximum that OpenSea has seen so far on the assets on your contract. If you set a max_value, make sure not to pass in a higher value.

Date Traits

OpenSea also supports a date display_type. Traits of this type will appear in the right column near "Rankings" and "Stats." Pass in a unix timestamp as the value.

    {
      "display_type": "date", 
      "trait_type": "birthday", 
      "value": 1546360800
    }

If you don't want to have a trait_type for a particular trait, you can include just a value in the trait and it will be set as a generic property. For example,

  {
    "value": "Happy"
  }

We also support the Enjin Metadata style:

{
    "properties": {
        "base": "starfish",
        "rich_property": {
            "name": "eyes",
            "value": "big",
            "display_value": "Big",
        }
                ...
    }
}

While we advise against storing metadata on chain, if you decide that it's important for your use case, contact us at [email protected] and we'll get back to you with questions and next steps.

Attribute guidelines

A couple important notes when coming up with your attributes! You should include string attributes as strings (remember the quotes), and numeric properties as either floats or integers so that OpenSea can display them appropriately. String properties should be human-readable strings.

Deploying your metadata API

You're welcome to deploy your metadata API however you see fit: you can host it on IPFS, cloud storage, or your own servers. To get you started, we've created a sample API server in both Python and NodeJS:

We'll create a tutorial on building and deploying your metadata server to Heroku soon! In the meantime, check out Heroku's resource on the subject.

Storing on IPFS

If you plan to store on IPFS, we recommend Pinata for easily storing data in IPFS.

Updated about 11 hours ago

Metadata Standards


How to add rich metadata to your ERC721 or ERC1155 NFTs

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.