The ultimate, definitive

NFT metadata
Cheat Sheet

An easy-to-use & up-to-date ERC-721 metadata reference.

Last updated Sep 14 2023

Metadata Example

London Gift Collection

{ "name": "quarrelsome skirt", "description": "In celebration of EIP-1559.", "image": "ipfs://bafybeiaduopgn6uqef73a6n6qrjqnfaviw765wcfdge7rvhslnmn5nukte", "attributes": [...] }

NFTs are nothing without its metadata. Currently, the most supported metadata standard is OpenSea metadata std as specified in their docs.

Even as the most supported std, OpenSea's std have features that are poorly supported across the industry. By testing 100+ permutations of NFT metadata, we crafted this cheat sheet to help NFT creators deliver the best stories in their NFTs.

OpenSea Std.

name

Name of NFT. Unicode is supported. Optional, defaults to "#tokenId", "untitled", "Collection Name #tokenId"

Examples

description

Description of NFT. Unicode and markdown is supported by some NFT indexers. Optional, defaults to collection description if provided.

Examples

image

URI (Uniform Resource Identifier) to an image of NFT. All URI types specified below are supported. SVGs, PNGs, GIFs, JPGs, WEBPs, ICOs, AVIFs, APNGs are supported. Optional, defaults to collection image. Note: SVG is not fully rendered by all platforms, especially mobile experiences.

Examples

image_data

Raw image data for NFT item. Effectively, deprecated. Rarely used and ONLY in place of image parameter. When used in conjunction with image, behavior is unpredictable; image_data or image can be shown dependent on NFT indexer implementation.

Examples

external_url

A URI (uniform resource identifier) to an external website to view the NFT. URI will require browser to support web3 resolution. (Brave supports IPFS, but not Arweave.) https:// is the most consistently reliable URI resolution. Optional, if not provided, NFT indexers can default to collection url.

Examples

background_color

Background Color of NFT. Specified as hexadecimal without the pre-pended #. Optional. Rarely used in practice and poorly supported by NFT Indexers.

Examples

animation_url

URI to multi-media asset for NFT. File can be GLTF, GLB, WEBM, MP4, MOV, OGG, OGV, MP3, M4A, FLAC, AAC, WAV, OGA, HTML. Not all NFT indexers support all file formats.

If image is provided in conjunction with animation_url, some NFT indexers will use image as a 'preview' and render in contexts where a 'preview' is preferred.

HTML Nuances
HTML files will be run in a sandbox iframe with javascript and webgl enabled. Will be run in a square aspect ratio. The following browser features are sometimes allowed by NFT Indexers: accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture

Examples

youtube_url

A youtube url. Effectively deprecated. Do not use this attribute.

Examples

attributesor

propertiesor

traitsor

features

Array of JSON objects that define unique "attributes" of the NFT. These attributes are commonly surfaced in UI and can be used to filter & search for specific categories of NFTs. Attributes are designed to be human readable and help users better understand the nuances of their NFT.

Each attribute object contained in the attributes array are in the following shape.

{ "trait_type": string, "value": string | number, "display_type": 'number' | 'date' | 'boost_number' | 'boost_percentage', "max_value": number, }

trait_type defines the name of this attribute. Unicode is supported. Ex. "headgear" | "tier" | "clothing"
value defines the NFT's value for this attribute. This can be either a string or a number. Unicode is supported. Ex. "Ball Cap" | "Ultra Rare" | "Hoodie"

Attributes with value as a number
NFT Indexers can render numeric attributes in unique UIs, inspired by in-game character stat UIs.

display_type is an optional value to control UI rendered, it informs how NFT indexers should best render this attribute. Opensea only recognizes the above strings as valid.

max_value can be provided to help further inform NFT indexers how to contextually render the attribute in UI. Optional.

Gotchas
Remember to make attributes human-readable. Attributes are rendered on collector-facing UI and should be optimized for such display.

In NFT Metadata, attributes, properties, traits, features are all valid keys to the attributes array.

If two attributes in array have the same trait_value, both will be rendered on UI.

display_type & max_value is poorly supported by NFT indexers. We do not advise using these as we only observe OpenSea supporting these values.

display_type & max_value only work with numeric attributes.

display_type: "date" attributes should provide unix time (seconds since 1970) as value.

display_type: "number" attributes will sometimes behave differently on NFT indexers than numeric traits without any display_type set.

Examples

Enjin Std.

Enjin Metadata Standard largely shares the same schema as the OpenSea std with a few notable changes. Both OpenSea and Enjin are widely supported NFT standards.

propertiesor

