by -172 views

asset metadata
allows applications like OpenSea to pull in rich data for digital assets and hands display them in-app. Digital assets on a given smart contract are typically represented solely by a unique identifier (e.k., the
in ERC721), then metadata allows these assets to accept additional properties, such every bit a name, description, and paradigm.

For OpenSea to pull in off-concatenation metadata for ERC721 and ERC1155 assets, your contract will need to return a URI where nosotros can find the metadata. To find this URI, we utilize the
method in ERC721 and the
method in ERC1155. Outset, let’s wait closely at the
method in the Fauna contract.

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

function in your ERC721 or the
function in your ERC1155 contract should return an HTTP or IPFS URL. When queried, this URL should in turn render a JSON blob of data with the metadata for your token. You can come across an case of a simple Python server for serving metadata in the OpenSea creatures repo here.

See the section on
IPFS and Arweave
below for how to handle decentralized metadata URIs.

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

Additionally, we back up 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 Animal that enjoys long swims in the bounding main.",    "external_url": "",    "image": "",    "name": "Dave Starbelly",   "attributes": [ ... ],  }

Hither’s how each of these backdrop work:


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


Raw SVG image information, if yous want to generate images on the wing (non recommended). Merely utilise this if you lot’re not including the


This is the URL that will appear below the nugget’southward image on OpenSea and will allow users to go out OpenSea and view the particular on your site.


A human readable clarification of the detail. Markdown is supported.


Name of the item.


These are the attributes for the particular, which will bear witness up on the OpenSea folio for the item. (meet below)


Background colour of the detail on OpenSea. Must exist a half dozen-character hexadecimal
a pre-pended #.


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

Animation_url also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvass, WebGL, and more. Scripts and relative paths within the HTML page are now supported. Even so, access to browser extensions is not supported.


A URL to a YouTube video.

To give your items a piddling more than pizazz, we also allow y’all to add custom “attributes” to your metadata that will show up underneath each of your avails. For example, here are the attributes for ane of the OpenSea creatures.

To generate those attributes, the post-obit array of attributes was included in the metadata:

          ... { "attributes": [     {       "trait_type": "Base of operations",        "value": "Starfish"     },      {       "trait_type": "Eyes",        "value": "Big"     },      {       "trait_type": "Mouth",        "value": "Surprised"     },      {       "trait_type": "Level",        "value": 5     },      {       "trait_type": "Stamina",        "value": one.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     }   ] }

is the name of the trait,
is the value of the trait, and
is a field indicating how you would like it to be displayed. For
traits, you lot don’t have to worry near

For numeric traits, OpenSea currently supports three different options,
(lower right in the epitome below),
(lower left in the paradigm to a higher place), and
(similar to
but doesn’t show a pct sign). If you lot pass in a
that’s a number and you don’t set a
display_type, the trait will announced in the Rankings section (top right in the image above).

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

OpenSea also supports a
display_type. Traits of this type will appear in the right cavalcade near “Rankings” and “Stats.” Pass in a unix timestamp (seconds) as the value.

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

If y’all don’t desire to have a
for a particular trait, yous can include only a value in the trait and it will be ready as a generic property. For case,

            {     "value": "Happy"   }

We as well support the Enjin Metadata style:

          {     "properties": {         "base of operations": "starfish",         "rich_property": {             "name": "optics",             "value": "big",             "display_value": "Big",         }                 ...     } }

While nosotros advise confronting storing metadata on chain, if yous decide that information technology’south of import for your use case, contact the states at
[email protected]
and nosotros’ll become back to yous with questions and next steps.

A couple of import notes when coming upwardly with your attributes! You should include cord attributes equally strings (remember the quotes), and numeric backdrop as either floats or integers and so that OpenSea tin can display them appropriately. String properties should exist human-readable strings.

You’re welcome to deploy your metadata API however you encounter fit: y’all tin host information technology on IPFS, deject storage, or your own servers. To get you started, we’ve created a sample API server in both Python and NodeJS:

  • Python example API server
  • NodeJS example API server

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

OpenSea supports the storage of NFT metadata in decentralized file networks, so that they tin can’t be modified by a fundamental party.

If you utilise IPFS to host your metadata,
URL should be in the format
ipfs://<hash>. For instance,
ipfs://QmTy8w65yBXgyfG2ZBg5TrfB2hPjrDQH3RCQFJGkARStJb. If you lot programme to store on IPFS, we recommend Pinata for hands storing data. Here’s a tutorial by Chainlink for getting started:

Arweave’s equivalent is
ar://<hash>. For example,

Yous can indicate to OpenSea that an NFT’southward metadata is no longer changeable by anyone (in other words, it is “frozen”) by emitting this event from the smart contract:

event PermanentURI(string _value, uint256 indexed _id);

Contact us if y’all’d like to mark an unabridged smart contract as frozen.