{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://proofofcustody.io/schemas/custody.schema.json",
  "title": "custody.json",
  "description": "A provider-published statement of how it holds client bitcoin, served at https://<provider-domain>/.well-known/custody.json. Written by the provider, about the provider, so an agent can read the provider's own words and check them against third-party records. Draft 0.1, 19 Oct 2026.",
  "type": "object",
  "required": ["version", "provider", "asOf", "custodyModel", "keyholders", "contact"],
  "properties": {
    "version": { "type": "string", "const": "0.1" },
    "asOf": { "type": "string", "format": "date", "description": "Date this statement was last reviewed by the provider." },
    "nextReview": { "type": "string", "format": "date" },
    "provider": {
      "type": "object",
      "required": ["name", "legalName", "domain"],
      "properties": {
        "name": { "type": "string" },
        "legalName": { "type": "string" },
        "domain": { "type": "string" },
        "jurisdiction": { "type": "string" },
        "registrations": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["regulator", "type"],
            "properties": {
              "regulator": { "type": "string", "description": "e.g. NYDFS, South Dakota Division of Banking, FinCEN" },
              "type": { "type": "string", "description": "e.g. limited-purpose trust charter, BitLicense, MSB registration" },
              "identifier": { "type": "string" },
              "url": { "type": "string", "format": "uri", "description": "Where an agent can verify the registration." }
            }
          }
        }
      }
    },
    "custodyModel": {
      "type": "string",
      "enum": ["exchange", "single-qualified-custodian", "collaborative-multisig", "multi-institution-custody", "self-custody-hardware", "etf-trust", "other"],
      "description": "The model as Proof of Custody defines it at https://proofofcustody.io/data/custody-models.json."
    },
    "quorum": {
      "type": "object",
      "description": "For multi-key models: how many signers of how many must act.",
      "properties": { "required": { "type": "integer" }, "total": { "type": "integer" } }
    },
    "keyholders": {
      "type": "array",
      "description": "Each institution that can sign. Count institutions, not keys. The holder, if they hold a key, is listed as {\"name\": \"client\"}.",
      "items": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "legalName": { "type": "string" },
          "jurisdiction": { "type": "string" },
          "role": { "type": "string", "description": "e.g. operator, independent keyholder, backup keyholder, client" },
          "url": { "type": "string", "format": "uri" }
        }
      }
    },
    "holderHoldsKey": { "type": "boolean", "description": "Whether the client ever handles a private key, seed phrase or signing device." },
    "segregation": { "type": "string", "enum": ["segregated-per-client", "omnibus", "mixed"], "description": "How client assets are titled and separated." },
    "attestations": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["type", "url"],
        "properties": {
          "type": { "type": "string", "description": "e.g. SOC 2 Type II, proof of reserves, financial audit, on-chain addresses" },
          "provider": { "type": "string" },
          "date": { "type": "string", "format": "date" },
          "cadence": { "type": "string" },
          "url": { "type": "string", "format": "uri" }
        }
      }
    },
    "insurance": {
      "type": "object",
      "properties": {
        "carrier": { "type": "string" },
        "limit": { "type": "string", "description": "State the limit exactly as the policy states it, including whether it is aggregate or per-client." },
        "basis": { "type": "string", "enum": ["aggregate", "per-client", "per-incident", "none"] },
        "whoPays": { "type": "string" },
        "url": { "type": "string", "format": "uri" }
      }
    },
    "withdrawal": {
      "type": "object",
      "properties": {
        "controls": { "type": "string", "description": "e.g. video verification, time delay, allowlists" },
        "typicalTime": { "type": "string" },
        "url": { "type": "string", "format": "uri" }
      }
    },
    "incidents": {
      "type": "array",
      "description": "Security or availability incidents the provider has disclosed, newest first.",
      "items": {
        "type": "object",
        "required": ["date", "summary", "url"],
        "properties": { "date": { "type": "string", "format": "date" }, "summary": { "type": "string" }, "url": { "type": "string", "format": "uri" } }
      }
    },
    "feed": { "type": "string", "format": "uri", "description": "Optional URL of a machine-readable change feed or status page." },
    "contact": {
      "type": "object",
      "required": ["security"],
      "properties": { "security": { "type": "string", "description": "Email or URL for security reports." }, "press": { "type": "string" } }
    }
  }
}
