DocsThe data protocol

claim/v1

packages/core/schema/claim.schema.json
On this page

One attributed, immutable statement about an account, a contract or a group. Named by the SHA-256 of its RFC 8785 canonical JSON, without id and proof. The rules a schema can't say are in validateClaim. See specs/002-system/contracts/claims.md.

Fields

Field Type or allowed values Presence in its parent Description
petal "claim/v1" Required
id string Required
subject string Required Namespaced. refs.ts says which namespaces parse. No natural person.
verb "holds" / "measured" / "delegates_to" / "owned_by" / "member_of" / "holds_role" / "voted" / "proposed" / "reviewed" / "paid" / "funded_by" / "signer_of" / "deployed" / "controls" / "declares_same_controller" / "shares_signer" / "moves_with" / "same_funder" / "same_address" / "labelled" / "requests_correction" / "challenges" / "responds" / "retracts" / "supersedes" / "confidence" Required A closed list per version. Each verb's definition is in verbs.ts and contracts/claims.md.
object choice Required
object (variant 1) string Required Namespaced. refs.ts says which namespaces parse. No natural person.
object (variant 2) object Required
object (variant 2).value string Required A number as a string, or a closed tag. Never free text.
object (variant 2).unit string Optional
qualifiers object Optional Checked per verb. Amounts are strings.
qualifiers.* string Optional
valid_from string Optional UTC with Z, so one moment has one spelling and one id.
valid_to string Optional UTC with Z, so one moment has one spelling and one id.
issued_at string Required UTC with Z, so one moment has one spelling and one id.
as_of object Optional
as_of.chain string Required
as_of.block integer Required
kind "observed" / "declared" / "sourced" / "inferred" Required
method string Optional Required if inferred: a rule or model, its version, and an optional hash of its parameters.
evidence array Required
evidence[] object Required
evidence[].snapshot_sha256 string Optional
evidence[].url string Optional
evidence[].url_sha256 string Optional
evidence[].retrieved_at string Optional UTC with Z, so one moment has one spelling and one id.
evidence[].claim_id string Optional
evidence[].note string Optional Must not name a person.
by string Required Namespaced. refs.ts says which namespaces parse. No natural person.
via string Optional Namespaced. refs.ts says which namespaces parse. No natural person.
proof choice Optional Outside the hash: the same claim can carry different proofs.
proof (variant 1) object Optional
proof (variant 1).type "tx" Required
proof (variant 1).hash string Required
proof (variant 2) object Optional
proof (variant 2).type "nep413" Required
proof (variant 2).account_id string Required
proof (variant 2).public_key string Required
proof (variant 2).signature string Required
proof (variant 2).message string Required
proof (variant 2).nonce string Required
proof (variant 2).recipient string Required
proof (variant 3) object Optional
proof (variant 3).type "nearai" Required
proof (variant 3).model string Required
proof (variant 3).completion_id string Required
proof (variant 3).text string Required
proof (variant 3).signature string Required
proof (variant 3).signing_address string Required
proof (variant 3).signing_algo "ecdsa" / "ed25519" Required

Examples

claim.v1.json

Fixture source

