Back

Blog details

ERC-1155 Metadata on IPFS: The ID Substitution Rule

AIOZ Network
6 min readOctober 21, 2026
aioz-pin

ERC-1155 metadata on IPFS follows different rules from ERC-721, because an ERC-1155 contract usually stores one URI with a placeholder instead of one URL per token. Every wallet and marketplace fills in that placeholder itself. It works smoothly on a normal web server and fails on IPFS, where a file name is part of what you pin. This guide covers the exact {id} rule from the standard, a folder layout that satisfies it, and the per-token alternative for when a single folder does not fit.

TL;DR:

  • ERC-1155 exposes metadata through uri(uint256 id), not tokenURI(), and the standard lets one URI containing {id} cover every token
  • Clients must replace {id} with the token ID in lowercase hexadecimal, no 0x prefix, zero-padded to 64 characters, so token 1 becomes 000...0001
  • On IPFS this means pinning a folder whose files are named with that 64-character hex ID, then setting the contract URI to ipfs://<FOLDER_CID>/{id}.json
  • OpenZeppelin's ERC1155URIStorage extension stores a separate URI per token instead, which removes the naming rule but adds one on-chain value per token
  • A folder is one CID, so editing any file inside it produces a new CID and a contract URI change, and the folder still has to stay pinned

What the Standard Says About

The metadata rules live in the EIP-1155 specification. The optional metadata extension defines one function, uri(uint256 _id), which returns a URI pointing at a JSON file. ERC-1155 has no tokenURI(); that name belongs to ERC-721, and calling it on an ERC-1155 contract is a common mix-up.

The part that causes trouble is the substitution rule. If the string {id} appears in a URI, clients must replace it with the actual token ID in hexadecimal. The spec adds two format requirements: the hex string is lowercase [0-9a-f] with no 0x prefix, and it is leading-zero padded to 64 characters. The EIP gives an example: https://token-cdn-domain/{id}.json becomes https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json for token ID 314592, which is 0x4CCE0 in hex.

The same rule applies to any JSON value in the metadata file, so a field can contain {id} too. The reason for the design is that a large number of tokens can share one on-chain string.

OpenZeppelin's base ERC1155 contract follows the same model. Its API documentation says the default uri() returns the same URI for all token types and relies on the ID substitution mechanism, so clients must replace the {id} substring. OpenSea's metadata standards page shows the same pattern for ERC-1155 with an IPFS address, ipfs://bafy.../{id}.json, and the same 314592 example.

Why This Breaks on IPFS

On a conventional server, a rewrite rule can map any padded ID to a file. IPFS has no rewrite layer. A path like ipfs://<FOLDER_CID>/<name> resolves only if a file with exactly that name exists in the pinned directory. So a folder that holds 1.json, 2.json, and 3.json looks reasonable and fails, because the client asks for the 64-character name.

These are the mistakes that show up most often:

  • Naming files in decimal (1.json) because the token ID is easy to read that way
  • Using hex without padding (4cce0.json)
  • Padding to the right length but writing uppercase letters, or keeping a 0x prefix
  • Putting the {id} in the contract URI and forgetting the .json extension in the file names, or the reverse
  • Pinning the folder's contents as individual files, so no directory CID exists to put in the URI

The EIP requires clients to request the padded form. Some tutorials show shortcuts that appear to work on one marketplace, so follow the spec and test on each client you care about.

A Working Folder Layout

The layout is one metadata folder, one images folder, and file names generated from the token IDs:

metadata/
  0000000000000000000000000000000000000000000000000000000000000001.json
  0000000000000000000000000000000000000000000000000000000000000002.json
  0000000000000000000000000000000000000000000000000000000000000003.json
images/
  1.png
  2.png
  3.png

Pin the images folder first, because its CID goes into every metadata file. AIOZ Pin's Node.js SDK pins a folder with pinFolderToIPFS, and the documentation says it returns the CID of the directory, so you can link to each file by name as the path part of an IPFS URI:

import AIOZPinClient from '@aioznetwork/aioz-pin-sdk'

const client = new AIOZPinClient(process.env.AIOZ_PIN_API_KEY, process.env.AIOZ_PIN_SECRET_KEY)
const options = { metadata: { name: 'game-items-images' } }

const images = await client.pinFolderToIPFS({ sourcePath: './images', options })
console.log(images) // note the directory CID

Generate the metadata file names instead of typing them. This script builds the padded name with BigInt and writes one JSON file per token, using the images CID from the previous step:

import fs from 'fs'

const IMAGES_CID = '<IMAGES_FOLDER_CID>'
const hexId = (id) => BigInt(id).toString(16).padStart(64, '0')

fs.mkdirSync('metadata', { recursive: true })
for (let id = 1; id <= 3; id++) {
  const metadata = {
    name: `Item #${id}`,
    description: 'Example item',
    image: `ipfs://${IMAGES_CID}/${id}.png`,
  }
  fs.writeFileSync(`metadata/${hexId(id)}.json`, JSON.stringify(metadata, null, 2))
}

