Skip to content

Token metadata

The JSON schema behind every Asteria token.

  • 4 min read
  • Page 12 of 24

Every Asteria token points to a JSON document that describes it. The format follows the ERC-721 metadata convention that wallets and marketplaces already read, and adds a namespaced asteria block holding the complete registry record. This page documents schema version 1.0.0, field by field.

Schema version
1.0.0
Semantic versioning
Format
JSON, UTF-8
Served via tokenURI
Standard
ERC-721 metadata
Plus an asteria namespace
Hosting
IPFS (planned)
Content-addressed, versioned

A live example#

The document below is generated by the same function that will produce launch metadata, applied to Vesperine (ASR-0001) from the preview catalogue. Values are demo data until verification.

ASR-0001.json
{
  "name": "Vesperine (ASR-0001)",
  "description": "The first light after dusk. A stony wanderer of the middle belt, bright enough to catch the Sun like a struck match. Vesperine opens the Asteria registry — the first entry, the first name. Registry name assigned by Asteria; not an IAU-recognised name. This token is a digital collectible and confers no ownership of any celestial body.",
  "image": "ipfs://<cid>/ASR-0001.png",
  "animation_url": "ipfs://<cid>/ASR-0001.mp4",
  "external_url": "https://asteriaasteroids.xyz/explore/vesperine",
  "attributes": [
    {
      "trait_type": "Spectral class",
      "value": "S-type"
    },
    {
      "trait_type": "Orbit class",
      "value": "Middle main belt"
    },
    {
      "trait_type": "Tier",
      "value": "Celestial"
    },
    {
      "trait_type": "Near-Earth object",
      "value": "No"
    },
    {
      "trait_type": "Diameter (km)",
      "value": 3.8,
      "display_type": "number"
    },
    {
      "trait_type": "Albedo",
      "value": 0.24,
      "display_type": "number"
    },
    {
      "trait_type": "Rotation period (h)",
      "value": 5.6,
      "display_type": "number"
    },
    {
      "trait_type": "Orbital period (yr)",
      "value": 4.29,
      "display_type": "number"
    }
  ],
  "asteria": {
    "schema_version": "1.0.0",
    "registry_id": "ASR-0001",
    "registry_name": "Vesperine",
    "name_meaning": "From the Latin vesper — the evening star, the first light after sunset.",
    "official_designation": null,
    "spectral_class": "S",
    "orbit": {
      "orbit_class": "Middle main belt",
      "semi_major_axis_au": 2.64,
      "eccentricity": 0.11,
      "inclination_deg": 7.2,
      "perihelion_au": 2.35,
      "aphelion_au": 2.93,
      "period_years": 4.289
    },
    "physical": {
      "diameter_km": 3.8,
      "geometric_albedo": 0.24,
      "rotation_period_h": 5.6,
      "absolute_magnitude_h": 14.27
    },
    "data_sources": [
      "To be linked on verification: JPL Small-Body Database, Minor Planet Center"
    ],
    "disclaimer": "Registry name only; not an official IAU designation. No property right in any celestial body is conveyed."
  }
}

Structure#

Shape of a v1.0.0 document
name, description, image, animation_url, external_url
attributes[8]           display traits for wallets and marketplaces
asteria
├── schema_version, registry_id, registry_name, name_meaning
├── official_designation, spectral_class
├── orbit               orbital elements + derived values
├── physical            size, albedo, rotation, magnitude
└── data_sources[], disclaimer

Top-level fields#

These are the fields every ERC-721 wallet and marketplace looks for.

FieldTypeDescriptionVesperine
namestringRegistry name followed by the registry ID in parenthesesVesperine (ASR-0001)
descriptionstringTagline, story, then a fixed sentence stating that the name is not IAU-recognised and the token confers no ownership of any celestial body"The first light after dusk. A stony wanderer…"
imageURICertificate still imageipfs://<cid>/ASR-0001.png
animation_urlURIAnimated certificate (MP4)ipfs://<cid>/ASR-0001.mp4
external_urlURLThe asteroid's page on the Asteria site…/explore/vesperine
attributesarrayEight display traits, listed below—

