Skip to main content
The Xpectrum Metadata Standard v1.0 defines the JSON that describes a token and a collection. It is deliberately self-describing (a token renders from its own JSON without fetching the collection) and provenance-friendly (every byte that matters is covered by the provenance hash). This page is the practical reference. If your folder passes xpress check, it conforms.

Layout

A collection lives in one Circle. Files use a fixed path convention:
The collection JSON URI is derived from the token URI (swap the filename for collection.json); there is no collection_uri field.

Token metadata ([token_id].json)

Each attribute is { "trait_type": string, "value": string | number }, with optional id and display_type. Rules: value is always present and human-readable; max 32 attributes; a trait_type appears at most once per token. Royalty fields must never appear in JSON; royalties are on-chain only.

Collection metadata (collection.json)

The on-chain provenance_hash is not mirrored here (that would be circular). It lives only on-chain.

Render types

  • composed: the token’s image is composited at display time from trait layers, ordered by each trait_types[].layer_order (lower renders first). Token JSONs carry no image.
  • prerendered: each token JSON points at a finished image asset.

Mutability

Collections launched on Xpectrum are frozen_by_provenance: set_provenance_hash() has been called, the collection is immutable on-chain, and indexers may cache it indefinitely. This is the only mode the Launchpad offers.
The standard reserves a "mutable" value for collections that keep write access open, but Xpectrum does not currently offer it. Treat frozen_by_provenance as the expected value.

Provenance hash

For a frozen collection, the hash is built over the exact stored bytes in a canonical order:
N is max_supply (all token JSONs must exist before freezing). ipfs:// media is not byte-hashed because the CID inside the JSON is already a content hash; https:// media is not allowed in a frozen collection. Avatar and banner are excluded. See Provenance for the verification flow.

Examples

Complete, copy-ready examples covering both render types and every supported field. A renderer that handles these handles the standard.

Composed collection

The collection declares trait_types with layer_order; each token lists its attributes and the renderer composites the trait layers bottom-to-top. Token JSONs carry no image. collection.json
42.json (one token)
The renderer composites these layers, ordered by each trait’s layer_order (bottom to top):
Trait layer paths are traits/[trait_slug]/[value_slug].png, where the slug lowercases and hyphenates the names ("Hollow Gold" becomes hollow-gold).

Prerendered collection

Each token points at a finished image. trait_types is optional (include it only to give indexers nicer filter labels). This example also shows external_url and display_type on attributes. collection.json
7.json (one token)

Notes for renderers and wallets

  • A token is fully renderable from its own JSON. For composed tokens, fetch collection.json once for layer_order; everything else is in the token.
  • display_type: "date" is Unix seconds; display_type: "number" renders the raw numeric value.
  • external_url is an informational webpage link only. Never fetch display media from it.
  • animation_uri is reserved for video/audio/3D/HTML. Preserve and surface it; a poster image should accompany it when present.
  • Resolve oct://[circle_id]/[path] by reading the asset from that circle on-chain. ipfs:// resolves through any IPFS gateway.