{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/gunspec-io/json-schema/gunspec-io-ammunition-load-schema.json",
  "title": "AmmunitionLoad",
  "description": "A specific factory ammunition load within a caliber.",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/gunspec-io-openapi.json#/components/schemas/AmmunitionLoad",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "URL-safe slug identifying the load, e.g. `9mm-124gr-fmj`."
    },
    "caliberId": {
      "type": "string",
      "description": "Slug of the cartridge. Resolve against `/v1/calibers/{id}`."
    },
    "name": {
      "type": "string",
      "description": "Display name, as the maker writes it."
    },
    "designation": {
      "type": [
        "string",
        "null"
      ],
      "description": "Military or standards designation for the load, e.g. `M882`."
    },
    "manufacturer": {
      "type": [
        "string",
        "null"
      ],
      "description": "Who makes it."
    },
    "countryOfOrigin": {
      "type": [
        "string",
        "null"
      ],
      "description": "ISO 3166-1 alpha-2 code of where it was designed, e.g. `AT`."
    },
    "bulletWeightG": {
      "type": "number",
      "description": "Bullet weight in grams. Divide by 0.0648 for grains."
    },
    "bulletType": {
      "type": "string",
      "description": "Bullet construction: `fmj`, `jhp`, `sp`, `match`."
    },
    "ballisticCoefficientG1": {
      "type": [
        "number",
        "null"
      ],
      "description": "Ballistic coefficient against the G1 drag model, the convention for flat-based bullets."
    },
    "ballisticCoefficientG7": {
      "type": [
        "number",
        "null"
      ],
      "description": "Ballistic coefficient against the G7 drag model, which fits boat-tail rifle bullets better than G1."
    },
    "referenceVelocityMps": {
      "type": "number",
      "description": "Muzzle velocity in metres per second **at the reference barrel length below**, not at the barrel of any particular firearm."
    },
    "referenceBarrelLengthMm": {
      "type": "number",
      "description": "Barrel length in millimetres the reference velocity was measured from. Velocity for another barrel is extrapolated from this pair."
    },
    "sectionalDensity": {
      "type": [
        "number",
        "null"
      ],
      "description": "Bullet mass divided by the square of its diameter. Higher penetrates better, all else equal."
    },
    "yearIntroduced": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Year it entered production or service. Null where the date is disputed or unknown."
    },
    "isCommon": {
      "type": "integer",
      "description": "1 when the load is commonly stocked."
    },
    "bulletSvgUrl": {
      "type": [
        "string",
        "null"
      ],
      "description": "Absolute URL of the rendered bullet diagram."
    },
    "velocityRetentionExponent": {
      "type": [
        "number",
        "null"
      ],
      "description": "Decay exponent used when extrapolating velocity to a barrel length other than the reference one."
    },
    "description": {
      "type": [
        "string",
        "null"
      ],
      "description": "Prose summary of the record, where one has been written."
    },
    "isMilitary": {
      "type": "integer",
      "description": "1 when the load is a military issue round."
    },
    "createdAt": {
      "type": "string",
      "description": "When the record was first added, `YYYY-MM-DD HH:MM:SS` in UTC."
    },
    "updatedAt": {
      "type": "string",
      "description": "When a field we serve last changed. Maintained by the database rather than by whatever wrote the row, so it moves for a corrected figure and does not move for a re-run of the seed. Before migration 0113 the seed rewrote every load on every run, and this said so."
    },
    "sources": {
      "type": [
        "array",
        "null"
      ],
      "items": {
        "type": "string"
      },
      "description": "Where the figures came from. Null on every load today: this family has somewhere to cite from and nothing cited yet, which the data quality page counts as a gap rather than hiding. Check a velocity against the maker until it is filled."
    },
    "dataConfidence": {
      "type": [
        "number",
        "null"
      ],
      "description": "How well specified the load is, on the same 0 to 1 scale as a firearm's. Null until there are sources behind it: a confidence figure with nothing supporting it looks like evidence and is not."
    },
    "provenance": {
      "$ref": "#/$defs/Provenance"
    },
    "version": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque fingerprint of this record. It changes when and only when a field we serve changes, so a client holding the same value already has the record and need not fetch it. Equality is the only supported operation: do not parse it, and do not assume how it is computed. Null means the record has not been written since versioning began, not that it is unchanged."
    }
  },
  "required": [
    "id",
    "caliberId",
    "name",
    "bulletWeightG",
    "bulletType",
    "referenceVelocityMps"
  ],
  "$defs": {
    "Provenance": {
      "type": "object",
      "description": "Where a record's figures came from and how far they have been checked, in one place. `sources` are the pages consulted; check a specific figure against those. `sourceKinds` says what each page is and `bestSourceKind` the strongest of them, on the hierarchy `SourceKind` defines: a maker or standards-body page is evidence for a figure, a retailer or forum page is evidence the item exists. `dataConfidence` is the 0 to 1 score set from what was actually sourced and never raised by hand. `verifiedAt` and `verifiedFields` say when a source was last read against the record and which fields it stated; null means the row is still seed knowledge. `updatedAt` and `version` are the same cache signals the record carries at the top level.",
      "properties": {
        "sources": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The pages consulted when the record was compiled, as an array. Check a specific figure against these rather than against `dataConfidence`."
        },
        "sourceKinds": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "description": "Absolute, directly fetchable URL."
              },
              "kind": {
                "$ref": "#/$defs/SourceKind"
              },
              "archivedFrom": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The original address when `url` is a Wayback Machine capture of it. A cited page that no longer answers is replaced by its last capture that answered 200, so the citation still shows what its author read; `kind` is the original page's."
              },
              "rank": {
                "type": "integer",
                "description": "The kind's place in the source hierarchy: 0 is the maker, the strongest; higher is weaker."
              },
              "tier": {
                "type": "string",
                "enum": [
                  "authority",
                  "classified",
                  "unclassified"
                ],
                "description": "Where the site stands in the source registry (`/v1/data/sources`): an authority (the maker, a standards body, a government), a classified site, or one not yet classed."
              },
              "basis": {
                "type": "string",
                "enum": [
                  "declared",
                  "maker",
                  "rule",
                  "unclassified"
                ],
                "description": "What the class rests on: classed by a person, a catalogued maker's own site, a .gov or .mil domain, or nothing yet."
              },
              "evidence": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The words the site was classed on, where a person recorded them."
              }
            },
            "required": [
              "url",
              "kind",
              "archivedFrom",
              "rank",
              "tier",
              "basis",
              "evidence"
            ]
          },
          "description": "What each cited page is, in `sources` order, on the `SourceKind` hierarchy. A host not in the source map is `other`, never guessed."
        },
        "bestSourceKind": {
          "anyOf": [
            {
              "$ref": "#/$defs/SourceKind"
            },
            {
              "type": "null"
            }
          ],
          "description": "The strongest kind among the citations, or null when nothing is cited. `manufacturer` or `standards_body` means a figure can be checked against an authority; `retailer` or `community` alone means the record is still supported by copies of copies."
        },
        "makerSource": {
          "type": [
            "string",
            "null"
          ],
          "description": "The first cited page on the record's own manufacturer's website, or null when it cites none. A page on another maker's site does not count. Cited from the maker is not the same as checked against it: `verifiedFields` names the figures that were read against a source."
        },
        "evidence": {
          "type": "string",
          "enum": [
            "verified",
            "maker",
            "authority",
            "secondary",
            "none"
          ],
          "description": "How far the record's figures are backed, strongest first, for a badge: `verified` when at least one figure was read against a source (`verifiedFields`), `maker` when it cites a page on its own manufacturer's site (`makerSource`), `authority` when it cites a maker, standards body or government page, `secondary` when it cites only press, retailers, references or forums, `none` when it cites nothing. Derived from the fields beside it."
        },
        "checks": {
          "type": "object",
          "description": "The checks the record has been through, on a single record's response only: every task the data agent (Redback) or a person was given about it, what each proposed, the pages it read, and whether a person accepted it. Nothing an agent proposes reaches the record until a person accepts it, so this is the trail behind `verifiedFields`. Who reviewed is not published; an agent's instance name is.",
          "properties": {
            "raised": {
              "type": "integer",
              "description": "Every task ever raised on the record, answered or not."
            },
            "open": {
              "type": "integer",
              "description": "Tasks still waiting to be worked."
            },
            "history": {
              "type": "array",
              "description": "The latest twenty, newest first.",
              "items": {
                "type": "object",
                "properties": {
                  "task": {
                    "type": "string",
                    "description": "The task id, stable across runs; the same id `/v1/data/tasks/{taskKey}` answers for."
                  },
                  "number": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "The task's number; `/v1/data/tasks/{number}` loads it as its key does."
                  },
                  "check": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "The check that raised it, where one did."
                  },
                  "kind": {
                    "type": "string",
                    "description": "`verify` reads the record against its maker's page, `gap` researches an empty field, `contradiction` judges fields that disagree, `vocabulary` a value outside a list."
                  },
                  "agent": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "`redback` when the agent worked it, `staff` when a person did, null when nobody has."
                  },
                  "worker": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "The agent instance that worked it; null for a person."
                  },
                  "status": {
                    "type": "string",
                    "description": "`resolved` (a proposal was filed), `unverifiable` (nothing could be established; retried after a cooldown), `not_a_fault`, or open."
                  },
                  "decidedAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "When the task was answered; null while it is open."
                  },
                  "proposed": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "What it proposed, in its own words; null while it is open."
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Per-field completeness, keyed by column name."
                  },
                  "sources": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The pages it read and quoted."
                  },
                  "review": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "decision": {
                        "type": "string",
                        "enum": [
                          "accepted",
                          "rejected"
                        ],
                        "description": "Whether a person accepted the proposal."
                      },
                      "at": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "When they decided."
                      }
                    },
                    "description": "A person's decision on the proposal; null until reviewed."
                  },
                  "finding": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "description": "What the check found, where a check raised the task: its own line for this record and the figures it measured, so a reader sees how the value breaks the method. The same the public task board serves with `include=research`.",
                    "properties": {
                      "why": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The check's line for this record."
                      },
                      "evidence": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "additionalProperties": true,
                        "description": "The figures the check measured."
                      }
                    },
                    "required": [
                      "why",
                      "evidence"
                    ]
                  }
                },
                "required": [
                  "task",
                  "number",
                  "check",
                  "kind",
                  "agent",
                  "worker",
                  "status",
                  "decidedAt",
                  "proposed",
                  "fields",
                  "sources",
                  "review",
                  "finding"
                ]
              }
            }
          },
          "required": [
            "raised",
            "open",
            "history"
          ]
        },
        "dataConfidence": {
          "type": [
            "number",
            "null"
          ],
          "description": "The 0 to 1 score set from what was actually sourced, never raised by hand. See the confidence bands in the docs."
        },
        "verifiedAt": {
          "type": [
            "string",
            "null"
          ],
          "description": "When a source was last read against this record. Null means the row is still seed knowledge."
        },
        "verifiedFields": {
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          },
          "description": "Which fields the source stated, as an array. Everything else on a verified row is still unverified. Null where no source has been read."
        },
        "specSource": {
          "type": [
            "string",
            "null"
          ],
          "description": "Cartridges only: the page the drawing figures were taken from. Null on every other kind of record."
        },
        "updatedAt": {
          "type": "string",
          "description": "When a served column last changed; the same value the record carries at the top level."
        },
        "version": {
          "type": [
            "string",
            "null"
          ],
          "description": "The record's content version, equal to the top-level `version`; equal versions mean equal data."
        }
      },
      "required": [
        "sources",
        "sourceKinds",
        "bestSourceKind",
        "makerSource",
        "evidence",
        "dataConfidence",
        "verifiedAt",
        "verifiedFields",
        "specSource",
        "updatedAt",
        "version"
      ]
    },
    "SourceKind": {
      "type": "string",
      "enum": [
        "manufacturer",
        "standards_body",
        "government",
        "peer_reviewed",
        "reference",
        "aggregator",
        "press",
        "retailer",
        "community",
        "other"
      ],
      "description": "What kind of page a cited source is, strongest first: the maker's own page, a standards body (SAAMI, C.I.P.), a government or military document, an independent reference work, a specification aggregator, the press, a retailer or auction listing, a community site, or an unclassified page. Weigh a figure by the best kind behind it, never by how many pages were cited."
    }
  }
}