<cid> is a placeholder in preview output. It is replaced by a real IPFS content identifier when the media are pinned.

Attributes#

Each trait is an object with trait_type and value. Numeric traits add display_type: "number" so marketplaces can render them as numbers rather than labels.

trait_typeValuedisplay_typeDerivationVesperine
Spectral classstring—Class name, e.g. "S-type"S-type
Orbit classstring—Classified from a, e and iMiddle main belt
Tierstring—Genesis, Celestial or SovereignCelestial
Near-Earth object"Yes" or "No"—True for Atira, Aten, Apollo and Amor orbitsNo
Diameter (km)number, 2 dpnumberStored value3.8
Albedonumber, 2 dpnumberGeometric albedo0.24
Rotation period (h)number, 1 dpnumberStored value5.6
Orbital period (yr)number, 2 dpnumberDerived from a4.29

Attribute values are rounded for display. The full-precision record lives in the asteria block.

The asteria block#

FieldTypeDescriptionVesperine
schema_versionstringSemantic version of this schema"1.0.0"
registry_idstringPermanent Asteria registry ID, ASR- plus at least four digits"ASR-0001"
registry_namestringAsteria registry name, 3–32 characters — not an IAU name"Vesperine"
name_meaningstringWhere the name comes from"From the Latin vesper…"
official_designationstring or nullMPC designation once verified; null in previewnull
spectral_classenumOne of C, S, M, V, X, D"S"
orbitobjectOrbital elements and derived valuessee below
physicalobjectPhysical propertiessee below
data_sourcesstring[]Databases the record is checked againstOne entry, pending verification
disclaimerstringFixed legal text"Registry name only; …"

Orbit (asteria.orbit)#