{
  "petal": "claim/v1",
  "subject": "near:mainnet:tern.pool.example.near",
  "verb": "holds",
  "object": "asset:near:mainnet:NEAR",
  "qualifiers": {
    "amount": "1000.5",
    "measure": "validator_stake",
    "unit": "NEAR"
  },
  "issued_at": "2026-11-05T12:00:00Z",
  "valid_from": "2026-11-05T12:00:00Z",
  "valid_to": "2026-11-05T12:00:00Z",
  "as_of": {
    "chain": "near:mainnet",
    "block": 123
  },
  "kind": "observed",
  "evidence": [
    {
      "snapshot_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    }
  ],
  "by": "tool:petal/observed-claims@1",
  "id": "7ae8e42a82da887b85d2d27b936ce89f75b4b77e0aeacafb5e3935126c5246c2"
}

Full schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:petal:schema:claim:v1",
  "title": "Petal claim v1",
  "description": "One attributed, immutable statement about an account, a contract or a group. Named by the SHA-256 of its RFC 8785 canonical JSON, without id and proof. The rules a schema can't say are in validateClaim. See specs/002-system/contracts/claims.md.",
  "type": "object",
  "required": [
    "petal",
    "id",
    "subject",
    "verb",
    "object",
    "issued_at",
    "kind",
    "evidence",
    "by"
  ],
  "additionalProperties": false,
  "properties": {
    "petal": {
      "const": "claim/v1"
    },
    "id": {
      "$ref": "#/$defs/sha256"
    },
    "subject": {
      "$ref": "#/$defs/entityRef"
    },
    "verb": {
      "enum": [
        "holds",
        "measured",
        "delegates_to",
        "owned_by",
        "member_of",
        "holds_role",
        "voted",
        "proposed",
        "reviewed",
        "paid",
        "funded_by",
        "signer_of",
        "deployed",
        "controls",
        "declares_same_controller",
        "shares_signer",
        "moves_with",
        "same_funder",
        "same_address",
        "labelled",
        "requests_correction",
        "challenges",
        "responds",
        "retracts",
        "supersedes",
        "confidence"
      ],
      "description": "A closed list per version. Each verb's definition is in verbs.ts and contracts/claims.md."
    },
    "object": {
      "oneOf": [
        {
          "$ref": "#/$defs/entityRef"
        },
        {
          "type": "object",
          "required": [
            "value"
          ],
          "additionalProperties": false,
          "properties": {
            "value": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "description": "A number as a string, or a closed tag. Never free text."
            },
            "unit": {
              "type": "string",
              "minLength": 1,
              "maxLength": 32
            }
          }
        }
      ]
    },
    "qualifiers": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "maxLength": 256
      },
      "description": "Checked per verb. Amounts are strings."
    },
    "valid_from": {
      "$ref": "#/$defs/datetime"
    },
    "valid_to": {
      "$ref": "#/$defs/datetime"
    },
    "issued_at": {
      "$ref": "#/$defs/datetime"
    },
    "as_of": {
      "type": "object",
      "required": [
        "chain",
        "block"
      ],
      "additionalProperties": false,
      "properties": {
        "chain": {
          "type": "string",
          "pattern": "^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$"
        },
        "block": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      }
    },
    "kind": {
      "enum": [
        "observed",
        "declared",
        "sourced",
        "inferred"
      ]
    },
    "method": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._/-]*@[a-zA-Z0-9][a-zA-Z0-9._/-]*(#[0-9a-f]{8,64})?$",
      "description": "Required if inferred: a rule or model, its version, and an optional hash of its parameters."
    },
    "evidence": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/evidence"
      }
    },
    "by": {
      "$ref": "#/$defs/entityRef"
    },
    "via": {
      "$ref": "#/$defs/entityRef"
    },
    "proof": {
      "oneOf": [
        {
          "$ref": "#/$defs/txProof"
        },
        {
          "$ref": "#/$defs/nep413Proof"
        },
        {
          "$ref": "#/$defs/nearAiProof"
        }
      ],
      "description": "Outside the hash: the same claim can carry different proofs."
    }
  },
  "if": {
    "type": "object",
    "properties": {
      "kind": {
        "const": "inferred"
      }
    },
    "required": [
      "kind"
    ]
  },
  "then": {
    "type": "object",
    "properties": {
      "method": true
    },
    "required": [
      "method"
    ]
  },
  "else": {
    "not": {
      "type": "object",
      "properties": {
        "method": true
      },
      "required": [
        "method"
      ]
    }
  },
  "$defs": {
    "sha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "datetime": {
      "type": "string",
      "format": "date-time",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$",
      "description": "UTC with Z, so one moment has one spelling and one id."
    },
    "entityRef": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*:[^\\s]+$",
      "maxLength": 300,
      "description": "Namespaced. refs.ts says which namespaces parse. No natural person."
    },
    "evidence": {
      "type": "object",
      "minProperties": 1,
      "additionalProperties": false,
      "properties": {
        "snapshot_sha256": {
          "$ref": "#/$defs/sha256"
        },
        "url": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2048
        },
        "url_sha256": {
          "$ref": "#/$defs/sha256"
        },
        "retrieved_at": {
          "$ref": "#/$defs/datetime"
        },
        "claim_id": {
          "$ref": "#/$defs/sha256"
        },
        "note": {
          "type": "string",
          "minLength": 1,
          "maxLength": 280,
          "description": "Must not name a person."
        }
      }
    },
    "txProof": {
      "type": "object",
      "required": [
        "type",
        "hash"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "tx"
        },
        "hash": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "nep413Proof": {
      "type": "object",
      "required": [
        "type",
        "account_id",
        "public_key",
        "signature",
        "message",
        "nonce",
        "recipient"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "nep413"
        },
        "account_id": {
          "type": "string"
        },
        "public_key": {
          "type": "string",
          "pattern": "^ed25519:"
        },
        "signature": {
          "type": "string"
        },
        "message": {
          "type": "string"
        },
        "nonce": {
          "type": "string"
        },
        "recipient": {
          "type": "string"
        }
      }
    },
    "nearAiProof": {
      "type": "object",
      "required": [
        "type",
        "model",
        "completion_id",
        "text",
        "signature",
        "signing_address",
        "signing_algo"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "nearai"
        },
        "model": {
          "type": "string"
        },
        "completion_id": {
          "type": "string"
        },
        "text": {
          "type": "string"
        },
        "signature": {
          "type": "string"
        },
        "signing_address": {
          "type": "string"
        },
        "signing_algo": {
          "enum": [
            "ecdsa",
            "ed25519"
          ]
        }
      }
    }
  }
}