Cartridges, loads and ballistics
Four endpoints answer four different questions that people ask as one. Picking the wrong one puts rifle velocities on a pistol page.
Which number you actually want
Velocity is a property of a load fired through a barrel, not of a cartridge and not of a gun. Each row below fixes a different part of that sentence.
| The question | The call | What it fixes |
|---|---|---|
| What is this cartridge, and what is it derived from? | GET /v1/calibers/{id} | The cartridge record: dimensions, case shape, the lineage links. |
| Roughly how does this cartridge perform? | GET /v1/calibers/ballistics?id= | A profile from the cartridge’s typical load. A shape, not a load you can buy. |
| What loads exist in it? | GET /v1/calibers/{id}/ammunition | The factory loads catalogued in that cartridge. |
| How does this load perform, through this barrel? | GET /v1/ammunition/{id}/ballistics | One load, your distances, your barrel length. |
| How does this gun perform with this load? | GET /v1/firearms/{id}/load?ammo_id= | The firearm’s own barrel, sampled out to 1000 m with terminal indices. |
| Does that agree with what the catalog publishes? | GET /v1/firearms/{id}/calculate?ammo_id= | Muzzle figures only, compared against the record’s own published figures. |
Cartridge to a plotted table
Three calls, and the third is the one that matters: pass the barrel you are modelling. Omit it and you get the load’s reference barrel, which is fine for a box-label figure and wrong for a specific gun. Parameters are on the ammunition reference.
// From a cartridge to a number on a page.// 1. The cartridge, and what else is in its family.const { data: caliber } = await gunspec.calibers.get('300-blackout') // 2. The factory loads actually catalogued in it.const { data: loads } = await gunspec.calibers.getAmmunition('300-blackout') // 3. One load, computed out to the distances you want to plot -// and through a specific barrel, because velocity is a property// of the pairing and not of the box.const { data: table } = await gunspec.ammunition.ballistics(loads[0].id, { barrel_length_mm: 406, distances: '0,100,200,300,400,500',})Ballistics for one firearm and one load
Two endpoints, deliberately separate, because a trajectory and a muzzle comparison are different pages.
// The same question asked of a firearm rather than a load.// `load` samples the trajectory out to 1000 m using the firearm's// own barrel: this is what a "chamber it and plot it" page wants.const { data: profile } = await gunspec.firearms.load('sig-sauer-mcx', { ammo_id: '300-blk-125gr-otm' }) // `calculate` returns muzzle figures only and compares them with// the figures the catalog records for that firearm. That is how// you show a computed number honestly beside a published one.const { data: muzzle } = await gunspec.firearms.calculate('sig-sauer-mcx', { ammo_id: '300-blk-125gr-otm' })loadis the plotting endpoint: each point carries velocity, energy, drop, time of flight and the indices, so a chart needs one request.calculateis the honesty endpoint: it returns the computed muzzle figures beside the ones the catalog records, which is what lets you show a difference rather than hide one.- Both need the cartridge to make sense for the firearm. Resolve the firearm first, read its calibers, and offer loads from those.
Cartridge families and lineage
/v1/calibers/{id}/parent-chain walks upward, taking .300 Blackout back to .223 Remington, and /family returns the cartridge with its parent and everything derived from it. Use them for "related cartridges" rails and for explaining why two names describe nearly the same round. /v1/calibers/compare puts up to five side by side. The calibers reference has the fields.
Showing computed numbers honestly
A computed trajectory is a model, and the catalog’s published figures are somebody else’s measurement. The ballistics fields say which is which, and the accuracy note says what we do and do not warrant.
- Label computed figures as computed, and say which barrel length and load they assume.
- Where the record carries
sourceMuzzleVelocityMpsand the like, those are published figures with a source. Show them as the published ones. - Do not average a computed figure with a published one. They are different claims, and the mean of the two is a third number nobody stands behind.