FieldUnitRuleVesperine
orbit_class—One of 12 classes, from Atira to Jupiter Trojan, or OtherMiddle main belt
semi_major_axis_auAUGreater than 02.64
eccentricity—0 ≤ e < 1 (bound orbits only)0.11
inclination_degdegrees0 ≤ i ≤ 180, relative to the ecliptic7.2
perihelion_auAUa × (1 − e), 3 dp2.35
aphelion_auAUa × (1 + e), 3 dp2.93
period_yearsyearsa^1.5 (Kepler's third law), 3 dp4.289

Physical data (asteria.physical)#

FieldUnitRuleVesperine
diameter_kmkmGreater than 03.8
geometric_albedo—Greater than 0, at most 10.24
rotation_period_hhoursGreater than 05.6
absolute_magnitude_hmag5 × log10(1329 / (D × √p)), 2 dp14.27

The full list of orbit classes, with their boundaries, is in Orbits explained.

Validation rules#

Some rules can be written as JSON Schema; others compare fields with each other and are enforced by Asteria's generation pipeline and test suite. A document is valid only if it passes both.

  • Bound orbit: eccentricity must be at least 0 and strictly below 1. An orbit with e ≥ 1 would not return.
  • Ranges: semi_major_axis_au, diameter_km and rotation_period_h are positive; geometric_albedo lies in (0, 1]; inclination_deg lies in [0, 180].
  • Derived values agree: perihelion, aphelion, period and absolute magnitude must match the formulas above within rounding (±0.001 for orbital values, ±0.01 for H).
  • Class agrees: orbit_class must equal the class computed from a, e and i, and the "Near-Earth object" trait must agree with it.
  • Attributes agree: every attribute must equal the rounded value of its asteria counterpart.
  • Name agrees: name must be exactly the registry name, a space, and the registry ID in parentheses.
  • Registry name: 3–32 characters, following the naming guidelines.

JSON Schema#

The schema below (draft 2020-12) describes the shape of a v1 document. It is open to additional fields in the asteria block so that minor versions remain valid.

asteria-token-metadata.schema.json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:asteria:schema:token-metadata:1",
  "title": "Asteria token metadata, v1",
  "type": "object",
  "required": ["name", "description", "image", "external_url", "attributes", "asteria"],
  "properties": {
    "name": { "type": "string", "minLength": 1 },
    "description": { "type": "string", "minLength": 1 },
    "image": { "type": "string", "format": "uri" },
    "animation_url": { "type": "string", "format": "uri" },
    "external_url": { "type": "string", "format": "uri" },
    "attributes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["trait_type", "value"],
        "properties": {
          "trait_type": { "type": "string" },
          "value": { "type": ["string", "number"] },
          "display_type": { "const": "number" }
        },
        "additionalProperties": false
      }
    },
    "asteria": { "$ref": "#/$defs/asteria" }
  },
  "$defs": {
    "asteria": {
      "type": "object",
      "required": [
        "schema_version", "registry_id", "registry_name", "name_meaning",
        "official_designation", "spectral_class", "orbit", "physical",
        "data_sources", "disclaimer"
      ],
      "properties": {
        "schema_version": { "type": "string", "pattern": "^1\\.\\d+\\.\\d+$" },
        "registry_id": { "type": "string", "pattern": "^ASR-\\d{4,}$" },
        "registry_name": { "type": "string", "minLength": 3, "maxLength": 32 },
        "name_meaning": { "type": "string" },
        "official_designation": { "type": ["string", "null"], "minLength": 1 },
        "spectral_class": { "enum": ["C", "S", "M", "V", "X", "D"] },
        "orbit": { "$ref": "#/$defs/orbit" },
        "physical": { "$ref": "#/$defs/physical" },
        "data_sources": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
        "disclaimer": { "type": "string", "minLength": 1 }
      }
    },
    "orbit": {
      "type": "object",
      "required": [
        "orbit_class", "semi_major_axis_au", "eccentricity", "inclination_deg",
        "perihelion_au", "aphelion_au", "period_years"
      ],
      "properties": {
        "orbit_class": {
          "enum": [
            "Atira", "Aten", "Apollo", "Amor", "Mars-crosser", "Hungaria",
            "Inner main belt", "Middle main belt", "Outer main belt",
            "Hilda", "Jupiter Trojan", "Other"
          ]
        },
        "semi_major_axis_au": { "type": "number", "exclusiveMinimum": 0 },
        "eccentricity": { "type": "number", "minimum": 0, "exclusiveMaximum": 1 },
        "inclination_deg": { "type": "number", "minimum": 0, "maximum": 180 },
        "perihelion_au": { "type": "number", "exclusiveMinimum": 0 },
        "aphelion_au": { "type": "number", "exclusiveMinimum": 0 },
        "period_years": { "type": "number", "exclusiveMinimum": 0 }
      },
      "additionalProperties": false
    },
    "physical": {
      "type": "object",
      "required": ["diameter_km", "geometric_albedo", "rotation_period_h", "absolute_magnitude_h"],
      "properties": {
        "diameter_km": { "type": "number", "exclusiveMinimum": 0 },
        "geometric_albedo": { "type": "number", "exclusiveMinimum": 0, "maximum": 1 },
        "rotation_period_h": { "type": "number", "exclusiveMinimum": 0 },
        "absolute_magnitude_h": { "type": "number" }
      },
      "additionalProperties": false
    }
  }
}

Versioning policy#

The schema follows semantic versioning, and asteria.schema_version is always the first thing a consumer should read.

ChangeVersion bumpExample
Clarification, no change to the shapePatch — 1.0.xRewording the fixed description sentence
New optional fieldMinor — 1.x.0Adding an optional dedication or verification block
Renamed, removed or retyped field; changed unitMajor — 2.0.0Splitting orbit into osculating and proper elements
  • Consumers must ignore fields they do not recognise. That is what keeps minor versions safe.
  • Nothing is overwritten in place. Every update is published as a new IPFS document with a new CID; earlier versions remain retrievable.
  • Refreshes are signalled on-chain. The planned contract emits a standard metadata-update event (ERC-4906) whenever metadata changes.
  • Major versions are rare and announced. A new major version would be documented here, with a migration note, before any token uses it.

Next steps#