Skip to main content
The metadata standard covering NFTs, NFT collections, and jettons is outlined in TEP-64 (TON Enhancement Proposal 64). On TON, entities can have three types of metadata: on-chain, semi-chain, and off-chain.
  • On-chain metadata: stored on the blockchain, including name, attributes, and image.
  • Off-chain metadata: stored via a link to a metadata file hosted off-chain.
  • Semi-chain metadata: a hybrid approach that stores small fields (e.g., name or attributes) on-chain, while hosting the image off-chain and storing only a link to it.

Snake data encoding

The Snake encoding allows a portion of data to be stored in a standardized cell, with the remainder stored recursively in child cells. In this scheme, Snake-encoded data is typically prefixed with the 0x00 byte (see the note below for exceptions). TL-B schema:
TL-B
Read more about similar examples. When the payload exceeds the maximum size of a single cell, Snake stores the remaining data in child cells. Part of the data is placed in the root cell, and the rest in the first child cell, continuing recursively until all data is stored. Below is an example of Snake encoding and decoding in TypeScript:
TypeScript
The 0x00 byte prefix is not always required in the root cell when using Snake, for example, with off-chain NFT content. Also, cells are filled with bytes rather than bits to simplify parsing. To avoid issues when adding a reference in a child cell after it has already been written to its parent, the Snake cell is constructed in reverse order.

Chunked encoding

The chunked encoding stores data in a dictionary that maps chunk_index to a chunk. Chunked encoding must be prefixed with the 0x01 byte. This in-structure marker is distinct from the top-level content marker 0x01 that indicates off-chain content. TL-B schema:
TL-B
Below is an example of chunked data decoding in TypeScript:
TypeScript

NFT metadata attributes

Jetton metadata attributes

amount_style

  • n — number of jettons (default). If the user has 100 tokens with 0 decimals, display 100.
  • n-of-total — the number of jettons out of the total issued. For example, if the totalSupply is 1000 and the user has 100, display “100 of 1000” (or an equivalent representation of the ratio).
  • % — the percentage of total issued jettons. For example, with a total of 1000 and a user balance of 100, display 10% (100 ÷ 1000 = 0.1).

render_type

  • currency — display as a currency (default).
  • game — game-style display that appears as an NFT, shows the number of tokens, and respects amount_style.

decimals

The decimals parameter defines the number of decimal places for displaying token amounts. The on-chain balance is stored as an integer in the smallest unit (nano-tokens), and must be divided by 10^decimals to get the user-facing value. Common values:
  • Most jettons use decimals: 9 (default when not specified)
  • USDT uses decimals: 6
Example: If the on-chain balance is 1000000000 nano-tokens:
  • With decimals: 9 → displayed as 1.0 token
  • With decimals: 6 → displayed as 1000.0 tokens
When transferring jettons programmatically, the amount must be calculated as: on_chain_amount = display_amount × 10^decimals. For example, to transfer 1 USDT (decimals: 6):
  • Correct on-chain amount: 1 × 10^6 = 1000000
  • Incorrect (using default 9): 1 × 10^9 = 1000000000 (transfers 1000 USDT instead of 1)

Parsing metadata

To parse metadata, first retrieve the NFT data from the blockchain. For details, see retrieving NFT data. After the on-chain NFT data is retrieved, determine the content type by reading the first byte of the content, then parse accordingly.

Off-chain

If the metadata byte string starts with 0x01, the content is off-chain. Decode the remainder using Snake as an ASCII string to obtain the URL. Once you fetch the off-chain metadata and identification data, the process is complete. Example URL for off-chain NFT metadata: https://s.getgems.io/nft/b/c/62fba50217c3fe3cbaad9e7f/95/meta.json Contents of the referenced URL:
json

On-chain and semi-chain

If the metadata byte string starts with 0x00, it indicates on-chain or semi-chain NFT metadata. The metadata is stored in a dictionary where the key is the SHA-256 hash of the attribute name, and the value is data stored using the Snake or chunked format. Read known attributes such as uri, name, image, description, and image_data. If the uri field is present, the layout is semi-chain: download the off-chain content specified by uri and merge it with the dictionary values. Examples: On-chain NFT: EQBq5z4N_GeJyBdvNh4tPjMpSkA08p8vWyiAX6LNbr3aLjI0 Semi-chain NFT: EQB2NJFK0H5OxJTgyQbej0fy5zuicZAXk2vFZEDrqbQ_n5YW On-chain jetton master: EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs

How to parse

Use the following API to parse metadata: API Metadata. It handles most cases within gas limits; in rare cases, parsing may fail.

Important notes on NFT metadata

  1. For NFT metadata, the name, description, and image (or image_data) fields are commonly used to display the NFT.
  2. For jetton metadata, the name, symbol, decimals, and image (or image_data) fields are commonly used.
  3. Anyone can create an NFT or jetton using any name, description, or image. To prevent scams and confusion, apps should clearly distinguish tokens by their address rather than by names or tickers.
  4. Some items may include a video field linking to video content associated with the NFT or jetton.

References