Skip to main content

Metadata standards

Overview

Using asset metadata, Mavis Market can incorporate rich data for your NFTs and display it on the NFT collection page and the NFT details page. Because digital assets on smart contracts are usually represented by nothing but a unique identifier, such as tokenId in ERC721, metadata plays a crucial role in enhancing these tokens with additional properties, which includes a name, description, image, and some custom attributes.

How to implement token URI

Metadata is stored off-chain. In order for Mavis Market to pull it for your ERC721 and ERC1155 assets, your contract needs to return a URI where our system can find the metadata. To identify this URI, we use the tokenURI function in ERC721 and the uri function in ERC1155. Whichever standard you follow, the function in your contract should return an HTTP or IPFS URL. When our system queries it, the URL should return a JSON blob of data with the metadata for your token.

Metadata structure

Mavis Market supports metadata that is structured according to the official ERC721 metadata standard or the Enjin Metadata suggestions.

We also support other properties such as images, videos, and animation, as well as interactive traits for your items, which enables sorting and filtering capabilities on the NFT collection page.

The following is an example metadata for one of the assets on Mavis Market:

{
"name": "Carota",
"description": "Carota",
"image": "https://cdn.skymavis.com/mm-cache/5/f/6139f745ad89731b16844a4fee546c.jpg",
"animation_url": "https://viewer.cyberkongz.com/4570",
"attributes": [ ... ]
}

Here’s how these properties work:

PropertyRequired?Description
nameRequiredThe name of the item.
descriptionOptionalA human-readable description of the item.
imageRequiredThe URL of the image of the item. The image is displayed on the NFT collection page. The supported formats are PNG, JPEG, and GIF. We recommend using a minimum 480x480 image with the file size of 8 MB or less. Regardless the resolution, Mavis Market caches and downscales your images to 480x480 pixels.
videoOptionalThe URL of the video of the item. The video is displayed on the NFT details page. The supported formats are MP4 and WEBM. We recommend that you host the video on a CDN instead of directly on the server, otherwise the load speed may be slow. You must provide us domain URL of this video so we can allowlist on Mavis Market otherwise video won't be shown.
external_urlOptionalThe URL to the item’s page on your website. Note: This property is not yet implemented on Mavis Market, so we will store the URL internally until further notice.
attributesOptionalThe attributes for the item that are displayed on Mavis Market. We recommend that you use this property for your NFT metadata, because this enables better sorting and filtering on the NFT collection page, and allows for using specific display types for your traits. Mutually exclusive with properties.
propertiesOptionalThe attributes for the item that are displayed on Mavis Market. Doesn’t support specific display types for your traits, which may limit the filtering experience on the NFT collection page. Mutually exclusive with attributes.
animation_urlOptionalThe URL to a web page with the animation of your item. Note: Ensure that the URL ends with ".html" and provide the domain URL to your Sky Mavis partner engineer so that we can allowlist it.

Metadata display priority

  • On the NFT collection page: the image is displayed.
  • On the NFT details page: the priority of displaying is animation_url > video > image.

Attributes

With Mavis Market, you can add custom attributes to your metadata that will appear underneath each item.

There are two ways to store custom attributes: using an attributes array or a properties object:

  • If you store your custom metadata in the attributes array, you can set the display type for traits, such as string, number, date, and bool. This affects how the trait is displayed on the marketplace.
  • If you store metadata in the properties object, you can use numeric and string values, but Mavis Market will display all your NFT traits as strings.

Here’s an example of one of the Mavis Market items that uses attributes for custom metadata:

To generate these attributes, we stored them in the following way:

{
"name": "Foresty #5188",
"description": "The Foresty Planets are full of the opportunity for adventure; there are mysteries in the hidden glades in the deepwood.",
"external_url": "https://marketplace.apeironnft.com/planet/planetDetail/?planetId=5188",
"image": "https://nftprops.apeironnft.com/planetartworks/Opensea_Planet_Reveal/Foresty_0_3_0_255_1.jpg",
"attributes": [
{
"display_type": "number",
"trait_type": "Conjunction Count",
"value": 2,
"max_value": 3
},
{
"display_type": "date",
"trait_type": "Born Time",
"value": 1660011249
},
{
"display_type": "number",
"trait_type": "Element-Fire",
"value": 0,
"max_value": 100
},
{
"display_type": "number",
"trait_type": "Element-Water",
"value": 27,
"max_value": 100
},
{
"display_type": "number",
"trait_type": "Element-Air",
"value": 42,
"max_value": 100
},
{
"display_type": "number",
"trait_type": "Element-Earth",
"value": 31,
"max_value": 100
},
{
"trait_type": "Planet Class",
"value": "The Fury"
},
{
"trait_type": "Generation",
"value": "1"
},
{
"trait_type": "Planet Type",
"value": "Foresty"
},
{
"trait_type": "Bloodline",
"value": "Tri"
}
]
}
About the use of nested attributes

