Metadata standards

How to provide metadata for ERC-721 and ERC-1155 NFTs

OpenSea reads token metadata from the URI returned by your ERC-721 tokenURI function or ERC-1155 uri function. That metadata controls the name, media, description, and traits shown for an NFT.

To publish token metadata:

  1. Return a URI for each token from your contract.
  2. Serve valid JSON from that URI, or return the JSON onchain.
  3. Add the media and traits that you want OpenSea to display.
  4. Emit the relevant event when metadata changes.

Use the pages in this section to implement tokenURI or uri, choose storage, define media and traits, and handle updates.

For contract-level fields such as the name, banner, and collaborators, see Contract-level metadata.

Return token metadata

OpenSea fetches a token's metadata from the URI returned by your contract. The URI can point to a JSON document or embed metadata onchain. The Metadata storage page lists supported URI formats.

ERC-721

Implement tokenURI(uint256 tokenId) to return the metadata URI for a token.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract ExampleNFT is ERC721 {
    constructor() ERC721("Example NFT", "EXAMPLE") {
        _mint(msg.sender, 1);
    }

    function tokenURI(uint256 tokenId) public pure override returns (string memory) {
        require(tokenId == 1, "Nonexistent token");
        return "https://example.com/metadata/1.json";
    }
}

ERC-1155

Implement uri(uint256 id) to return the metadata URI for a token type.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

contract ExampleTokens is ERC1155 {
    constructor() ERC1155("") {}

    function uri(uint256) public pure override returns (string memory) {
        return "ipfs://bafy.../{id}.json";
    }
}

ERC-1155 clients replace {id} with the token ID as lowercase hexadecimal, without 0x, padded to 64 characters. For example, token ID 314592 resolves {id} to 000000000000000000000000000000000000000000000000000000000004cce0.

The URI should resolve to a JSON object. For example:

{
  "name": "Example NFT #1",
  "description": "An example NFT.",
  "image": "ipfs://bafy.../1.png"
}

See the Media and traits page for supported fields and attribute formats.