---
eip: 4906
title: EIP-721 Metadata Update Extension
description: Add a MetadataUpdate event to EIP-721.
author: Anders (@0xanders), Lance (@LanceSnow), Shrug <shrug@emojidao.org>, Nathan <nathan.gang@gemini.com>
discussions-to: https://ethereum-magicians.org/t/eip4906-erc-721-erc-1155-metadata-update-extension/8588
status: Final
type: Standards Track
category: ERC
created: 2022-03-13
requires: 165, 721
---

## Abstract

This standard is an extension of [EIP-721](./eip-721.md). It adds a `MetadataUpdate` event to EIP-721 tokens.

## Motivation

Many [EIP-721](./eip-721.md) contracts emit an event when one of its tokens' metadata are changed. While tracking changes based on these different events is possible, it is an extra effort for third-party platforms, such as an NFT marketplace, to build individualized solutions for each NFT collection.

Having a standard `MetadataUpdate` event will make it easy for third-party platforms to timely update the metadata of many NFTs.

## Specification

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

The **metadata update extension** is OPTIONAL for EIP-721 contracts.


```solidity
/// @title EIP-721 Metadata Update Extension
interface IERC4906 is IERC165, IERC721 {
    /// @dev This event emits when the metadata of a token is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFT.
    event MetadataUpdate(uint256 _tokenId);

    /// @dev This event emits when the metadata of a range of tokens is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFTs.    
    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}
```

The `MetadataUpdate` or `BatchMetadataUpdate` event MUST be emitted when the JSON metadata of a token, or a consecutive range of tokens, is changed.

Not emitting `MetadataUpdate` event is RECOMMENDED when a token is minted.

Not emitting `MetadataUpdate` event is RECOMMENDED  when a token is burned.

Not emitting `MetadataUpdate` event is RECOMMENDED  when the tokenURI changes but the JSON metadata does not.

The `supportsInterface` method MUST return `true` when called with `0x49064906`.

## Rationale

Different NFTs have different metadata, and metadata generally has multiple fields. `bytes data` could be used to represents the modified value of metadata.  It is difficult for third-party platforms to identify various types of `bytes data`, so as to avoid unnecessary complexity, arbitrary metadata is not included in the `MetadataUpdate` event.

After capturing the `MetadataUpdate` event, a third party can update the metadata with information returned from the `tokenURI(uint256 _tokenId)` of EIP-721. When a range of token ids is specified, the third party can query each token URI individually.

## Backwards Compatibility

No backwards compatibility issues were found

## Reference Implementation

```solidity
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./IERC4906.sol";

contract ERC4906 is ERC721, IERC4906 {

    constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {
    }

    /// @dev See {IERC165-supportsInterface}.
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);
    }
}
```

## Security Considerations

If there is an off-chain modification of metadata, a method that triggers `MetadataUpdate` can be added, but ensure that the function's permission controls are correct.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
