---
title: "Get a firearm"
method: GET
path: "/v1/firearms/{id}"
tags: ["Firearms"]
---

# Get a firearm

`GET /v1/firearms/{id}`

## Request

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

Returns the full specification for a single firearm, including its manufacturer, category, calibers, images, and known users.

**Requires Builder tier or higher.**

## Path parameters

- `id` string, required

## Headers

- `If-None-Match` string

## Response `200`

Get a firearm

- object
  - `success` boolean, required: Always true on a successful response. Every error carries `false` and an `error` object instead.
  - `data` FirearmDetail, required: A firearm as stored: every specification column we serve, with no nested relations. `FirearmDetail` is this plus them, and `/v1/firearms/{id}/family-tree` returns this shape for `current`, since the walk reads the row and does not load the relations.
    - `has3dModel` integer: Integer flag, `1` when a 3D model is on file. Stored as the database holds it rather than as a boolean.
    - `svgLineArtUrl` string, nullable: Line-art silhouette, or null where none has been drawn.
    - `model3dUrl` string, nullable: GLB model, or null where none is on file.
    - `defaultAmmoId` string, nullable: The ammunition load ballistics figures are quoted against, where one is nominated.
    - `sourceMuzzleVelocityMps` number, nullable: Muzzle velocity in metres per second **exactly as the source stated it**, kept beside our own figure so a reader can see what was quoted and what was derived.
    - `sourceMuzzleEnergyJ` number, nullable: Muzzle energy in joules exactly as the source stated it.
    - `sourceEffectiveRangeM` number, nullable: Effective range in metres exactly as the source stated it.
    - `sourceMaxRangeM` number, nullable: Maximum range in metres exactly as the source stated it.
    - `ballisticsSource` string, nullable: Where the ballistics figures came from, named in prose.
    - `ballisticsSourceUrl` string, nullable: URL of the ballistics source, where it is a page rather than a book.
    - `id` string: URL-safe slug identifying the firearm, e.g. `glock-g17-gen5`. Stable: it is what a mirror keys on.
    - `name` string: Display name, as the maker writes it.
    - `manufacturerId` string: Slug of the manufacturer that makes it. Resolve against `/v1/manufacturers/{id}`.
    - `categoryId` string: Slug of the category it belongs to. Resolve against `/v1/categories`.
    - `parentFirearmId` string, nullable: The firearm this one is a variant of, or null when it is not a variant. Variant relationships are what `firearm.variant.updated` webhooks and `/v1/firearms/{id}/variants` follow.
    - `variantType` string, nullable: How this record differs from its parent: `optics_ready`, `compact`, `threaded` and so on. Null when the record has no parent.
    - `yearIntroduced` integer, nullable: Year it entered production or service. Null where the date is disputed or unknown.
    - `yearDiscontinued` integer, nullable: Year production ended, or null while it is still made.
    - `status` 'in_production' | 'discontinued' | 'out_of_production' | 'in_service' | 'limited_production' | 'prototype': Production status of a firearm. Closed: these are every value the catalog holds.
    - `countryOfOrigin` string, nullable: ISO 3166-1 alpha-2 code of where it was designed, e.g. `AT`.
    - `weightEmptyG` number, nullable: Unloaded weight in grams, without magazine.
    - `weightLoadedG` number, nullable: Loaded weight in grams, with a full magazine.
    - `overallLengthMm` number, nullable: Overall length in millimetres, stock extended where it folds or collapses.
    - `barrelLengthMm` number, nullable: Barrel length in millimetres, measured from the breech face.
    - `heightMm` number, nullable: Height in millimetres, including sights and a fitted magazine.
    - `widthMm` number, nullable: Width in millimetres at the widest point.
    - `sightRadiusMm` number, nullable: Distance between front and rear iron sights in millimetres. Null on a record with no iron sights.
    - `actionType` string, nullable: How the action cycles: `short_recoil`, `gas_operated`, `blowback`, `bolt_action` and so on. An open vocabulary: the values in use are published on the schema as `x-gunspec-vocabulary`, and `GET /v1/firearms/action-types` is the live list.
    - `firingMechanism` string, nullable: What releases the striker or hammer: `striker_fired`, `hammer_fired`.
    - `triggerType` string, nullable: Trigger arrangement: `single_action`, `double_action`, `safe_action`.
    - `triggerPullN` number, nullable: Trigger pull weight in newtons. Divide by 4.448 for pounds-force.
    - `magazineCapacity` integer, nullable: Rounds in the standard magazine. Null where the firearm is not magazine-fed.
    - `magazineType` string, nullable: Magazine pattern: `detachable_box`, `internal`, `drum`, `belt`.
    - `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.
    - `maxRangeM` number, nullable: Maximum range in metres. Where the projectile lands, not where it is useful.
    - `rateOfFireRpm` integer, nullable: Cyclic rate in rounds per minute. Null on anything that is not automatic.
    - `barrelRifling` string, nullable: Rifling description, e.g. `6 grooves, right-hand twist`.
    - `riflingTwistMm` number, nullable: Rifling twist rate in millimetres per turn. Divide by 25.4 for inches.
    - `numberOfGrooves` integer, nullable: Number of grooves cut in the bore.
    - `frameMaterial` string, nullable: What the frame or receiver is made of.
    - `slideMaterial` string, nullable: What the slide is made of. Null on anything without one.
    - `barrelMaterial` string, nullable: What the barrel is made of.
    - `stockMaterial` string, nullable: What the stock or furniture is made of.
    - `finish` string, nullable: Surface finish, e.g. `nitride`, `parkerized`, `cerakote`.
    - `safetyMechanisms` string[], nullable: Safety mechanisms the design carries.
    - `features` string[], nullable: Notable features of the design.
    - `feedSystems` string[], nullable: How the firearm is fed.
    - `gameDamage` integer, nullable: Editorial game statistic, 0-100. **Not a measured figure.** These are balance numbers for game use and are not derived from the ballistics above.
    - `gameAccuracy` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `gameRange` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `gameFireRate` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `gameMobility` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `gameRecoilControl` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `gameReloadSpeed` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `gameConcealment` integer, nullable: Editorial game statistic, 0-100. Not a measured figure.
    - `description` string, nullable: Prose summary of the record, where one has been written.
    - `notes` string, nullable: Free-text notes that do not belong in a specific field.
    - `designer` string, nullable: Person or team credited with the design, where it is known.
    - `foldedLengthMm` number, nullable: Length with stock folded (mm)
    - `alternateNames` string[], nullable: Other names and designations the same firearm is known by.
    - `firingModes` string[], nullable: Firing modes the selector offers.
    - `conflicts` object[], nullable: Conflicts the firearm saw service in.
      - `name` string: The conflict.
      - `years` string: When it ran, as written.
      - `sides` string[]: The belligerents.
    - `productionNumbers` object, nullable: How many were made, and over what period.
      - `estimated_total` integer, nullable: Units believed produced.
      - `production_years` string, nullable: The production run, as written.
      - `notes` string, nullable: What the estimate covers.
    - `lore` string, nullable: Historical trivia / game-dev flavor text
    - `sources` string[], nullable: Source URLs the record was compiled from. Check a specific figure against these rather than against `dataConfidence`. The same list is in `provenance.sources`.
    - `verifiedAt` string, nullable: When a source was last read against the record's figures. Null until one has been. The same value is in `provenance.verifiedAt`.
    - `verifiedFields` string[], nullable: The figures a source confirmed: read off the manufacturer's own page, within the published tolerance, and accepted by a person. The same list is in `provenance.verifiedFields`.
    - `dataConfidence` number, nullable: How completely the record is specified and how well it is sourced, 0 to 1. A record-level completeness and provenance measure, **not** a per-field probability of correctness. Use it to rank and triage; use `sources` to verify an individual number.
    - `createdAt` string: When the record was first added, `YYYY-MM-DD HH:MM:SS` in UTC.
    - `updatedAt` string: When a field we serve last changed. Maintained by the database rather than by whatever wrote the row, so it moves for a corrected specification and does not move for a re-run of the importer.
    - `version` string, nullable: 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.
    - `provenance` Provenance: 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.
      - `sources` string[], required: The pages consulted when the record was compiled, as an array. Check a specific figure against these rather than against `dataConfidence`.
      - `sourceKinds` object[], required: What each cited page is, in `sources` order, on the `SourceKind` hierarchy. A host not in the source map is `other`, never guessed.
        - `url` string, required: Absolute, directly fetchable URL.
        - `kind` 'manufacturer' | 'standards_body' | 'government' | 'peer_reviewed' | 'reference' | 'aggregator' | 'press' | 'retailer' | 'community' | 'other', required: 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.
        - `archivedFrom` string, nullable, required: 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` integer, required: The kind's place in the source hierarchy: 0 is the maker, the strongest; higher is weaker.
        - `tier` 'authority' | 'classified' | 'unclassified', required: 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` 'declared' | 'maker' | 'rule' | 'unclassified', required: What the class rests on: classed by a person, a catalogued maker's own site, a .gov or .mil domain, or nothing yet.
        - `evidence` string, nullable, required: The words the site was classed on, where a person recorded them.
      - `bestSourceKind` 'manufacturer' | 'standards_body' | 'government' | 'peer_reviewed' | 'reference' | 'aggregator' | 'press' | 'retailer' | 'community' | 'other', required: 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.
      - `makerSource` string, nullable, required: 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` 'verified' | 'maker' | 'authority' | 'secondary' | 'none', required: 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` object: 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.
        - `raised` integer, required: Every task ever raised on the record, answered or not.
        - `open` integer, required: Tasks still waiting to be worked.
        - `history` object[], required: The latest twenty, newest first.
          - `task` string, required: The task id, stable across runs; the same id `/v1/data/tasks/{taskKey}` answers for.
          - `number` integer, nullable, required: The task's number; `/v1/data/tasks/{number}` loads it as its key does.
          - `check` string, nullable, required: The check that raised it, where one did.
          - `kind` string, required: `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` string, nullable, required: `redback` when the agent worked it, `staff` when a person did, null when nobody has.
          - `worker` string, nullable, required: The agent instance that worked it; null for a person.
          - `status` string, required: `resolved` (a proposal was filed), `unverifiable` (nothing could be established; retried after a cooldown), `not_a_fault`, or open.
          - `decidedAt` string, nullable, required: When the task was answered; null while it is open.
          - `proposed` string, nullable, required: What it proposed, in its own words; null while it is open.
          - `fields` string[], required: Per-field completeness, keyed by column name.
          - `sources` string[], required: The pages it read and quoted.
          - `review` object, nullable, required: A person's decision on the proposal; null until reviewed.
            - `decision` 'accepted' | 'rejected': Whether a person accepted the proposal.
            - `at` string, nullable: When they decided.
          - `finding` object, nullable, required: 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`.
            - `why` string, nullable, required: The check's line for this record.
            - `evidence` object, nullable, required: The figures the check measured.
      - `dataConfidence` number, nullable, required: The 0 to 1 score set from what was actually sourced, never raised by hand. See the confidence bands in the docs.
      - `verifiedAt` string, nullable, required: When a source was last read against this record. Null means the row is still seed knowledge.
      - `verifiedFields` string[], nullable, required: 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` string, nullable, required: Cartridges only: the page the drawing figures were taken from. Null on every other kind of record.
      - `updatedAt` string, required: When a served column last changed; the same value the record carries at the top level.
      - `version` string, nullable, required: The record's content version, equal to the top-level `version`; equal versions mean equal data.
    - `manufacturer` Manufacturer
      - `id` string: URL-safe slug identifying the manufacturer, e.g. `glock`.
      - `name` string: Display name, as the maker writes it.
      - `countryCode` string, nullable: ISO 3166-1 alpha-2 code of where the company is based.
      - `foundedYear` integer, nullable: Year the company was founded.
      - `status` 'active' | 'defunct' | 'unknown' | 'null', nullable: Whether the company still trades. Much of this catalog is historical, and null means nobody has established which.
      - `defunctYear` integer, nullable: Year the company ceased trading, where that is established. Null while it still trades, and also null where the closing year is simply unknown, so an absent value is never read as "still trading".
      - `stateOwned` boolean, nullable: Government owned. **Null is not false**: it means nobody has established it, and a consumer treating null as false would report every unchecked company as private.
      - `makesFirearms` boolean, nullable: Builds the products this catalog lists, as against importing, rebranding or customising them. Scope is the catalog rather than a legal definition: air rifles are listed here as rifles and pistols, so their makers are true. Null means unestablished.
      - `parentId` string, nullable: The manufacturer that owns this one today.
      - `predecessorId` string, nullable: The manufacturer this one succeeded, which is not the same as being owned by it: U.S. Repeating Arms followed Winchester without Winchester owning it.
      - `website` string, nullable: Official website, where one is known.
      - `logoUrl` string, nullable: Absolute URL of the logo, or null where none is on file.
      - `description` string, nullable: Prose summary of the record, where one has been written.
      - `createdAt` string: When the record was first added, `YYYY-MM-DD HH:MM:SS` in UTC.
      - `updatedAt` string: When a field we serve last changed. Maintained by the database rather than by whatever wrote the row, so it moves for a corrected specification and does not move for a re-run of the importer.
      - `version` string, nullable: 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.
    - `category` Category
      - `id` string: URL-safe slug identifying the category, e.g. `pistol`.
      - `name` string: Display name, as the maker writes it.
      - `description` string, nullable: Prose summary of the record, where one has been written.
    - `calibers` FirearmCaliber[]: Every cartridge this firearm is chambered for, primary first.
      - `caliberId` string: Slug of the cartridge. Resolve against `/v1/calibers/{id}`.
      - `isPrimary` integer: Integer flag, `1` on the chambering the firearm is normally sold in. A firearm may be chambered for several cartridges but has at most one primary.
      - `name` string: Display name, as the maker writes it.
      - `natoDesignation` string, nullable: NATO designation where the cartridge has one, e.g. `9mm NATO`. Null otherwise.
      - `bulletDiameterMm` number, nullable: Bullet diameter in millimetres.
      - `caseLengthMm` number, nullable: Case length in millimetres.
      - `cartridgeType` string, nullable: Head type: `rimmed`, `rimless`, `semi_rimmed`, `rebated_rim`, `belted`, plus historical values like `cap_and_ball`. **Not the broad class.** The registry said `pistol`/`rifle`/`shotgun` until the column was read, and it holds neither.
      - `neckDiameterMm` number, nullable: Case neck outside diameter in millimetres.
      - `shoulderDiameterMm` number, nullable: Bottleneck cases only.
      - `baseDiameterMm` number, nullable: Case base diameter in millimetres, ahead of the extractor groove.
      - `rimDiameterMm` number, nullable: Rim diameter in millimetres.
      - `rimThicknessMm` number, nullable: Rim thickness in millimetres.
      - `overallLengthMm` number, nullable: Overall length in millimetres, stock extended where it folds or collapses.
      - `bulletLengthMm` number, nullable: Typical projectile length.
      - `typicalBulletWeightG` number, nullable: Representative bullet weight in grams. Divide by 0.0648 for grains.
      - `primerType` string, nullable: Primer size and type, e.g. `small_pistol`, `large_rifle`, `rimfire`.
      - `caseShape` 'straight' | 'tapered' | 'bottleneck' | 'none' | 'null', nullable: Case profile: `straight`, `bottleneck`, `tapered`, `belted`.
      - `caseMaterial` 'brass' | 'nickel_brass' | 'steel' | 'lacquered_steel' | 'aluminium' | 'polymer' | 'paper' | 'caseless' | 'none' | 'null', nullable: What the case is made of: `brass`, `steel`, `aluminium`, `polymer`.
      - `projectileKind` 'bullet' | 'none' | 'shot' | 'slug' | 'round_ball' | 'flechette' | 'dart' | 'pellet' | 'rocket' | 'grenade' | 'signal' | 'null', nullable: `none` is a blank.
      - `bulletProfile` 'spitzer' | 'spitzer_boat_tail' | 'round_nose' | 'flat_nose' | 'wadcutter' | 'semi_wadcutter' | 'hollow_point' | 'truncated_cone' | 'round_ball' | 'null', nullable: Bullet shape: `fmj`, `hollow_point`, `soft_point`, `spitzer`, `round_nose`.
      - `closure` 'bullet' | 'star_crimp' | 'rosette_crimp' | 'roll_crimp' | 'fold_crimp' | 'wad' | 'paper' | 'none' | 'null', nullable: What seals the case mouth; a blank is a star crimp.
      - `markingColor` 'black' | 'white' | 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple' | 'pink' | 'brown' | 'grey' | 'silver' | 'gold' | 'null', nullable: Paint that identifies the load: crimp lacquer on a blank, tip colour on a military round.
    - `images` FirearmImage[]: Every image on file, silhouette first. Each carries an absolute, directly fetchable `url`.
      - `id` integer: Autoincrementing image id. Numeric, unlike the catalog slugs.
      - `firearmId` string: Slug of the firearm this row belongs to.
      - `url` string: Absolute, directly fetchable URL.
      - `type` 'svg' | 'photo' | '3d_model' | 'gallery' | 'primary' | 'thumbnail' | 'render' | 'profile' | 'angle' | 'detail': The storage label on `FirearmImage.type`, predating `kind`: `svg` is `silhouette`, `3d_model` is `model`, and `gallery` is the default an upload lands on. Branch on `kind`.
      - `source` string, nullable: Where the record came from: a curated entry, an inference, or an import.
      - `license` string, nullable: Licence the asset is held under, where one is recorded.
      - `kind` 'silhouette' | 'render' | 'photo' | 'schematic' | 'model': What kind of asset a media row is.
      - `storage` string, nullable: Where the bytes live: `cdn` for a static path, `r2` for an upload we serve.
      - `author` string, nullable: Who made the asset, where it is credited.
      - `sourceUrl` string, nullable: Page the asset or document was taken from.
      - `alt` string, nullable: Alt text, where one has been written. Null otherwise, so do not render an empty string.
      - `width` integer, nullable: Pixel width, where it is known.
      - `height` integer, nullable: Pixel height, where it is known.
      - `sortOrder` integer: Position within its list, ascending.
    - `users` FirearmUser[]: Forces and agencies that have adopted it.
      - `id` integer: Autoincrementing row id.
      - `firearmId` string: Slug of the firearm this row belongs to.
      - `userName` string: The force, agency or organisation that adopted it.
      - `userType` string, nullable: What kind of user: `military`, `police`, `civilian`.
      - `countryCode` string, nullable: ISO 3166-1 alpha-2 code of the user's country.
      - `adoptedYear` integer, nullable: Year of adoption, where it is known.
      - `designation` string, nullable: What that user calls it, where it differs from the maker's name.
    - `schematics` FirearmSchematic[]: Exploded-view and parts diagrams on file, empty where none have been sourced.
      - `id` integer, required: Autoincrementing schematic id.
      - `firearmId` string, required: Slug of the firearm this row belongs to.
      - `title` string, required: What the document is called.
      - `type` 'blueprint' | 'spec_sheet' | 'manual' | 'datasheet' | 'exploded_view' | 'reference', required: What a schematic document is.
      - `url` string, required: Absolute, directly fetchable URL.
      - `format` string, nullable: File format, e.g. `pdf`.
      - `version` string, nullable: Revision of the document, where the publisher versions it.
      - `manufacturer` string, nullable: Publisher of the document, often but not always the maker.
      - `source` string, nullable: Where the document came from.
      - `sourceUrl` string, nullable: Page the asset or document was taken from.
      - `author` string, nullable: Who made the asset, where it is credited.
      - `license` string, nullable: Licence the asset is held under, where one is recorded.
      - `createdAt` string: When the record was first added, `YYYY-MM-DD HH:MM:SS` in UTC.

## Other responses

- `304`: Your copy is current. No body is sent, and this response does not count toward the daily request allowance.
- `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)
