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 example shows 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": [ ... ]
}

The following table defines each property:

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 at least a 480x480-pixel image with the file size of up to 8 MB. 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. Must end with .html. Note: 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 appears underneath each item.

You can use one of the 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.
  • Use either an attributes array or a properties object, not both at the same time.

Note: Mavis Market ignores any attributes with incorrect value types. For example, if you define display_type as number, but pass a string in value, the attribute is ignored.

The following image shows one of the Mavis Market items that uses attributes for custom metadata:

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

{
"name": "Mavis #0001",
"description": "Step into the world of birds and join Mavis.",
"external_url": "https://marketplace.skymavis.com/mavis/birdDetail/?birdId=0001",
"image": "https://marketplace.skymavis.com/birds/Mavis_0_1.jpg",
"attributes": [
{
"display_type": "string",
"trait_type": "Planet Class",
"value": "the fury"
},
{
"display_type": "string",
"trait_type": "Planet Type",
"value": "forestry"
},
{
"display_type": "number",
"trait_type": "Conjunction Count",
"value": 2
},
{
"display_type": "date",
"trait_type": "Born Time",
"value": 1679938000
},
{
"display_type": "number",
"trait_type": "Element-Air",
"value": 42
},
{
"display_type": "number",
"trait_type": "Element-Earth",
"value": 31
},
{
"display_type": "number",
"trait_type": "Element-Fire",
"value": 0
},
{
"display_type": "number",
"trait_type": "Element-Water",
"value": 27
},
{
"display_type": "string",
"trait_type": "Bloodline",
"value": "tri"
},
{
"display_type": "number",
"trait_type": "Generation",
"value": 1
}
]
}
About the use of nested attributes

When structuring your metadata, place all traits combined on the root level of the attributes key or properties key, depending on the convention that you use.

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 want the trait to be displayed on Mavis Market. The system calculates 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. 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 displays all your NFT traits as strings.

{
"name": "Mavis #0001",
"description": "Step into the world of birds and join Mavis.",
"image": "https://marketplace.skymavis.com/birds/Mavis_0_1.jpg",
"properties": {
"Planet Class": "the fury",
"Planet Type": "forestry",
"Conjunction Count": 2,
"Born Time": 1679938000,
"Element-Air": 42,
"Element-Earth": 31,
"Element-Fire": 0,
"Element-Water": 27,
"Bloodline": "tri",
"Generation": 1
}
}

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, but you need to enclose the value in quotes and keep the attributes human-readable.

Use either this:

{
"trait_type": "Planet Class",
"value": "the fury"
},

Or this:

{
"display_type": "string",
"trait_type": "Planet Class",
"value": "the fury"
},

The following image shows string traits on the NFT details page:

Bool traits

For "true" or "false" traits, Mavis Market supports a bool display type:

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

The following image shows a filter for "true" or "false" traits 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.

When defining numeric traits, format the values as either floats or integers.

{
"display_type": "number",
"trait_type": "Element-Earth",
"value": 18
},
{
"display_type": "number",
"trait_type": "Element-Fire",
"value": 24
},
{
"display_type": "number",
"trait_type": "Element-Water",
"value": 29
}

The following image shows numeric traits with max values on the NFT details page:

While the following images shows 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": 1701167938
},
{
"display_type": "date",
"trait_type": "Expiration Date",
"value": 1732703938
},

The following image shows date traits on the NFT details page:

While the following image illustrates a filter for dates on the NFT collection page:

Trait grouping

Mavis Market offers an optional capability to group your NFT traits into different categories and display them in a pre-defined order on the NFT details page. This feature is useful when you have a large number of traits and want to organize them in a more structured way.

Custom trait grouping

Key things to know when defining custom trait groups:

  • All traits are placed in the "Properties" section on the NFT details page.
  • If a trait type isn't found in any group, it's placed in the "Others" category within the "Properties" section.
  • The name of each trait in the grouping array must match the trait_type in the attributes array of your NFT's metadata.
  • A trait type can belong to only one trait group. If you add a trait type to more than one group, Mavis Market selects its first occurrence.

The following image shows how Mavis Market displays traits with custom grouping:

The JSON file used to define the custom grouping looks like this:

{
"name": "About",
"traits": [ {"name": "Planet Class"}, {"name": "Planet Type"}, {"name": "Conjunction Count"}, {"name": "Born Time"} ]
},
{
"name": "Element's Value",
"traits": [ {"name": "Element-Air"}, {"name": "Element-Earth"}, {"name": "Element-Fire"}, {"name": "Element-Water"} ]
}

To define trait groups for your assets, create a JSON array in the following format and submit it as part of your NFT collection's information:

[
{
"name": "<YOUR FIRST GROUP>",
"traits": [
{
"name": "<FIRST GROUP - FIRST TRAIT>"
},
{
"name": "<FIRST GROUP - SECOND TRAIT>"
},
{
"name": "<FIRST GROUP - THIRD TRAIT>"
},
{
"name": "<FIRST GROUP - FORTH TRAIT>"
}
]
},
{
"name": "<YOUR SECOND GROUP>",
"traits": [
{
"name": "<SECOND GROUP - FIRST TRAIT>"
},
{
"name": "<SECOND GROUP - SECOND TRAIT>"
}
]
},
...
]

Default trait grouping

If you don’t provide any custom grouping, Mavis Market still places all traits in the "Properties" section on the NFT details page. Within that section, the traits are further organized as follows:

  • Any strings, dates, and boolean trait types are placed in the "Traits" category and sorted alphabetically.
  • Any numeric trait types are added to the "Others" category, also sorted alphabetically.

The following image shows how Mavis Market displays traits without custom grouping:

Metadata deployment

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

caution

Refrain from using bot prevention on the server where you host your metadata. Mavis Market relies on fetching metadata from the server to index data and allow searching across the collection.

Metadata refresh

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...