NFT Metadata File Schema

The NFT spec calls for a metadata URL that can be used to store additional metadata off chain. In order to maximize wallet and marketplace support for these metadata files we would like to standardize on a format. This format should contain a standard set of properties and allow for custom additions.

The current thinking is to use JSON encoded files for this off chain metadata. This format should be easily consumable by web based marketplaces as well as native desktop/mobile wallets.

The follow JSON schema is the current proposal for this metadata file:

{
  "title": "This is the title of the NFT",
  "description": "This is a long description for the NFT",
  "attributes": ["attribute1", "attribute2", ..., "attributeX"]
}

These should cover most of the data commonly displayed by NFT galleries but we would like suggestions on additional fields or file formats that may be useful.

2 Likes

What if you want key-value metadata, or more complex objects? Such as “sharpness” on an ingame sword item.

Yes, so my thinking was that these would be the standard fields, but that any other arbitrary data could be put in the JSON file.

I wondered if the attributes should be more than simple strings, maybe we should consider objects instead of strings:

  "attributes": [
    {
      "name": "sharpness",
      "value": 0.5,
    }
  ]
5 Likes

Yeah attributes like that make sense imo

Agreed, name/value is much more versatile than just a named attribute.

1 Like

Any specific reason why you used title instead of name?
Is that something where we want to be consistent with other ecosystems?
At least ERC-1155 and Solana call that field name.

Regarding the attributes, I’m not sure whether to prefer a nested object or an array of objects. If the values are always key/value pairs I’d prefer a nested object like this:

  "description": "This is a long description for the NFT",
  "attributes": {
    "sharpness": 0.5
  }
}

What would be the advantage of an array of objects?

1 Like

Good point on name vs title. We can go with name.

On attributes, I could go either way. An array of objects felt a little more future proof so I went with that, since you could have more properties than just value. However, I don’t have a use case for that in mind so maybe its not worth the extra space.

So for collections, I like the suggestion of having a name and an ID.
I think the current draft is a bit too pythonic.

{
    "name": "Donatello",
    "description": "The smart one",
    "collection_name": "Ninja Turtles",
    "collection_id": "49B83117-3C25-4848-AD9C-A57F320F90C5"
}

I would suggest

{
  "name": "Donatello",
  "description": "The smart one",
  "collection": {
    "name": "Ninja Turtles",
    "id": "49B83117-3C25-4848-AD9C-A57F320F90C5"
  }
}

No objection here to the suggested “collection” object change mentioned above.

Here’s the off-chain metadata that was referenced:

{
    "name": "Donatello",
    "description": "The smart one",
    "collection_name": "Ninja Turtles",
    "collection_id": "49B83117-3C25-4848-AD9C-A57F320F90C5",
    "attributes": [
        {
            "trait_type": "Headband Color",
            "value": "Purple",
        },
        {
            "trait_type": "Weapon",
            "value": "Bo Staff"
        },
        {
            "trait_type": "Strength",
            "value": 80,
            "min_value": 0,
            "max_value": 100
        },
        {
            "trait_type": "Intelligence",
            "value": 95,
            "min_value": 0,
            "max_value": 100
        },
        {
            "trait_type": "Agility",
            "value": 40,
            "min_value": 0,
            "max_value": 100
        },
    ]
}
1 Like

Can the collection change into JSON objects as @acevail suggested?

"collection": {
    "name": "Ninja Turtles",
    "id": "49B83117-3C25-4848-AD9C-A57F320F90C5"
  }

Yes, we’re updating to the “collection” object suggestion.

1 Like

Some ideas:

version of the schema used

"version": "1.0"

array of json objects (no limit to nested objects)

"data": [{         
}],

Update policy link (policy defines how this metadata is allowed to be altered when it’s token changes ownership)

"update_policy": ""
1 Like

If the structure is changed, it will be easier to read quickly. Scripts can get the UID without parsing all the other values.


{
  "UID": {
    "name": "Donatello",
    "description": "The smart one",
    ...
  }
}
1 Like

Can we add more info sround collection so a artist can provide collection icon and any background Infos.

"collection": {
    "name": "Ninja Turtles",
    "id": "49B83117-3C25-4848-AD9C-A57F320F90C5"
    "icon": "url to the collection icon" 
    "banner":"url to the collection banner"
  }

