---
title: "Load a firearm with an ammunition type"
method: GET
path: "/v1/firearms/{id}/load"
tags: ["Ammunition"]
---

# Load a firearm with an ammunition type

`GET /v1/firearms/{id}/load`

## Request

- Base URL: `https://api.gunspec.io`
- URL: `https://api.gunspec.io/v1/firearms/{id}/load`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Returns the full ballistic profile for a firearm chambered with a given load: muzzle velocity and energy, effective range, terminal indices, and the trajectory sampled from the muzzle out to 1000 m.

Each trajectory point carries velocity, energy, drop from the bore, path from the line of sight for the answer's `zeroing`, time of flight, Mach number, momentum, Taylor Knock-Out factor and energy density, so the whole drop table can be rendered from one call. The trajectory is flown through the ICAO standard atmosphere at sea level.

When the firearm has no recorded barrel length, or no load can be resolved for its primary caliber, the response is still `200` and carries an `error` string in place of the computed blocks.

**Requires Builder tier or higher.**

## Path parameters

- `id` string, required

## Query parameters

- `ammo_id` string
- `zero_m` integer
- `sight_height_mm` number

## Response `200`

Load a firearm with an ammunition type

- object
  - `success` boolean, required: Always true on a successful response. Every error carries `false` and an `error` object instead.
  - `data` object, required: The response payload.
    - `firearm` BallisticsFirearm: The firearm the solution was computed for. `barrelLengthMm` is absent when the firearm has no recorded barrel.
      - `id` string, required: URL-safe slug identifying the firearm, e.g. `glock-g17-gen5`.
      - `name` string, required: Display name, as the maker writes it.
      - `barrelLengthMm` number: Barrel length in millimetres, measured from the breech face.
    - `ammunition` object: The load the calculation used.
      - `id` string: Slug of the ammunition load the firearm was chambered with.
      - `name` string: Display name, as the maker writes it.
      - `caliberId` string: Slug of the cartridge. Resolve against `/v1/calibers/{id}`.
      - `bulletWeightG` number: Bullet weight in grams. Divide by 0.0648 for grains.
      - `bulletType` string: Bullet construction: `fmj`, `jhp`, `sp`, `match`.
    - `calculated` object: The figures derived for the barrel length asked about, rather than the reference one.
      - `muzzleVelocityMps` number: Muzzle velocity in metres per second, for the default load.
      - `muzzleEnergyJ` number: Muzzle energy in joules, for the default load.
      - `effectiveRangeM` number: Effective range in metres against a point target.
      - `terminalBallistics` TerminalBallistics: Terminal performance indices computed at the muzzle.
        - `tkoFactor` number, required: Taylor Knock-Out factor.
        - `momentumKgMs` number, required: Momentum in kilogram-metres per second.
        - `sectionalDensity` number, required: Bullet mass divided by the square of its diameter. Higher penetrates better, all else equal.
        - `hatcherRSP` number, required: Hatcher Relative Stopping Power.
        - `energyDensityJCm2` number, required: Energy per unit frontal area, in joules per square centimetre.
    - `sourceReported` object: The figures published for this firearm, where the catalog records them.
      - `muzzleVelocityMps` number, nullable: Muzzle velocity in metres per second, for the default load.
      - `muzzleEnergyJ` number, nullable: Muzzle energy in joules, for the default load.
      - `effectiveRangeM` number, nullable: Effective range in metres against a point target.
    - `zeroing` Zeroing: How the gun is assumed sighted for `pathCm`. Neither figure is recorded per gun, so each is an assumption the caller may override with `zero_m` and `sight_height_mm`: a handgun zeroed at 25 m with its sights 20 mm above the bore, a long gun at 100 m with an optic 38 mm above it.
      - `zeroM` number, required: The distance at which the bullet crosses the line of sight, in m.
      - `sightHeightMm` number, required: The line of sight above the bore, in mm.
    - `trajectory` TrajectoryPoint[]: The flight path, one row per distance step.
      - `distanceM` number, required: Distance from the muzzle in metres.
      - `velocityMps` number, required: Remaining velocity at this distance, in metres per second.
      - `energyJ` number, required: Remaining energy at this distance, in joules.
      - `dropCm` number, required: Drop below the bore line at this distance, in cm: the fall under gravity alone, with no sighting.
      - `pathCm` number: Height relative to the line of sight at this distance, in cm, negative below: how a drop table reads, for the answer's `zeroing` (the gun zeroed at `zeroM` with its sights `sightHeightMm` above the bore). Starts at minus the sight height at the muzzle and is 0 at the zero.
      - `timeOfFlightS` number, required: Time of flight to this distance, in seconds.
      - `machNumber` number, required: Velocity as a multiple of the speed of sound. Below ~1.2 the projectile is transonic and destabilises.
      - `momentumKgMs` number, required: Momentum in kilogram-metres per second.
      - `tkoFactor` number, required: Taylor Knock-Out factor at this distance.
      - `energyDensityJCm2` number, required: Energy per unit frontal area, in joules per square centimetre.
    - `error` string, nullable: Why the calculation could not be completed, or null when it succeeded.

## Other responses

- `400`: Validation error
- `401`: Missing or invalid API key
- `403`: The credential is valid and the caller is not permitted. Three causes, none of which reissuing a key changes: the plan is below the endpoint's tier, the account is suspended, or the key is not attached to the thing being acted on, meaning a user account for `/v1/me` or a shop for `/v1/vendor`. Distinct from 401, which means the credential is missing, malformed or expired and a new one can work.
- `404`: Resource not found
- `429`: A limit was reached. `RATE_LIMITED` is the per-minute limit: wait `Retry-After` seconds (a minute) and retry. `DAILY_CAP_EXCEEDED` is the plan's daily limit, per key: nothing will be served until the counters return to zero at midnight UTC. `MONTHLY_CAP_EXCEEDED` is the plan's monthly allowance, for the whole account: nothing will be served until midnight UTC on the first of next month, or until the plan changes. For both, `Retry-After` is the seconds until then and `error.resetsAt` says when as an instant. Calls made after a refusal are refused too and do not spend the month, and a free key that keeps calling is paused, so stop at the first one and resume at the reset.
- `500`: Internal server error

---

[API](https://skmtc.dev/gunspec/apis/gunspec-io-api.md) · [All operations](https://skmtc.dev/gunspec/apis/gunspec-io-api/llms.txt) · [OpenAPI document](https://skmtc.dev/gunspec/apis/gunspec-io-api/revisions/f2e974d8b05c?raw)
