{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:cede:schema:feed-data:v0",
  "title": "CEDE feed data document, v0",
  "description": "The publisher's response for one pinned snapshot, verbatim, with the digest beside it. The body of GET /feeds/{id}/versions/{version}/data. This is the document that makes data lineage checkable rather than asserted: `content` holds the file's bytes exactly as committed — nothing reorders, reformats or re-escapes them — so encoding `content` with `charset` and taking its sha256 reproduces `sha256`, which is the same value named in the assumption set of every price and backtest that read this version. The bytes travel inside a JSON envelope because SPEC.md section 7 validates every API response against a published schema, and a bare file body would be the one response on the surface with no schema to validate against.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "id",
    "version",
    "media_type",
    "charset",
    "sha256",
    "bytes",
    "verification",
    "content"
  ],
  "properties": {
    "schema_version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
    "id": { "type": "string", "minLength": 1 },
    "version": { "type": "string", "minLength": 1 },
    "media_type": {
      "type": "string",
      "minLength": 1,
      "description": "The media type of the data itself — text/csv for the catalogues pinned today — not of this envelope, which is JSON."
    },
    "charset": {
      "type": "string",
      "enum": ["utf-8"],
      "description": "The encoding that turns `content` back into the pinned bytes. One value today: every snapshot committed so far is UTF-8 text, and a snapshot that did not round-trip through it would be refused rather than served in a form the digest could not confirm."
    },
    "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
    "bytes": {
      "type": "integer",
      "minimum": 0,
      "description": "Length of the pinned file in bytes — the length of `content` re-encoded with `charset`, not the length of this document."
    },
    "verification": {
      "type": "string",
      "minLength": 1,
      "description": "How to check the digest, carried in the response so the instruction cannot go stale on a docs page."
    },
    "content": {
      "type": "string",
      "description": "The snapshot's bytes, decoded with `charset`. Empty is possible only for an empty file."
    }
  }
}
