GunSpec

Firearms

Resource class for interacting with the GunSpec Firearms API. Wraps all /v1/firearms endpoints. Instantiated internally by the GunSpec client and exposed as client.firearms.

Auth RequiredExplorer+

List firearms with optional filters and pagination.

list(params?: ListFirearmsParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms

  • stringheaderrequired

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

  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example
  • stringdefaultname

    Sort field

    Accepts
    Example
  • stringdefaultasc

    Sort order

    Accepts
    Example
  • string

    Comma-separated list of fields to include

    Example
  • string

    Filter by manufacturer slug

    Max length
    100
    Example
  • string

    Filter by caliber slug

    Example
  • string

    Filter by category slug

    Max length
    100
    Example
  • string

    Filter by action type, as stored and underscored. The vocabulary is /v1/firearms/action-types

    Example
  • string

    Filter by ISO 3166-1 alpha-2 country code

    Example
  • integer

    Minimum year introduced

  • integer

    Maximum year introduced

  • number

    Minimum empty weight (grams)

  • number

    Maximum empty weight (grams)

  • number

    Minimum barrel length (mm)

  • string

    Filter by production status

    Accepts
  • string

    Comma-separated feature slugs; all must match

    Example
  • string

    Only firearms with (or without) a 3D model

    Accepts
  • string

    Only firearms with (or without) real imagery: a render or a photograph, ignoring the line-art silhouette every firearm has

    Accepts
  • string

    Only records added after this ISO 8601 timestamp

  • string

    Only records added before this ISO 8601 timestamp

  • FirearmListItem[]

    One page of results

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • string

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string

    Slug of the category it belongs to. Resolve against /v1/categories.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • string | null

    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.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • InlineMediaItem[]

    Every image this firearm has, silhouette first. Empty when none are on file.

  • integer

    Autoincrementing image id.

  • string

    Absolute, directly fetchable URL.

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    GLB model, or null where none is on file.

  • integer

    How many accounts have favorited this record.

  • 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.

  • string | null

    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.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

Auto-paginate through all firearms matching the given filters. Returns an async iterator that fetches pages on demand, yielding individual Firearm objects. Useful for processing large result sets without managing pagination manually.

listAutoPaging(params?: ListFirearmsParams): AsyncIterableIterator<Firearm>
GET/v1/firearms

  • stringheaderrequired

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

  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example
  • stringdefaultname

    Sort field

    Accepts
    Example
  • stringdefaultasc

    Sort order

    Accepts
    Example
  • string

    Comma-separated list of fields to include

    Example
  • string

    Filter by manufacturer slug

    Max length
    100
    Example
  • string

    Filter by caliber slug

    Example
  • string

    Filter by category slug

    Max length
    100
    Example
  • string

    Filter by action type, as stored and underscored. The vocabulary is /v1/firearms/action-types

    Example
  • string

    Filter by ISO 3166-1 alpha-2 country code

    Example
  • integer

    Minimum year introduced

  • integer

    Maximum year introduced

  • number

    Minimum empty weight (grams)

  • number

    Maximum empty weight (grams)

  • number

    Minimum barrel length (mm)

  • string

    Filter by production status

    Accepts
  • string

    Comma-separated feature slugs; all must match

    Example
  • string

    Only firearms with (or without) a 3D model

    Accepts
  • string

    Only firearms with (or without) real imagery: a render or a photograph, ignoring the line-art silhouette every firearm has

    Accepts
  • string

    Only records added after this ISO 8601 timestamp

  • string

    Only records added before this ISO 8601 timestamp

  • FirearmListItem[]

    One page of results

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • string

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string

    Slug of the category it belongs to. Resolve against /v1/categories.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • string | null

    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.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • InlineMediaItem[]

    Every image this firearm has, silhouette first. Empty when none are on file.

  • integer

    Autoincrementing image id.

  • string

    Absolute, directly fetchable URL.

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    GLB model, or null where none is on file.

  • integer

    How many accounts have favorited this record.

  • 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.

  • string | null

    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.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Returns an async iterator: it fetches each page as you consume it, so a loop over the whole collection is one statement and one page in memory at a time.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Full-text search across firearms.

search(params: SearchFirearmsParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/search

  • stringheaderrequired

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

  • stringrequired

    Search query

    Max length
    200
    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • FirearmSearchResult[]

    One search hit. The field names are snake_case here, unlike /v1/firearms and the rest of the catalog: these are the search view's own columns and renaming them would break every consumer already reading them. manufacturer_name and category_name are joined in so a result list renders without a second call.

  • string

    URL-safe slug identifying the firearm. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer. manufacturerId on the camelCase endpoints.

  • string | null

    Slug of the category. categoryId on the camelCase endpoints.

  • string | null

    Display name of the manufacturer, joined in so a result row needs no second call.

  • string | null

    Display name of the category.

  • string | null

    Slug of the category again, under the name the search view uses. Same value as category_id.

  • integer | null

    Year the model was introduced.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of the country of origin.

  • string | null

    Operating action as stored, underscored, e.g. short_recoil, bolt_action, gas_operated. The full vocabulary is /v1/firearms/action-types; a hyphenated value matches nothing.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    GLB model, or null where none is on file.

  • integer

    How many accounts have favorited this record.

  • number | null

    FTS5 relevance score the page is ordered by. Lower is a better match (SQLite bm25 scores are negative), and it is only comparable within one response. Absent or null when the query fell back to a plain substring match, which has no ranking.

  • InlineMediaItem[]

    Every image this firearm has, silhouette first. Empty when none are on file.

  • integer

    Autoincrementing image id.

  • string

    Absolute, directly fetchable URL.

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Compare up to 5 firearms side by side.

compare(params: CompareFirearmsParams): Promise<APIResponse<FirearmComparison>>
GET/v1/firearms/compare

  • stringheaderrequired

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

  • stringrequired

    Comma-separated firearm slugs, maximum 5

    Example

  • object

    The response payload.

  • FirearmWithRelations[]

    The compared firearms, in the order their ids were given.

  • integer

    Integer flag, 1 when a 3D model is on file. Stored as the database holds it rather than as a boolean.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    GLB model, or null where none is on file.

  • string | null

    The ammunition load ballistics figures are quoted against, where one is nominated.

  • number | null

    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.

  • number | null

    Muzzle energy in joules exactly as the source stated it.

  • number | null

    Effective range in metres exactly as the source stated it.

  • number | null

    Maximum range in metres exactly as the source stated it.

  • string | null

    Where the ballistics figures came from, named in prose.

  • string | null

    URL of the ballistics source, where it is a page rather than a book.

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • object[]

    Per-field differences across the compared firearms, one entry per numeric field.

  • string

    Which column the row is about, named as the database names it.

  • number | null[]

    This field on each compared firearm, in the order the ids were given. Null where that record does not carry the field.

  • number | null

    Lowest value across the compared firearms. Null when fewer than two of them carry the field.

  • number | null

    Highest value across the compared firearms. Null when fewer than two of them carry the field.

  • number | null

    Spread from the lowest value, as a percentage of it: (max - min) / min * 100, rounded to two places. Null when the minimum is zero or fewer than two records carry the field.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Retrieve game metadata for firearms (archetypes, stat ranges, etc.).

gameMeta(params?: GameMetaParams): Promise<APIResponse<GameMetaItem[]>>
GET/v1/firearms/game-meta

  • stringheaderrequired

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

  • string

    Restrict to a single archetype

    Accepts

  • GameProfile[]

    The response payload.

  • string

    Slug of the firearm this profile is for.

  • string

    Display name, as the maker writes it.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure. These are balance numbers for game use and are not derived from the ballistics above.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • GameArchetype

    The role a firearm's game profile assigns it.

  • string[]

    The statistics this firearm scores highest on.

  • string[]

    The statistics it scores lowest on.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

List all known action types across the database.

actionTypes(): Promise<APIResponse<ActionTypeStats[]>>
GET/v1/firearms/action-types

  • stringheaderrequired

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

  • object[]

    The response payload.

  • string

    The action type as stored, and the value to send as action_type when filtering.

  • string

    Display name, as the maker writes it.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

Get available filter options for the firearms list endpoint. Returns distinct values for manufacturers, calibers, categories, action types, countries, and statuses that can be used as filter values.

filterOptions(): Promise<APIResponse<FilterOptions>>
GET/v1/firearms/filter-options

  • stringheaderrequired

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

  • object

    The distinct filter values currently present in the catalog.

  • object[]

    Manufacturers with at least one firearm.

  • string

    Slug of the manufacturer, and the value to send as manufacturer.

  • string

    Display name, as the maker writes it.

  • string | null

    ISO 3166-1 alpha-2 code of where they are based, for grouping the list by country.

  • object[]

    Categories with at least one firearm.

  • string

    Slug of the category, and the value to send as category. Keyed slug here rather than id, unlike the other lists.

  • string

    Display name, as the maker writes it.

  • object[]

    Cartridges chambered by at least one firearm.

  • string

    Slug of the cartridge, and the value to send as caliber.

  • string

    Display name, as the maker writes it.

  • object[]

    Operating actions present in the catalog.

  • string

    The action type as stored, and the value to send as action_type.

  • string

    Display name, as the maker writes it.

  • object[]

    JSON array of notable features, as a string. The same vocabulary /v1/firearms/by-feature filters on.

  • string

    The feature as stored, and the value to send as feature to /v1/firearms/by-feature.

  • string

    Display name, as the maker writes it.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

Get a random firearm, optionally filtered by category or country.

random(params?: RandomFirearmParams): Promise<APIResponse<Firearm>>
GET/v1/firearms/random

  • stringheaderrequired

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

  • string

    Restrict the draw to a category slug

    Example
  • string

    Restrict the draw to an ISO country code

    Example

  • object

    The response payload.

  • string

    Slug of the drawn firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer. Null where the maker is unrecorded.

  • string | null

    Slug of the category the firearm belongs to.

  • integer | null

    Year the model was introduced.

  • string | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of the country of origin.

  • string | null

    Operating action as stored, underscored, e.g. short_recoil, bolt_action, gas_operated. The full vocabulary is /v1/firearms/action-types; a hyphenated value matches nothing.

  • number | null

    Unloaded weight in grams.

  • number | null

    Barrel length in millimetres.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredBuilder+

Get top firearms ranked by a specific statistic.

top(params: TopFirearmsParams): Promise<APIResponse<Firearm[]>>
GET/v1/firearms/top

  • stringheaderrequired

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

  • stringrequired

    Which superlative to rank by

    Accepts
    Example
  • string

    Restrict the ranking to a category slug

    Example
  • integerdefault10

    How many to return

    Range
    1 – 25
    Example

  • TopFirearm[]

    The response payload.

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • number | null

    The figure this ranking is by, in the unit of whichever statistic was requested.

  • string

    One of g, m, rpm, mm, rounds, J

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Compare two firearms in a head-to-head matchup.

headToHead(params: HeadToHeadParams): Promise<APIResponse<HeadToHead>>
GET/v1/firearms/head-to-head

  • stringheaderrequired

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

  • stringrequired

    First firearm slug

    Max length
    255
    Example
  • stringrequired

    Second firearm slug

    Max length
    255
    Example

  • object

    The response payload.

  • HeadToHeadFirearm

    One of the two compared firearms, as selected: the sixteen columns the verdicts are computed from, snake_case, under their database names.

  • string

    URL-safe slug identifying the firearm. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer. manufacturerId on the camelCase endpoints.

  • string | null

    Slug of the category. categoryId on the camelCase endpoints.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Overall length in millimetres.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • integer | null

    Standard magazine capacity, in rounds.

  • number | null

    Muzzle velocity in metres per second, with the reference load.

  • number | null

    Muzzle energy in joules, with the reference load.

  • number | null

    Effective range in metres.

  • number | null

    Cyclic rate of fire in rounds per minute; null for a semi-automatic or manual action.

  • HeadToHeadFirearm

    One of the two compared firearms, as selected: the sixteen columns the verdicts are computed from, snake_case, under their database names.

  • string

    URL-safe slug identifying the firearm. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer. manufacturerId on the camelCase endpoints.

  • string | null

    Slug of the category. categoryId on the camelCase endpoints.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Overall length in millimetres.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • integer | null

    Standard magazine capacity, in rounds.

  • number | null

    Muzzle velocity in metres per second, with the reference load.

  • number | null

    Muzzle energy in joules, with the reference load.

  • number | null

    Effective range in metres.

  • number | null

    Cyclic rate of fire in rounds per minute; null for a semi-automatic or manual action.

  • object

    One verdict per compared stat, keyed by the stat's camelCase name (weightEmptyG, overallLengthMm, barrelLengthMm, magazineCapacity, muzzleVelocityMps, muzzleEnergyJ, effectiveRangeM, rateOfFireRpm). A stat neither firearm carries is omitted, so the key set is the stats that could be compared.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Filter firearms by a specific feature.

byFeature(params: ByFeatureParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/by-feature

  • stringheaderrequired

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

  • stringrequired

    Feature name as stored, e.g. threaded barrel. The vocabulary is features on /v1/firearms/filter-options

    Example
  • string

    Restrict to a category slug

    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • object[]

    One page of results

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    JSON array of every feature this firearm carries, as a string, not only the one filtered on.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

Filter firearms by action type.

byAction(params: ByActionParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/by-action

  • stringheaderrequired

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

  • stringrequired

    Action type as stored, underscored, e.g. short_recoil. The vocabulary is /v1/firearms/action-types

    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • object[]

    One page of results

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • string | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    The action this firearm uses, as stored.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Filter firearms by frame/component material.

byMaterial(params: ByMaterialParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/by-material

  • stringheaderrequired

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

  • stringrequired

    Material name

    Example
  • stringrequired

    Which component the material applies to

    Accepts
    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • object[]

    One page of results

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    The material recorded for the component that was filtered on. Matched case-insensitively, returned as stored.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Filter firearms by designer name.

byDesigner(params: ByDesignerParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/by-designer

  • stringheaderrequired

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

  • stringrequired

    Designer name. Matched as a substring, so a surname alone works

    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • object[]

    One page of results

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    Everyone credited on this firearm, as stored, not only the name filtered on.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Get firearms ranked by computed power rating.

powerRating(params?: PowerRatingParams): Promise<PaginatedResponse<PowerRating>>
GET/v1/firearms/power-rating

  • stringheaderrequired

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

  • string

    Restrict the ranking to a category slug

    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • object[]

    One page of results

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string

    Slug of the category it belongs to. Resolve against /v1/categories.

  • number

    Composite score from 0 to 100, the sum of the weighted components in breakdown.

  • object

    The weighted components powerRating is the sum of.

  • number

    Muzzle-energy component, out of 30.

  • number

    Effective-range component, out of 25.

  • number

    Rate-of-fire component, out of 20.

  • number

    Magazine-capacity component, out of 15.

  • number

    Mobility component, out of 10. Lighter and shorter scores higher.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Get firearms arranged in a chronological timeline.

timeline(params?: TimelineParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/timeline

  • stringheaderrequired

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

  • integer

    Earliest year of introduction

    Example
  • integer

    Latest year of introduction

    Example
  • string

    Restrict to a category slug

    Example
  • integerdefault1

    Page number

    Range
    1 – 10000
    Example
  • integerdefault50

    Items per page (max 100)

    Range
    1 – 100
    Example
  • stringdefaultasc

    Sort order

    Accepts
    Example

  • TimelineEntry[]

    One page of results

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • integer | null

    Year production ended, or null while it is still made.

  • string | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredStudio+

Filter firearms by military conflict.

byConflict(params: ByConflictParams): Promise<PaginatedResponse<Firearm>>
GET/v1/firearms/by-conflict

  • stringheaderrequired

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

  • stringrequired

    Conflict name

    Example
  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • object[]

    One page of results

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • string | null

    Every conflict this firearm is recorded in, comma-separated, not only the one filtered on.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

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.

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredBuilder+

Get a single firearm by its slug or ID.

get(id: string): Promise<APIResponse<FirearmDetail>>
GET/v1/firearms/{id}

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmDetail

    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.

  • integer

    Integer flag, 1 when a 3D model is on file. Stored as the database holds it rather than as a boolean.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    GLB model, or null where none is on file.

  • string | null

    The ammunition load ballistics figures are quoted against, where one is nominated.

  • number | null

    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.

  • number | null

    Muzzle energy in joules exactly as the source stated it.

  • number | null

    Effective range in metres exactly as the source stated it.

  • number | null

    Maximum range in metres exactly as the source stated it.

  • string | null

    Where the ballistics figures came from, named in prose.

  • string | null

    URL of the ballistics source, where it is a page rather than a book.

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • string

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    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.

  • string | null

    How this record differs from its parent: optics_ready, compact, threaded and so on. Null when the record has no parent.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • integer | null

    Year production ended, or null while it is still made.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Loaded weight in grams, with a full magazine.

  • number | null

    Overall length in millimetres, stock extended where it folds or collapses.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • number | null

    Height in millimetres, including sights and a fitted magazine.

  • number | null

    Width in millimetres at the widest point.

  • number | null

    Distance between front and rear iron sights in millimetres. Null on a record with no iron sights.

  • string | null

    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.

  • string | null

    What releases the striker or hammer: striker_fired, hammer_fired.

  • string | null

    Trigger arrangement: single_action, double_action, safe_action.

  • number | null

    Trigger pull weight in newtons. Divide by 4.448 for pounds-force.

  • integer | null

    Rounds in the standard magazine. Null where the firearm is not magazine-fed.

  • string | null

    Magazine pattern: detachable_box, internal, drum, belt.

  • number | null

    Muzzle velocity in metres per second, for the default load.

  • number | null

    Muzzle energy in joules, for the default load.

  • number | null

    Effective range in metres against a point target.

  • number | null

    Maximum range in metres. Where the projectile lands, not where it is useful.

  • integer | null

    Cyclic rate in rounds per minute. Null on anything that is not automatic.

  • string | null

    Rifling description, e.g. 6 grooves, right-hand twist.

  • number | null

    Rifling twist rate in millimetres per turn. Divide by 25.4 for inches.

  • integer | null

    Number of grooves cut in the bore.

  • string | null

    What the frame or receiver is made of.

  • string | null

    What the slide is made of. Null on anything without one.

  • string | null

    What the barrel is made of.

  • string | null

    What the stock or furniture is made of.

  • string | null

    Surface finish, e.g. nitride, parkerized, cerakote.

  • string | null

    JSON array of safety mechanisms

  • string | null

    JSON array of features

  • string | null

    JSON array of feed systems

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure. These are balance numbers for game use and are not derived from the ballistics above.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • string | null

    Prose summary of the record, where one has been written.

  • string | null

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

  • string | null

    Person or team credited with the design, where it is known.

  • number | null

    Length with stock folded (mm)

  • string | null

    JSON array of alternate names/designations

  • string | null

    JSON array of firing modes

  • string | null

    JSON array of conflict objects with name, years, and sides

  • string | null

    JSON object with estimated_total, production_years, and notes

  • string | null

    Historical trivia / game-dev flavor text

  • string | null

    JSON array of source URLs the record was compiled from. Check a specific figure against these rather than against dataConfidence.

  • number | null

    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.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • 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.

  • string | null

    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

    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.

  • string[]

    The pages consulted when the record was compiled, as an array. Check a specific figure against these rather than against dataConfidence.

  • object[]

    What each cited page is, in sources order, on the SourceKind hierarchy. A host not in the source map is other, never guessed.

  • SourceKind | null

    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.

  • number | null

    The 0 to 1 score set from what was actually sourced, never raised by hand. See the confidence bands in the docs.

  • string | null

    When a source was last read against this record. Null means the row is still seed knowledge.

  • string[]

    Which fields the source stated, as an array. Everything else on a verified row is still unverified. Null where no source has been read.

  • string | null

    Cartridges only: the page the drawing figures were taken from. Null on every other kind of record.

  • string

    When a served column last changed; the same value the record carries at the top level.

  • string | null

    The record's content version, equal to the top-level version; equal versions mean equal data.

  • Manufacturer | null

    Null when the record names a manufacturer id the catalog no longer holds.

  • Category | null

    Null when the record names a category id the catalog no longer holds.

  • FirearmCaliber[]

    Every cartridge this firearm is chambered for, primary first.

  • string

    Slug of the cartridge. Resolve against /v1/calibers/{id}.

  • 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.

  • string

    Display name, as the maker writes it.

  • string | null

    NATO designation where the cartridge has one, e.g. 9mm NATO. Null otherwise.

  • number | null

    Bullet diameter in millimetres.

  • number | null

    Case length in millimetres.

  • string | null

    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.

  • number | null

    Case neck outside diameter in millimetres.

  • number | null

    Bottleneck cases only.

  • number | null

    Case base diameter in millimetres, ahead of the extractor groove.

  • number | null

    Rim diameter in millimetres.

  • number | null

    Rim thickness in millimetres.

  • FirearmImage[]

    Every image on file, silhouette first. Each carries an absolute, directly fetchable url.

  • integer

    Autoincrementing image id. Numeric, unlike the catalog slugs.

  • string

    Slug of the firearm this row belongs to.

  • string

    Absolute, directly fetchable URL.

  • ImageType | null

    Role of the image: primary, gallery, thumbnail, svg, render.

  • string | null

    Where the record came from: a curated entry, an inference, or an import.

  • string | null

    Licence the asset is held under, where one is recorded.

  • MediaKind | null

    What the asset is: silhouette, render, photo, schematic, model. /v1/firearms/{id}/media/{selector} addresses an asset by this.

  • string | null

    Where the bytes live: cdn for a static path, r2 for an upload we serve.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • FirearmUser[]

    Forces and agencies that have adopted it.

  • integer

    Autoincrementing row id.

  • string

    Slug of the firearm this row belongs to.

  • string

    The force, agency or organisation that adopted it.

  • string | null

    What kind of user: military, police, civilian.

  • string | null

    ISO 3166-1 alpha-2 code of the user's country.

  • integer | null

    Year of adoption, where it is known.

  • string | null

    What that user calls it, where it differs from the maker's name.

  • FirearmSchematic[]

    Exploded-view and parts diagrams on file, empty where none have been sourced.

  • integer

    Autoincrementing schematic id.

  • string

    Slug of the firearm this row belongs to.

  • string

    What the document is called.

  • SchematicType

    What a schematic document is.

  • string

    Absolute, directly fetchable URL.

  • string | null

    File format, e.g. pdf.

  • string | null

    Revision of the document, where the publisher versions it.

  • string | null

    Publisher of the document, often but not always the maker.

  • string | null

    Where the document came from.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Licence the asset is held under, where one is recorded.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

Get all variants of a firearm.

getVariants(id: string): Promise<APIResponse<Firearm[]>>
GET/v1/firearms/{id}/variants

  • stringheaderrequired

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

  • stringrequired

    Firearm slug

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmVariant[]

    The response payload.

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5.

  • string

    Display name, as the maker writes it.

  • string | null

    How this record differs from its parent: optics_ready, compact, threaded and so on. Null when the record has no parent.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredExplorer+

Get images for a firearm.

getImages(id: string): Promise<APIResponse<FirearmImage[]>>
GET/v1/firearms/{id}/images

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmImage[]

    The response payload.

  • integer

    Autoincrementing image id. Numeric, unlike the catalog slugs.

  • string

    Slug of the firearm this row belongs to.

  • string

    Absolute, directly fetchable URL.

  • ImageType | null

    Role of the image: primary, gallery, thumbnail, svg, render.

  • string | null

    Where the record came from: a curated entry, an inference, or an import.

  • string | null

    Licence the asset is held under, where one is recorded.

  • MediaKind | null

    What the asset is: silhouette, render, photo, schematic, model. /v1/firearms/{id}/media/{selector} addresses an asset by this.

  • string | null

    Where the bytes live: cdn for a static path, r2 for an upload we serve.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • integer

    Position within its list, ascending.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredBuilder+

Get computed game statistics for a firearm.

getGameStats(id: string): Promise<APIResponse<GameStats>>
GET/v1/firearms/{id}/game-stats

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmGameStats

    The response payload

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5.

  • string

    Display name, as the maker writes it.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure. These are balance numbers for game use and are not derived from the ballistics above.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

Get physical dimensions for a firearm.

getDimensions(id: string): Promise<APIResponse<Dimensions>>
GET/v1/firearms/{id}/dimensions

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmDimensions

    Physical dimensions in both metric and imperial units.

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • object

    Every dimension in millimetres and grams.

  • number | null

    Unloaded weight in grams, without magazine.

  • number | null

    Loaded weight in grams, with a full magazine.

  • number | null

    Overall length in millimetres, stock extended where it folds or collapses.

  • number | null

    Barrel length in millimetres, measured from the breech face.

  • number | null

    Height in millimetres, including sights and a fitted magazine.

  • number | null

    Width in millimetres at the widest point.

  • number | null

    Overall length in millimetres with the stock folded or collapsed. Null where it does not.

  • object

    The same measurements converted to pounds and inches.

  • number | null

    Unloaded weight in pounds, without magazine. Converted from weightEmptyG.

  • number | null

    Loaded weight in pounds, with a full magazine. Converted from weightLoadedG.

  • number | null

    Overall length in inches, stock extended where it folds or collapses. Converted from overallLengthMm.

  • number | null

    Barrel length in inches, measured from the breech face. Converted from barrelLengthMm.

  • number | null

    Height in inches, including sights and a fitted magazine. Converted from heightMm.

  • number | null

    Width in inches at the widest point. Converted from widthMm.

  • number | null

    Overall length in inches with the stock folded or collapsed. Null where it does not. Converted from foldedLengthMm.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredExplorer+

Get known military/law-enforcement adopters of a firearm.

getUsers(id: string): Promise<APIResponse<FirearmUser[]>>
GET/v1/firearms/{id}/users

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmUser[]

    The response payload.

  • integer

    Autoincrementing row id.

  • string

    Slug of the firearm this row belongs to.

  • string

    The force, agency or organisation that adopted it.

  • string | null

    What kind of user: military, police, civilian.

  • string | null

    ISO 3166-1 alpha-2 code of the user's country.

  • integer | null

    Year of adoption, where it is known.

  • string | null

    What that user calls it, where it differs from the maker's name.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredBuilder+

Get the family tree (lineage) of a firearm.

getFamilyTree(id: string): Promise<APIResponse<FamilyTree>>
GET/v1/firearms/{id}/family-tree

  • stringheaderrequired

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

  • stringrequired

    Firearm slug

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FamilyTree

    The firearm plus its ancestor and descendant variants, walked recursively.

  • FamilyMember[]

    The parent chain, nearest first, up to 20 deep.

  • string

    URL-safe slug identifying the related firearm, e.g. type-58.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    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.

  • string | null

    How this record differs from its parent: optics_ready, compact, threaded and so on. Null when the record has no parent.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • 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.

  • string | null

    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.

  • FirearmRecord

    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.

  • integer

    Integer flag, 1 when a 3D model is on file. Stored as the database holds it rather than as a boolean.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    GLB model, or null where none is on file.

  • string | null

    The ammunition load ballistics figures are quoted against, where one is nominated.

  • number | null

    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.

  • number | null

    Muzzle energy in joules exactly as the source stated it.

  • number | null

    Effective range in metres exactly as the source stated it.

  • number | null

    Maximum range in metres exactly as the source stated it.

  • string | null

    Where the ballistics figures came from, named in prose.

  • string | null

    URL of the ballistics source, where it is a page rather than a book.

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5. Stable: it is what a mirror keys on.

  • string

    Display name, as the maker writes it.

  • FamilyMember[]

    Everything derived from it, breadth-first, up to 50 rows.

  • string

    URL-safe slug identifying the related firearm, e.g. type-58.

  • string

    Display name, as the maker writes it.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    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.

  • string | null

    How this record differs from its parent: optics_ready, compact, threaded and so on. Null when the record has no parent.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • 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.

  • string | null

    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.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredExplorer+

Get firearms similar to a given firearm.

getSimilar(id: string): Promise<APIResponse<SimilarFirearm[]>>
GET/v1/firearms/{id}/similar

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • SimilarFirearm[]

    The response payload.

  • string

    Slug of the similar firearm.

  • string

    Display name, as the maker writes it.

  • number

    How alike the two records are, 0 to 1. Computed from the specifications, not from what people browse together.

  • string | null

    Slug of the manufacturer that makes it. Resolve against /v1/manufacturers/{id}.

  • string | null

    Slug of the category it belongs to. Resolve against /v1/categories.

  • string | null

    ISO 3166-1 alpha-2 code of where it was designed, e.g. AT.

  • integer | null

    Year it entered production or service. Null where the date is disputed or unknown.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • string | null

    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.

  • InlineMediaItem[]

    Every image this firearm has, silhouette first. Empty when none are on file.

  • integer

    Autoincrementing image id.

  • string

    Absolute, directly fetchable URL.

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredStudio+

Get the worldwide adoption map for a firearm.

getAdoptionMap(id: string): Promise<APIResponse<AdoptionMap>>
GET/v1/firearms/{id}/adoption-map

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • AdoptionMap

    Military and law-enforcement adoption of a firearm, grouped by country.

  • string

    Slug of the firearm this row belongs to.

  • string

    Display name of the firearm the map is for.

  • object[]

    Every country recorded as having adopted it.

  • string | null

    ISO 3166-1 alpha-2 code of the country. Null where the operator country is unrecorded.

  • object[]

    The organisations in that country recorded as operating the firearm.

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

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.

Auth RequiredBuilder+

Get the full game profile for a firearm.

getGameProfile(id: string): Promise<APIResponse<GameProfile>>
GET/v1/firearms/{id}/game-profile

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • GameProfile

    Game stats for a firearm plus its derived archetype classification.

  • string

    Slug of the firearm this profile is for.

  • string

    Display name, as the maker writes it.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure. These are balance numbers for game use and are not derived from the ballistics above.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • integer | null

    Editorial game statistic, 0-100. Not a measured figure.

  • GameArchetype

    The role a firearm's game profile assigns it.

  • string[]

    The statistics this firearm scores highest on.

  • string[]

    The statistics it scores lowest on.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

Get an SVG silhouette (line art) of a firearm.

getSilhouette(id: string, params?: SilhouetteParams): Promise<APIResponse<Silhouette>>
GET/v1/firearms/{id}/silhouette

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • stringdefaultraw

    An SVG file (raw; svg is accepted as the same thing, the name SDK 0.1.x used), an inline data URI, or the SVG source as JSON

    Accepts
    Example
  • integerdefault0

    Inject a stroke so the line art reads on any background. 0 leaves it unstroked; anything above 20 is clamped to 20

    Range
    0 – 20
    Example
  • stringdefaultblack

    Colour of that stroke. Any CSS colour the browser understands: a name, a hex value, rgb(), oklch(), color-mix(). Quotes, angle brackets, ampersands and backslashes are refused, because the value is written into an SVG attribute

    Max length
    64
    Example

  • object

    The response payload.

  • string

    Slug of the firearm.

  • string

    Display name, as the maker writes it.

  • string

    Slug of the line-art file, which is the firearm slug.

  • string

    Which JSON form this is: datauri or svg.

  • string

    Media type of the bytes, e.g. image/png.

  • string

    Present when format=datauri: the SVG inlined as an RFC 2397 data URI.

  • string

    Present when format=json: the SVG source, for parsing or manipulating in code.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

Calculate ballistics for a firearm with specific ammunition.

calculate(id: string, params: CalculateBallisticsParams): Promise<APIResponse<FirearmCalculation>>
GET/v1/firearms/{id}/calculate

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • stringrequired

    Ammunition load to fire

    Max length
    255
    Example

  • object

    Muzzle solution adjusted for this firearm barrel length, against its published figures.

  • BallisticsFirearm

    The firearm the solution was computed for. barrelLengthMm is absent when the firearm has no recorded barrel.

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5.

  • string

    Display name, as the maker writes it.

  • number

    Barrel length in millimetres, measured from the breech face.

  • object

    The load the calculation used.

  • string

    Slug of the ammunition load that was fired.

  • string

    Display name, as the maker writes it.

  • object

    The figures derived for the barrel length asked about, rather than the reference one.

  • number

    Muzzle velocity in metres per second, for the default load.

  • number

    Muzzle energy in joules, for the default load.

  • TerminalBallistics

    Terminal performance indices computed at the muzzle.

  • object

    The figures published for this firearm, where the catalog records them.

  • number | null

    Muzzle velocity in metres per second, for the default load.

  • number | null

    Muzzle energy in joules, for the default load.

  • object

    Computed minus source-reported. Null where no source figure exists to compare against.

  • number | null

    Remaining velocity at this distance, in metres per second.

  • number | null

    Remaining energy at this distance, in joules.

  • string | null

    Why the calculation could not be completed, or null when it succeeded.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

Load a firearm with ammunition and get combined performance data.

load(id: string, params?: LoadFirearmParams): Promise<APIResponse<FirearmLoadProfile>>
GET/v1/firearms/{id}/load

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • string

    Ammunition load to chamber. Defaults to the firearm default load, then the first common load for its primary caliber.

    Max length
    255
    Example

  • object

    The response payload.

  • BallisticsFirearm

    The firearm the solution was computed for. barrelLengthMm is absent when the firearm has no recorded barrel.

  • string

    URL-safe slug identifying the firearm, e.g. glock-17-gen5.

  • string

    Display name, as the maker writes it.

  • number

    Barrel length in millimetres, measured from the breech face.

  • object

    The load the calculation used.

  • string

    Slug of the ammunition load the firearm was chambered with.

  • string

    Display name, as the maker writes it.

  • string

    Slug of the cartridge. Resolve against /v1/calibers/{id}.

  • number

    Bullet weight in grams. Divide by 0.0648 for grains.

  • string

    Bullet construction: fmj, jhp, sp, match.

  • object

    The figures derived for the barrel length asked about, rather than the reference one.

  • number

    Muzzle velocity in metres per second, for the default load.

  • number

    Muzzle energy in joules, for the default load.

  • number

    Effective range in metres against a point target.

  • TerminalBallistics

    Terminal performance indices computed at the muzzle.

  • object

    The figures published for this firearm, where the catalog records them.

  • number | null

    Muzzle velocity in metres per second, for the default load.

  • number | null

    Muzzle energy in joules, for the default load.

  • number | null

    Effective range in metres against a point target.

  • TrajectoryPoint[]

    The flight path, one row per distance step.

  • number

    Distance from the muzzle in metres.

  • number

    Remaining velocity at this distance, in metres per second.

  • number

    Remaining energy at this distance, in joules.

  • number

    Bullet drop below the line of sight at this distance, in centimetres.

  • number

    Time of flight to this distance, in seconds.

  • number

    Velocity as a multiple of the speed of sound. Below ~1.2 the projectile is transonic and destabilises.

  • number

    Momentum in kilogram-metres per second.

  • number

    Taylor Knock-Out factor at this distance.

  • number

    Energy per unit frontal area, in joules per square centimetre.

  • string | null

    Why the calculation could not be completed, or null when it succeeded.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredStudio+

Get the technical schematics for a firearm. Returns exploded-view and cutaway drawings with their attribution.

getSchematics(id: string): Promise<APIResponse<FirearmSchematic[]>>
GET/v1/firearms/{id}/schematics

  • stringheaderrequired

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

  • stringrequired

    Firearm slug

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • FirearmSchematic[]

    The response payload.

  • integer

    Autoincrementing schematic id.

  • string

    Slug of the firearm this row belongs to.

  • string

    What the document is called.

  • SchematicType

    What a schematic document is.

  • string

    Absolute, directly fetchable URL.

  • string | null

    File format, e.g. pdf.

  • string | null

    Revision of the document, where the publisher versions it.

  • string | null

    Publisher of the document, often but not always the maker.

  • string | null

    Where the document came from.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Licence the asset is held under, where one is recorded.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

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

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.

Auth RequiredExplorer+

List the most viewed firearms over a trailing window.

popular(params?: { days?: number; limit?: number }): Promise<APIResponse<PopularFirearm[]>>
GET/v1/popular/firearms

  • stringheaderrequired

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

  • integerdefault7

    Trailing window in days

    Range
    1 – 30
    Example
  • integerdefault10

    How many to return

    Range
    1 – 20
    Example

  • PopularFirearm[]

    The response payload.

  • string

    Slug of the firearm. Named entity_id because the rollup counts views of any entity kind; it is id on the catalog endpoints.

  • string

    Display name of the firearm.

  • string | null

    Slug of the manufacturer. manufacturerId on the camelCase endpoints.

  • string | null

    Slug of the category. categoryId on the camelCase endpoints.

  • string | null

    ISO 3166-1 alpha-2 code of the country of origin.

  • integer | null

    Year the model was introduced.

  • FirearmStatus | null

    Production status, one of in_production, discontinued, out_of_production, in_service, limited_production, prototype. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today.

  • string | null

    Line-art silhouette, or null where none has been drawn.

  • integer

    Views recorded inside the trailing window given by days.

  • integer

    Distinct visitors behind those views. Forty views from one reader is a different fact from forty readers.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredBuilder+

Resolve a free-text name to a firearm id. Builder.

resolve(q: string): Promise<APIResponse<ResolveResult>>
GET/v1/firearms/resolve

  • stringheaderrequired

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

  • stringrequired

    The name to resolve, up to 200 characters.

    Max length
    200
    Example

  • object

    What one query resolved to.

  • string

    The query this result answers, echoed back so a batch response can be matched to its request.

  • string

    One of resolved (exactly one record), ambiguous (several equally good, none chosen) or not_found.

  • string | null

    The resolved catalog id. Null on ambiguous and not_found, since an ambiguous query is deliberately not decided for you.

  • string | null

    How the resolution was made, or null when nothing resolved. Never fuzzy: a suggestion is not a resolution.

  • number

    Confidence in the resolution, 0 to 1. Derived from how much of the query a catalogued spelling accounted for and how strong that spelling is as evidence.

  • string[]

    The words of the query a catalogued spelling accounted for.

  • string[]

    The words it did not. Reported rather than guessed at: a variant we do not hold appears here instead of being silently dropped.

  • object[]

    Other records this query could mean, best first. On ambiguous these are the tied candidates and choosing between them is yours.

  • string

    The catalog id of this candidate.

  • string

    The catalogued name of this candidate.

  • string | null

    The maker, or null where the record has none.

  • string

    How this candidate was matched. One of slug, name, alternate, shorthand, base (the name with its maker removed), family (the model designation with its trailing descriptor removed, e.g. M4 from M4 Carbine) or fuzzy.

  • string | null

    The catalogued spelling that matched, or null for a fuzzy suggestion.

  • number

    Confidence in this candidate, 0 to 1. Always 0 for a fuzzy suggestion, which is offered rather than scored.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredStudio+

Resolve many names in one request. Studio.

resolveMany(queries: string[]): Promise<APIResponse<ResolveManyResult>>
POST/v1/firearms/resolve

  • stringheaderrequired

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

  • string[]required

    The names to resolve. Between 1 and 50, each up to 200 characters.

  • object

    The response payload.

  • object[]

    One result per query, in the order the queries were sent.

  • string

    The query this result answers, echoed back so a batch response can be matched to its request.

  • string

    One of resolved (exactly one record), ambiguous (several equally good, none chosen) or not_found.

  • string | null

    The resolved catalog id. Null on ambiguous and not_found, since an ambiguous query is deliberately not decided for you.

  • string | null

    How the resolution was made, or null when nothing resolved. Never fuzzy: a suggestion is not a resolution.

  • number

    Confidence in the resolution, 0 to 1. Derived from how much of the query a catalogued spelling accounted for and how strong that spelling is as evidence.

  • string[]

    The words of the query a catalogued spelling accounted for.

  • string[]

    The words it did not. Reported rather than guessed at: a variant we do not hold appears here instead of being silently dropped.

  • object[]

    Other records this query could mean, best first. On ambiguous these are the tied candidates and choosing between them is yours.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 413PAYLOAD_TOO_LARGERequest body too large
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

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.

Auth RequiredExplorer+

Every firearm that has imagery, one row each.

mediaCatalog(params?: MediaCatalogParams): Promise<PaginatedResponse<MediaCatalogItem>>
GET/v1/firearms/media

  • stringheaderrequired

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

  • integerdefault1

    Page number

    Range
    1 – 10000
    Example
  • integerdefault250

    Firearms per page

    Range
    1 – 1000
    Example
  • string

    Restrict the images on each row to one kind

    Accepts

  • MediaCatalogEntry[]

    One firearm and the real imagery it has. Deliberately three fields: this is the index for a media grid or a mirroring job, not a catalogue row. Silhouettes are excluded: every firearm has one, and they have their own build-time manifest.

  • string

    Slug of the firearm this row is about.

  • string

    Display name, as the maker writes it.

  • InlineMediaItem[]

    The imagery on file for it, silhouette excluded, since every firearm has one of those.

  • integer

    Autoincrementing image id.

  • string

    Absolute, directly fetchable URL.

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

This read answers conditional requests. Keep the ETag from a response and send it back as If-None-Match: an unchanged record returns 304 Not Modified with no body, which counts toward your per-minute rate limit but not your daily allowance.

Auth RequiredExplorer+

Every asset on a firearm, with credit and derivative sizes.

listMedia(id: string, params?: ListFirearmMediaParams): Promise<APIResponse<FirearmMedia[]>>
GET/v1/firearms/{id}/media

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • string

    Return only one kind of asset

    Accepts
    Example

  • MediaItem[]

    The response payload.

  • integer | null

    Null for assets stored as a column rather than a row (the 3D model).

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Media type of the bytes, e.g. image/png.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • string

    Absolute, directly fetchable URL.

  • object

    Per-size URLs. Absent on assets we link rather than host.

  • string

    URL of the asset at full size.

  • string

    URL of the mid-size rendition, for a detail page.

  • string

    URL of the thumbnail rendition, for a list or grid.

  • object

    Attribution required to reuse the asset. Populated wherever the catalogue records it.

  • string | null

    Where the record came from: a curated entry, an inference, or an import.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Licence the asset is held under, where one is recorded.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredBuilder+

Metadata for one asset, by kind or by row id. Builder.

getMedia(id: string, selector: MediaKind | number | string, params?: GetFirearmMediaParams): Promise<APIResponse<FirearmMedia>>
GET/v1/firearms/{id}/media/{selector}

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example
  • unknownrequired

    Which asset: a kind, which resolves to the primary asset of that kind, or the numeric id of one row from /v1/firearms/{id}/media. Addressing by kind means never having to list first just to learn an id.

    Accepts
    or a numeric id
    Example

  • stringdefaultraw

    Bytes, an inline data URI, or metadata only

    Accepts
    Example
  • stringdefaultfull

    Pre-rendered derivative; falls back to the original when absent

    Accepts
    Example
  • integerdefault0

    Silhouettes only: inject a stroke so line art reads on any background

    Range
    0 – 20
    Example
  • stringdefaultblack

    Silhouettes only: stroke colour. Any CSS colour the browser understands; quotes, angle brackets, ampersands and backslashes are refused, because the value is written into an SVG attribute

    Max length
    64
    Example

  • MediaItem

    One asset belonging to a firearm. Every kind, whether silhouette, render, photo, schematic or 3D model, is returned in this same shape, and url is always absolute and directly fetchable.

  • integer | null

    Null for assets stored as a column rather than a row (the 3D model).

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Media type of the bytes, e.g. image/png.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • string

    Absolute, directly fetchable URL.

  • object

    Per-size URLs. Absent on assets we link rather than host.

  • string

    URL of the asset at full size.

  • string

    URL of the mid-size rendition, for a detail page.

  • string

    URL of the thumbnail rendition, for a list or grid.

  • object

    Attribution required to reuse the asset. Populated wherever the catalogue records it.

  • string | null

    Where the record came from: a curated entry, an inference, or an import.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Licence the asset is held under, where one is recorded.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

The bytes of one asset, following the redirect to the CDN. Builder.

downloadMedia(id: string, selector: MediaKind | number | string, params?: GetFirearmMediaParams): Promise<RawResponse>
GET/v1/firearms/{id}/media/{selector}

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example
  • unknownrequired

    Which asset: a kind, which resolves to the primary asset of that kind, or the numeric id of one row from /v1/firearms/{id}/media. Addressing by kind means never having to list first just to learn an id.

    Accepts
    or a numeric id
    Example

  • stringdefaultraw

    Bytes, an inline data URI, or metadata only

    Accepts
    Example
  • stringdefaultfull

    Pre-rendered derivative; falls back to the original when absent

    Accepts
    Example
  • integerdefault0

    Silhouettes only: inject a stroke so line art reads on any background

    Range
    0 – 20
    Example
  • stringdefaultblack

    Silhouettes only: stroke colour. Any CSS colour the browser understands; quotes, angle brackets, ampersands and backslashes are refused, because the value is written into an SVG attribute

    Max length
    64
    Example

  • MediaItem

    One asset belonging to a firearm. Every kind, whether silhouette, render, photo, schematic or 3D model, is returned in this same shape, and url is always absolute and directly fetchable.

  • integer | null

    Null for assets stored as a column rather than a row (the 3D model).

  • MediaKind

    What kind of asset a media row is.

  • string | null

    Media type of the bytes, e.g. image/png.

  • integer | null

    Pixel width, where it is known.

  • integer | null

    Pixel height, where it is known.

  • string | null

    Alt text, where one has been written. Null otherwise, so do not render an empty string.

  • string

    Absolute, directly fetchable URL.

  • object

    Per-size URLs. Absent on assets we link rather than host.

  • string

    URL of the asset at full size.

  • string

    URL of the mid-size rendition, for a detail page.

  • string

    URL of the thumbnail rendition, for a list or grid.

  • object

    Attribution required to reuse the asset. Populated wherever the catalogue records it.

  • string | null

    Where the record came from: a curated entry, an inference, or an import.

  • string | null

    Who made the asset, where it is credited.

  • string | null

    Page the asset or document was taken from.

  • string | null

    Licence the asset is held under, where one is recorded.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

One image as a base64 data URI. Builder. Ask for a variant. A data URI is capped at 256 KB and a catalogue original is routinely five times that, so the default request fails on exactly the images most worth embedding. thumb and display are generated derivatives and always fit; original is for the cases where you know the file is small. For the full-size bytes use downloadMedia, which redirects to the CDN and has no such cap.

getImageAsset(id: string, imageId: number | string, params?: ImageAssetParams): Promise<APIResponse<ImageAsset>>
GET/v1/firearms/{id}/images/{imageId}

  • stringheaderrequired

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

  • stringrequired

    Resource slug ID

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example
  • stringrequired

    Image row id from /v1/firearms/{id}/images

    Example

  • stringdefaultraw

    raw file, or a base64 data URI

    Accepts
    Example
  • stringdefaultoriginal

    Pre-rendered derivative; falls back to the original when absent

    Accepts
    Example

  • object

    The response payload.

  • string

    Slug of the firearm the image belongs to.

  • integer

    Numeric id of the image within that firearm image set.

  • string

    Size rendered: original, display or thumb.

  • string

    Encoding of the returned image. datauri is the only format this route emits.

  • string

    Media type of the encoded bytes.

  • string

    The image inlined as an RFC 2397 data URI, ready to use as an <img src> with no second request.

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredBuilder+

The 3D model as GLB bytes. Builder.

getModel(id: string): Promise<RawResponse>
GET/v1/firearms/{id}/model

  • stringheaderrequired

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

  • stringrequired

    Firearm slug

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

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

Minimum tier
Builder+
Monthly quota
25,000/mo
Rate limit
60/min
Daily cap
2,000

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

Auth RequiredExplorer+

Sellers stocking this firearm; link out through client.vendor.clickUrl(offer.clickId).

getOffers(id: string, params?: OffersParams): Promise<APIResponse<PublicOffer[]>>
GET/v1/firearms/{id}/offers

  • 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

    ISO 3166-1 alpha-2 code; hides sellers who do not ship there

    Example

  • PublicOffer[]

    The response payload.

  • object

    The shop stocking the part.

  • string

    Slug of the shop.

  • string

    Display name, as the maker writes it.

  • string | null

    Official website, where one is known.

  • string | null

    Absolute URL of the logo, or null where none is on file.

  • string

    The shop's own catalogue key for the listing. A seller's identifier, not ours: it is what PATCH /v1/vendor/offers/{sku} addresses.

  • integer

    Price in integer minor units of currency, so cents for AUD. Never a float. Format with Intl.NumberFormat at render rather than dividing first.

  • string

    ISO 4217 code the price is in, e.g. AUD. Prices are integer minor units; format with Intl.NumberFormat at render rather than dividing first.

  • string

    Absolute, directly fetchable URL.

  • boolean

    Whether the shop reports it in stock. Derived from stockQty where the shop tracks a count.

  • string | null

    Opaque token for the outbound link: send readers to /v1/out/{clickId} so the visit is counted for the seller. Null on a listing that cannot currently be followed.

  • string | null

    ISO 3166-1 alpha-2 code the seller ships to. Null means they state no restriction.

  • string

    When the seller last refreshed this listing. A listing not refreshed inside its freshness window is hidden rather than shown stale.

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

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

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

Auth RequiredStudio+

The mount interfaces a firearm exposes. Studio.

getInterfaces(id: string): Promise<APIResponse<FirearmInterfaces>>
GET/v1/firearms/{id}/interfaces

  • stringheaderrequired

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

  • stringrequired

    Firearm slug

    Accepts
    a lowercase slug: letters, digits and hyphens
    Example

  • 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. Reached through its own memberships and its parent chain.

  • 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.

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

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.

Auth RequiredStudio+

Attachments that fit, grouped by category, with the evidence for each. Studio.

getAttachments(id: string, params?: FirearmAttachmentsParams): Promise<APIResponse<FirearmAttachments>>
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

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.