{
  "name": "Warconomy consumer validation guide",
  "asOf": "2026-06-05",
  "datasetVersion": "1.187.0",
  "note": "How to validate every Warconomy export against the published contract. Static examples only; no runtime validation service. Validate against the JSON Schemas and TypeScript types.",
  "page": "https://warconomy.com/developers/validation",
  "steps": [
    {
      "id": "dataset",
      "title": "Validate data.json",
      "how": "Validate the top-level export against schema.json (draft-07). Required: version, dataset, observations, sources, facts, series, distributions. Additional properties are allowed (additive contract).",
      "example": "// any draft-07 validator (e.g. ajv)\nconst schema = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/schema.json\")).json();\nconst data = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/data.json\")).json();\n// validate(data) against schema; new fields will not fail it.",
      "language": "javascript"
    },
    {
      "id": "provenance",
      "title": "Validate provenance",
      "how": "Every provenance record must resolve to a real source. Check that each record.sourceId exists in data.json sources and that summary.recordsWithoutSource === 0.",
      "example": "const prov = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/provenance.json\")).json();\nconsole.assert(prov.summary.recordsWithoutSource === 0);\nconst ids = new Set((await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/data.json\")).json()).sources.map(s => s.id));\nconsole.assert(prov.records.every(r => ids.has(r.sourceId)));",
      "language": "javascript"
    },
    {
      "id": "graph",
      "title": "Validate the citation graph",
      "how": "Every edge endpoint must be an existing node id (no dangling edges), and summary counts must match the arrays.",
      "example": "const g = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/graph.json\")).json();\nconst ids = new Set(g.nodes.map(n => n.id));\nconsole.assert(g.edges.every(e => ids.has(e.from) && ids.has(e.to)));\nconsole.assert(g.summary.nodeCount === g.nodes.length);",
      "language": "javascript"
    },
    {
      "id": "schemas",
      "title": "Validate against the record schemas",
      "how": "Use the per-record schemas (observation/source/series/graph/diff). They pin required fields and allow extras. A real record must satisfy its schema's required[].",
      "example": "const obsSchema = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/observation.schema.json\")).json();\nconst { observations } = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/data.json\")).json();\nconsole.assert(observations.every(o => obsSchema.required.every(f => o[f] !== undefined)));",
      "language": "javascript"
    },
    {
      "id": "distributions",
      "title": "Validate CSV / JSONL distributions",
      "how": "CSV is RFC-4180 with a header row; JSONL is one JSON object per line. Row counts should match the dataset arrays.",
      "example": "curl -s https://warconomy.com/datasets/conflict-economic-impact/observations.csv | head -n 1   # header row\ncurl -s https://warconomy.com/datasets/conflict-economic-impact/observations.jsonl | wc -l       # one object per observation",
      "language": "bash"
    },
    {
      "id": "diffs",
      "title": "Validate version & provenance diffs",
      "how": "diff.json is value-level when valueLevel is true; record-diffs.json carries scalar before/after for changed records; provenance-diff.json reports added/removed/changed provenance ids. All are honest about availability.",
      "example": "const diff = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/versions/1.187.0/diff.json\")).json();\nconst recs = await (await fetch(\"https://warconomy.com/datasets/conflict-economic-impact/versions/1.187.0/record-diffs.json\")).json();\nconsole.assert(typeof diff.valueLevel === \"boolean\");\nconsole.assert(recs.changedRecordCount === recs.records.length);",
      "language": "javascript"
    }
  ],
  "schema": "https://warconomy.com/datasets/conflict-economic-impact/schema.json",
  "types": "https://warconomy.com/developers/types"
}