Mavis Market metadata conventions do not support nested attributes. Therefore, when structuring your metadata, place all traits combined on the root level of the attributes key (or the properties key if you're using that convention).

Recommended:

"attributes": [
{
"display_type": "number",
"trait_type": "Level",
"value": 3
},
{
"display_type": "string",
"trait_type": "Hat",
"value": "Blue Bandana"
},
...

Not recommended:

"attributes": {
"nested_attributes": [
{
"display_type": "number",
"trait_type": "Level",
"value": 3
},
{
"display_type": "string",
"trait_type": "Hat",
"value": "Blue Bandana"
},
...

In the preceding example, the trait_type is the trait's name, the value is the value of the trait, and the display_type is a field indicating how you would like for the trait to be displayed on Mavis Market. The system will calculate the distribution of each trait type’s value automatically, so you don't need to specify it in the metadata, unless it's required for your own logic.

Metadata key compliance

When parsing your NFT metadata, Mavis Market specifically looks for the data stored in the trait_type, value, and display_type keys. Valid metadata is defined as metadata that is stored in accordance with our specifications. Data stored in any other keys is disregarded.

If you store metadata in the properties object, you can use numeric and string values, but Mavis Market will display all your NFT traits as strings.

{
"name": "Foresty #5188",
"description": "The Foresty Planets are full of the opportunity for adventure; there are mysteries in the hidden glades in the deepwood.",
"image": "https://nftprops.apeironnft.com/planetartworks/Opensea_Planet_Reveal/Foresty_0_3_0_255_1.jpg",
"properties": {
"Level": 3,
"Hat": "Blue Bandana",
...
}
}

String traits

For string traits, Mavis Market supports a string display type. When adding string traits, you don't need to explicitly state a display_type.

Use either this:

{
"trait_type": "Planet Type",
"value": "archipelago"
}

Or this:

{
"display_type": "string",
"trait_type": "Planet Type",
"value": "archipelago"
}

Here's how string traits are displayed on the NFT details page:

While the following image is a filter for string traits on the NFT collection page:

Bool traits

For boolean traits, Mavis Market supports a bool display type:

{
"display_type": "bool",
"trait_type": "Protected",
"value": true
}

Here's how bool traits are displayed on the NFT collection page:

Numeric traits

For numeric traits, Mavis Market supports a number display type. You can specify a pair of min and max values or just a single value. The max_value parameter is optional, it sets a ceiling for the possible values for a numeric trait. It defaults to the maximum value that Mavis Market has seen so far on the items in your contract. If you set a max_value, make sure that it doesn’t exceed the value.

{
"display_type": "number",
"trait_type": "Conjunction Count",
"value": 2
},
{
"display_type": "number",
"trait_type": "Element-Air",
"value": 29
},
{
"display_type": "number",
"trait_type": "Element-Earth",
"value": 1
},
{
"display_type": "number",
"trait_type": "Element-Fire",
"value": 24
},
{
"display_type": "number",
"trait_type": "Element-Water",
"value": 29
},

Here’s how numeric traits with max values are displayed on the NFT details page:

While the following image is a filter for numeric traits on the NFT collection page:

Date traits

For dates, Mavis Market supports a date display type. Pass in a Unix timestamp (in seconds) as the value.

{
"display_type": "date",
"trait_type": "Created Date",
"value": 1701129600
},
{
"display_type": "date",
"trait_type": "Expiration Date",
"value": 1732665600
},

Here’s how date traits are displayed on the NFT details page:

While the following image is a filter for date traits on the NFT collection page:

Attribute guidelines

  • Include string attributes as strings (enclosed in quotes), and numeric attributes as either floats or integers, so that Mavis Market can display them correctly. String properties should be human-readable strings.
  • To store your NFT attributes, use either an attributes array or a properties object. Not both at the same time.
  • Mavis Market will ignore an attribute if you pass the wrong type of value. For example, you define display_type as a number but your value is a string type:
{
"display_type": "number",
"trait_type": "generation",
"value": "2"
}

Metadata deployment

You can deploy your metadata however you see fit: host it on IPFS, cloud storage, or your own servers.

caution

The server responsible for deploying metadata should refrain from using bot prevention. This is because Mavis Marketplace relies on fetching metadata from the server to index data and allow searching across the collection.

Metadata updates

To refresh token metadata on Mavis Market, you can emit on-chain events as defined in ERC-4906:

event MetadataUpdate(uint256 _tokenId);
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);

To refresh a whole collection, emit a _toTokenId with the type(uint256).max.

Alternatively, you can make a request to the Mavis Market API. The following is an example call to request a metadata refetch:

curl 'https://marketplace-graphql.skymavis.com/graphql' \
-H 'content-type: application/json' \
--data-raw $'{"operationName":"RefreshMetadata","variables":{"tokenAddress":"0x1f7c16fce4fc894143afb5545bf04f676bf7dcf3","tokenId":"6545"},"query":"mutation RefreshMetadata($tokenAddress: String\u0021, $tokenId: String\u0021) {\\n refreshMetadata(tokenAddress: $tokenAddress, tokenId: $tokenId)\\n}\\n"}' \
--compressed
note

If your new metadata alters the display_type of the existing trait_type, inform your Sky Mavis partner engineer to perform the update.

Was this helpful?
Happy React is loading...