attributesor

traitsor

features

JSON Object that define unique "attributes". These attributes are commonly surfaced in UI and can be used to filter & search for specific categories of NFTs. Attributes are designed to be human readable and help users better understand the nuances of their NFT.

Compared to OpenSea's attribute design, Enjin utilizes an object over an array.

Keys in the properties object are the name of traits, equivalent to trait_type in OpenSea std. For example:

{ "tier": "common", "health": 100 }

Rich attributes
Instead of simply providing a string or number for an attribute, a rich attribute object can be provided.

{ "tier": { name: "Tier", value: "common", display_value: "Common", }, }

name can be optionally provided as the name of the attribute.

value is the value of the attribute.

display_value is a human readable string of the value.

Gotchas
Remember to make attributes human-readable. Attributes are rendered on collector-facing UI and should be optimized for such display.

In NFT Metadata, attributes, traits, features are all valid keys to the attributes object.

There is no official standard for Rich Attributes. As far as our testing goes, name and value are well supported. display_value is supported by a few NFT indexers. Any other values in Rich Attributes may not be supported.

Examples

URI Uniform Resource Identifier

Marketplaces like OpenSea support a variety of web2 and web3 URIs for NFT metadata and attributes contained in metadata. Each URI type have different pro and cons.

https://

A URI pointing to a specific resource/server hosted by a centralized entity. Resolved via DNS.

Operates at the speed of web2 infrastructure and can enable dynamic NFT metadata by generating metadata on-the-fly.

https is a location identifier for a server. Unlike decentralized solutions, if this location were to go down, the metadata will be lost or performance degraded.

ipfs://

A URI that identifies content on the IPFS network. IPFS URIs are content-based, not location based. This means, IPFS URIs are immutable content and are provably authentic.

Operates at the speed of the IPFS network and nodes. Content needs to be 'discovered' across nodes and then pinned by nodes. Network is typically accessed by end-users through https based gateways.

URIs identifying ipfs content is no guarantee content is stored permanently. IPFS nodes opt into pinning content and if no nodes pin, content is not discoverable on IPFS. Solutions like nft.storage stores content on storage blockchains like FileCoin to ensure data is permanent.

Learn more about how IPFS works.

arweave://

A URI that identifies content on the Arweave blockchain. Arweave URIs are content-based, not location based. This means, Arweave URIs are immutable content and are provably authentic.

Arweave utilizes a novel consensus algorithm and node design to scalably store data permanently. Retrieval of data means discovering content across Arweave Nodes. Network is typically accessed by end-users through https based gateways.

Arweave content is stored and payed for via transactions to the Arweave blockchain, paid in AR tokens. Content is NOT replicated on each Arweave node, instead, Arweave incentivizes the network to keep at least one copy of your data available.

Learn more about how Arweave works.

data:application/json;

URI that encodes the raw metadata in the URI itself. No external resource is required. Marketplaces decode the URL to get the metadata/resource provided.

Since no network is required, data URIs are some of the fastest and most performant means of metadata delivery.

Note that since all data is encoded in the URI, URI and metadata size limits may be a limiting factor.

Metadata Updates

Marketplaces like OpenSea cache NFT metadata for performance reasons. Notify marketplaces that metadata has changed via ERC-4906: ERC-721 Metadata Update Extension.

interface IERC4906 is IERC165, IERC721 { event MetadataUpdate(uint256 _tokenId); event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); }

We strongly recommend using ERC-4906 as it will notify all NFT-indexers to update NFT metadata. However, outside of the standard, most NFT-indexers have API end pts to trigger a metadata update. OpenSea Update End Pt

Tips & Tricks

Collected here are some tricks we, Pob Studio, discovered since our inception. These tricks are not specifically part of any NFT metadata standard.

  • Most marketplaces support a maximum NFT metadata size of 100mb.
  • Metadata do not have to be 100% compliant JSON. If two of the same keys have been provided, the later key in the JSON will be used. This behavior can be used to easily override different aspects of NFT metadata for dynamic applications.
  • Metadata performance can be greatly increased by using data:content; URIs. This reduces a network call required by NFT-indexers and makes dynamic NFTs feel more reactive.
  • When building fully on-chain NFT metadata, a safe maximum of 300 million gas should be observed for tokenURI.
  • While 300 million gas is considered safe for eth_call, some nodes will time-out due to some EVM operations taking longer than others.

References

Join our Discord to discuss and provide input to this guide.

Gradient of tokenization

Be in the know

Stay up to date with the latest from Pob Studio

"No finite point has meaning without an infinite reference point." - James Baldwin