Skip to main content

Metadata standards

Overview

Using asset metadata, Mavis Market can incorporate rich data for your NFTs and display it on the collection page and the token details page. Because digital assets on smart contracts are usually represented by nothing but a unique identifier, such as tokenId in ERC-721, 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 ERC-721 and ERC-1155 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 ERC-721 and the uri function in ERC-1155. 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 ERC-721 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 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.gif",
"animation_url": "https://viewer.cyberkongz.com/4570.html",
"attributes": [ ... ]
}

The following table defines each property:

PropertyRequired?Description
nameRequiredThe name of the item.
descriptionOptionalA human-readable description of the item.
imageRequiredA URL to an image of the item. This image is displayed on the collection page and token detail page if the video and animation_url properties are empty. Supports PNG, JPEG, and GIF formats. Use at least a 480x480-pixel attachment with the size of up to 1 MB. Regardless the resolution, Mavis Market caches and downscales your images to 480x480 pixels.
videoOptionalA URL to a video of the item. This video is displayed on the details page. Supports MP4 and WEBM formats. Use at least a 480x480-pixel video with the size of up to 1 MB. Host the video on a CDN instead of directly on the server, otherwise the load speed may be slow. Note: To prevent issues with video display, share the CDN URL with your Sky Mavis point of contact so we can allowlist it.
external_urlOptionalA URL to an item's webpage on your site. Note: This property is not yet live on Mavis Market, so we store the URL internally until further notice.
attributesOptionalOne of the two ways to store attributes for an item, mutually exclusive with properties. We recommend that you use this property for your NFT metadata, because this enables better sorting and filtering on the collection page, and allows using specific display types for your traits.
propertiesOptionalOne of the two ways to store attributes for an item, mutually exclusive with attributes. Doesn't support specific display types for your traits, which may limit the filtering experience on the collection page.
animation_urlOptionalA URL to an HTML page with any rich media content, such as an interactive animation of the item. This attachment is displayed on the token details page. For more details, see an example video. Note: Share the domain name with your Sky Mavis point of contact so we can allowlist it.

Metadata display priority

  • On the collection page: the image is displayed.
  • On the token details page: animation_url > video > image.
  • If the animation_url and video are empty, the image is displayed on the collection page and the token details page.
GIF attachments

If you use a GIF attachment, fill it in the image property, not in the animation_url property.

Attributes

You can add custom attributes to your metadata that appears 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.
  • 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 token 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 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 token details page:

While the following images shows a filter for numeric traits on the 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 token details page:

While the following image illustrates a filter for dates on the 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 token 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 token 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 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 token 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 use one of the following methods:

Emit on-chain events

Emit on-chain events as defined in ERC-4906:

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

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

GraphQL API

Make a request to the Mavis Market GraphQL API.

Example request:

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

REST API

Make a request to the Refresh NFT metadata endpoint to refresh the metadata of up to 100 tokens at a time.

Example request:

curl --location --request POST 'https://api-gateway.skymavis.com/mavis-market-partner/collections/0xa899849929e113315200609be208e6a0858f645c/refresh_metadata' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: YOUR_API_KEY' \
--data-raw '{
"token_ids": ["1", "2", "3", "4", "5", "6"]
}'
note

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