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:
- Return a URI for each token from your contract.
- Serve valid JSON from that URI, or return the JSON onchain.
- Add the media and traits that you want OpenSea to display.
- 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.
Updated 6 days ago