hexId(314592) returns 000000000000000000000000000000000000000000000000000000000004cce0, the same string as the EIP's example. The images keep short names, because the image field holds a plain path and is only substituted if you put {id} in it.

Then pin the metadata folder the same way, with sourcePath: './metadata', and take its directory CID. Using OpenZeppelin's ERC1155, that CID goes into the constructor:

contract GameItems is ERC1155 {
    constructor() ERC1155("ipfs://<METADATA_FOLDER_CID>/{id}.json") {}
}

Replace <METADATA_FOLDER_CID> with the directory CID of the metadata pin. Every token ID then resolves to its own padded file, and the contract stores a single string.

The Per-Token Alternative

If the folder approach does not fit, ERC-1155 also allows a different URI for each token. OpenZeppelin's ERC1155URIStorage extension provides storage-based token URI management, with _setURI(tokenId, tokenURI) for one token and _setBaseURI(baseURI) for a shared prefix. Each token then points at its own CID, and the {id} rule and file naming no longer apply.

The trade-off is that you store a value on-chain for every token rather than one for the collection. This pattern also matches how AIOZ Pin's NFT API works: creating an NFT uploads an asset and a metadata JSON together and returns an asset_cid and a metadata_cid for that one NFT, which suits a per-token URI. The AIOZ Pin tutorial on ERC-1155 metadata uses the same flow and builds an ipfs:// URI from the metadata CID.

Changing Metadata Later

A folder has one CID, and a CID is derived from the content. Fix a typo in a single file and the folder gets a new CID, so the URI in your contract no longer matches the corrected folder. The old folder still resolves for as long as someone keeps it pinned, which is the property that makes IPFS metadata trustworthy and the reason updates need a plan.

A base ERC1155 keeps its URI in an internal _setURI(newuri) function, so a contract that may need to change the folder must expose a restricted function that calls it. Decide this before launch. If the collection should be permanently fixed, pin the final folder and leave it. Either way, the folder has to stay pinned, because metadata that nobody hosts returns nothing, whatever the contract says.

Frequently Asked Questions

Does ERC-1155 use tokenURI or uri? ERC-1155 uses uri(uint256 id). The tokenURI(uint256) function belongs to ERC-721, and OpenSea reads whichever of the two matches the token standard.

What does {id} mean in an ERC-1155 URI? It is a placeholder that clients replace with the token ID in lowercase hexadecimal, without a 0x prefix, zero-padded to 64 characters.

Why does my ERC-1155 metadata return 404 on IPFS? The most likely cause is that the files in the pinned folder are not named with the 64-character hex ID, so the path the client builds does not exist in the folder.

Can I use one metadata file for every token? Yes. If the URI contains no {id}, every token resolves to the same file, which suits collections where all tokens share the same metadata.

Do I need a folder CID or can I pin files one by one? Pinning files one by one gives each its own CID and no common folder, so there is nothing to put before {id}. Use a folder for the {id} pattern, or use per-token URIs for individually pinned files.

What happens if I change one metadata file? The folder gets a new CID. You then need to update the contract's URI, and the old folder stays reachable only while it remains pinned.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

ERC-1155 Metadata on IPFS: The ID Substitution Rule

ERC-1155 metadata on IPFS breaks when filenames ignore the {id} rule. Here is the exact 64-character format, a working folder layout, and the per-token option.

6 min readOctober 21, 2026
blog thumbnail

AIOZ Pin Rate Limits: API, Public, and Premium Gateways

AIOZ Pin rate limits in one place: 180 requests per minute for the API, 15 per CID on the public gateway, and no predefined limit on premium gateways.

6 min readOctober 19, 2026
blog thumbnail

IPFS Pin Stuck on Pinning? What Each Pin Status Means

IPFS pin stuck on Pinning? Here is what Pinning, Pinned, and Failed mean on AIOZ Pin, why big directories can sit there, and how to read a pin's real state.

6 min readOctober 16, 2026
blog thumbnail

Why IPFS Used to Give You Different CIDs for the Same File

Two identical files, three IPFS tools, three different CIDs. Here is why that happened for years, and how IPIP-0499 made content addressing deterministic.

5 min readOctober 14, 2026
blog thumbnail

AIOZ Pin MCP Server Setup: llms.txt and 11 Tools Guide

AIOZ Pin MCP server setup has two paths: llms.txt lets a super intelligence assistant read the API, the MCP server lets it call 11 tools. Here is each one.

6 min readOctober 12, 2026
blog thumbnail

AIOZ Pin Pricing: The Complete Cost Breakdown

AIOZ Pin bills three flat rates against a token wallet, with no tiers to pick between. Here is what storage, bandwidth and pinned files cost, with examples.

5 min readOctober 09, 2026