GunSpec

Compatibility

Fit is computed from mount interfaces, never from names. A firearm declares what it exposes at each position (muzzle thread, rails, optic cut, stock and grip interfaces, magazine well); an attachment declares what it requires; the engine matches the two, through a named adapter where one bridges them. A caliber, bore or minimum-barrel mismatch is never bridged and never inferred.

Every fit carries `source` and `confidence`, and they are the first two fields to read. source is the weakest evidence in the chain that produced the fit; confidence is capped by the weakest interface it went through. The values, strongest first:

  • curated: a person recorded this interface or this fit against the maker's page.
  • universal: the attachment requires nothing (a sling), so every firearm fits it.
  • inherited:parent: the interface came from the firearm's parent record.
  • inherited:platform: the interface came from a platform the firearm belongs to (an AK-100 default, a mil-spec AR-15 default).
  • inferred: the interface was derived by a script from the record's own fields, at 0.6 or below. Convention rows are the weakest inferred evidence and are labelled as such: where a firearm is tagged threaded or optics-ready but names no standard, the backfill applies industry convention (a thread by cartridge and country, an optic plate by the maker's system) at 0.5 to 0.6, with a convention: note on the interface row.

A retailer or an engineering consumer should treat `inferred`, and anything below a confidence they choose, as unverified. Pass min_confidence to hide fits computed through interfaces below that figure; nothing in a response presents an inferred or convention row as verified, and neither should a product page built on it. via[] names each interface the fit went through with its own source, so a fit can be audited hop by hop; GET /v1/firearms/{id}/interfaces lists every row with its source, confidence and inheritedFrom.

Browsing the catalog (/v1/attachments, /v1/attachments/{id}, /v1/interfaces) is open to any key. Everything that answers "does this go on that" is Studio, and a lower plan receives 403 SUBSCRIPTION_REQUIRED rather than an empty list, so never read an error as "nothing fits". fits= on the attachment list is the same computation wearing a query parameter and is gated the same way.

Auth RequiredStudio+

Every catalogued attachment that fits the firearm, grouped by category. A retailer embeds this on a product page with vendor=me&only_offered=true&with_offers=true, which answers "what fits this gun, that I stock, at what price" in one request. Full detail: each with how it fits (direct, through a named adapter, or curated), which interface satisfied it, and a confidence. include=all adds the candidates that do not fit with the reason they were blocked, which is how a builder shows a greyed-out part. Rated items (suppressors, magazines) pass a caliber, bore and minimum-barrel gate that no adapter can bridge.

GET/v1/firearms/{id}/attachments

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • stringrequired

    Firearm slug

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • string

    Attachment category

    Max length
    100
    Example
  • string

    Manufacturer slug

    Max length
    100
    Example
  • stringdefaultcompatible

    compatible (default) or all to include blocked candidates with blockedBy

    Accepts
    Example
  • numberdefault0

    Hide fits computed through interfaces below this confidence

    Range
    0 – 1
    Example
  • string

    Restrict to one seller. me resolves to the vendor your key belongs to

    Max length
    64
    Example
  • boolean

    Drop anything that seller does not currently stock. Needs a resolvable vendor, and yields nothing without one

  • boolean

    Attach each item's live offers under offers, keyed by attachment id, so price and stock render beside fitment in one call

  • object

    The response payload.

  • object

    A firearm, identified by slug and name.

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • object[]

    Platforms this firearm belongs to, whose interfaces it inherits.

  • string

    Slug of the platform.

  • string

    Display name, as the maker writes it.

  • ResolvedInterface[]

    The mount interfaces resolved for this firearm, own rows first, then inherited.

  • string

    Where on the firearm the interface sits: muzzle, rear, top, bottom.

  • string

    Id of the interface standard, kind-prefixed, e.g. thread:1/2x28. Ids are never renamed; new spellings become aliases.

  • string

    Display name, as the maker writes it.

  • string

    What sort of interface it is: thread, rail, mag, stock_mount, optic_plate. Not a media kind: the shared registry filled this with silhouette/render until the consistency check caught it.

  • InterfaceSource

    Where an interface row on a firearm came from. curated is a person; inferred is the backfill, capped at 0.6 confidence; the inherited kinds came through the parent chain or a platform.

  • number

    How well evidenced this row is, 0 to 1. A minimum, not an average: an inferred row caps every fit computed through it, and min_confidence on the endpoint hides rows below a threshold.

  • string | null

    The parent firearm or platform this interface came from, or null when the firearm declares it itself.

  • string | null

    Free-text notes that do not belong in a specific field.

  • object[]

    Fitting attachments grouped by category, so a builder UI renders one panel per slot.

  • string

    Attachment category this group holds.

  • AttachmentFit[]

    The rows this response carries.

  • object

    Fitting attachments per category

  • object | null

    With with_offers=true, live offers keyed by attachment id, the same rows /v1/attachments/{id}/offers returns; null when not requested.

  • integer

    Total records matching the query across every page.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 404NOT_FOUNDResource not found
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Read source and confidence on every item before anything else. source is the weakest evidence behind the fit (curated, universal, inherited:parent, inherited:platform or inferred) and confidence is capped by the weakest interface it went through; via[] names each interface with its own source. inferred means a script derived the interface the fit went through; a product page should say so or hide it.

min_confidence=0.7 is the usual retail setting: it drops every fit that went through a convention row.

A retailer adds vendor=me&only_offered=true&with_offers=true to answer "what fits this gun, that I stock, at what price" in one call.

Minimum tier
Studio+
Monthly quota
150,000/mo
Rate limit
120/min
Daily cap
10,000

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.