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.


2. Adding metadata

For OpenSea to pull in off-chain metadata, you'll need your contract to return where to find the metadata. To do this, we use the tokenURI method in ERC721. 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(

Your tokenURI function in your ERC721 asset should return an HTTP or IPFS URL, such as 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.

OpenSea supports metadata that is structured according to the official ERC721 metadata standard. Additionally, we support several other properties that allow for richer display of your items (as well as all of 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": "", 
  "image": "", 
  "name": "Dave Starbelly",
  "attributes": [ ... ], 

Here's how each of these properties work:


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 can be IPFS URLs or paths.

image_data (instead of "image")

Raw SVG image data, if you want to generate images on the fly.


This is the URL that the item will link to on OpenSea. It should be the URL of that individual item on your site.


A human readable description of the item.


Name of the item.


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


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


A URL to an animated image of the item. GLTF, GLB, and WEBM are supported.


A URL to a YouTube video.


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.

For numeric traits, OpenSea currently supports three different options, number (lower right in the image below), boost_percentage (lower left in the image below), boost_number (similar to boost_percentage but doesn't show a percent sign), and ranking (upper right in the image below). The default is the upper right in the image below.

Lastly, max_value is an optional maximum for the trait's possible values. It defaults to the maximum that OpenSea has seen so far on the assets on your contract.

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"

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. You should also use underscore case (for example, max_power) for these properties to show up as human-readable strings on OpenSea.

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 two simple sample API servers in Python and NodeJS that serve metadata for OpenSea creatures:

2. Adding metadata

Suggested Edits are limited on API Reference Pages

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