On the Sunday Twitter space, the below Qs arose:

Q: What will be the best way to identify the minting tool or method used for NFTs?
Q: Should the metadata standard include a minting tool or method?

The answer somewhat relates to what blaktron mentioned in the keybase channel regarding versioning.

Maybe we include an array for minting information in general:

  • note I also included the metadata recommended by grig regarding update policy and jiyun regarding collections
  • updated with description recommended below
{
    "version": {
            "type": "offchain-metadata"
            "standard": "NFT1"
            "minting_tool": "link or name of minting tool"
            "update_policy": "link to the update policy"
        }
    "name": "Donatello",
    "description": "The smart one",
    "collection": {
           "name": "Ninja Turtles",
           "id": "49B83117-3C25-4848-AD9C-A57F320F90C5"
           "icon": "link to the collection icon" 
           "banner": "link to the collection banner"
           "description":"Collection description "
        }
    "attributes": [
        {
            "trait_type": "Headband Color",
            "value": "Purple",
        },
        {
            "trait_type": "Weapon",
            "value": "Bo Staff"
        },
        {
            "trait_type": "Strength",
            "value": 80,
            "min_value": 0,
            "max_value": 100
        },
        {
            "trait_type": "Intelligence",
            "value": 95,
            "min_value": 0,
            "max_value": 100
        },
        {
            "trait_type": "Agility",
            "value": 40,
            "min_value": 0,
            "max_value": 100
        },
    ]
}

Shall we add a description placeholder for the collection?

"collection": {
           "name": "Ninja Turtles",
           "id": "49B83117-3C25-4848-AD9C-A57F320F90C5"
           "icon": "link to the collection icon" 
           "banner": "link to the collection banner"
           "description":"Collection description "
        }
1 Like

If we make the collection to accept attribute lists then this could be used for icons, banners, and social links.
This flexibility would support collection meta info until we have the on-chain collection and attribute support.

{
  "version": {
    "type": "offchain-metadata",
    "standard": "NFT1",
    "minting_tool": "link or name of minting tool",
    "update_policy": "link to the update policy"
  },
  "name": "Donatello",
  "description": "The smart one",
  "traits": [
    {
      "type": "Headband Color",
      "value": "Purple"
    },
    {
      "type": "Weapon",
      "value": "Bo Staff"
    },
    {
      "type": "Strength",
      "value": 80,
      "min_value": 0,
      "max_value": 100
    },
    {
      "type": "Intelligence",
      "value": 95,
      "min_value": 0,
      "max_value": 100
    },
    {
      "type": "Agility",
      "value": 40,
      "min_value": 0,
      "max_value": 100
    }
  ],
   "collection": {
    "name": "Ninja Turtles",
    "id": "49B83117-3C25-4848-AD9C-A57F320F90C5",
    "attributes": [
      {
        "type": "icon",
        "value": "link to the icon"
      },
      {
        "type": "banner",
        "value": "link to the banner"
      },
      {
        "type": "description",
        "value": "Description text"
      },
      {
        "type": "twitter",
        "value": "twitter handle"
      },
      {
        "type": "website",
        "value": "link to website"
      }
    ]
  }
}

Wouln’t it be better, if the format was

{
"icon":"url",
"banner":"url",
}

Every time i see those type value pairs, i get pain because it’s counter intuitive…

It will be easy for now to have defined objects but if anyone wants to expand for future needs then it will be limited.
It may need a new CHIP and that have to go through the process again to add a new social media link in the future.
Note: The version could be used to add any new links in the future.

So I’m still not convinced that we need attributes for collections.

On the one hand it’s a lot of duplication, if all these attributes have to be stored in the metadata of each NFT that belongs to this collection.
It gets even messier if the collection details vary between different NFTs that seem to belong to the same collection (same creator, same ID, same name)
So one would always have to hash the whole structure to uniquely verify a collection.

My second issue is that things like icons and Twitter links change.
So marketplaces will have to provide ways to update these details afterwards anyway, to correct details that changed since minting.
Banners might also look very different depending on the platform. A mobile marketplace might need a different banner than one that is desktop based.

So I would prefer a more lightweight approach here, since it’s just an interim solution, and leave out the attributes.