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+
client.firearms.list()
List firearms with optional filters and pagination.
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
application/json
FirearmListItem[]
One page of results
string
URL-safe slug identifying the firearm, e.g. glock-g17-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.
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+
client.firearms.listAutoPaging()
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.
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
application/json
FirearmListItem[]
One page of results
string
URL-safe slug identifying the firearm, e.g. glock-g17-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.
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.
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
string
Only matches from this manufacturer slug
Max length
100
Example
string
Only matches in this category slug
Max length
100
Example
string
Only matches with this action type, as stored and underscored. The vocabulary is /v1/firearms/action-types
Max length
100
Example
string
Only matches from this ISO 3166-1 alpha-2 country code
Max length
10
Example
application/json
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.
string | null
The firearm's alternate name the query matched, when its own name did not: a special edition is filed as an alternate name on the model it is an edition of, so searching for the edition returns the model with the edition's name here. Null when the record's own name matched, or the match came from the maker, a caliber or the description.
string | null
edition when matched_name is an edition of this model (a limited, anniversary, engraved or finish edition), alternate when it is another name for it. Null when matched_name is null.
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.
Your API key. Authorization: Bearer <key> is accepted in its place.
stringrequired
Comma-separated firearm slugs, maximum 5
Example
application/json
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-g17-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.
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+
client.firearms.loadCarriage()
Compare the metabolic cost of a foot march carrying each of up to 5 firearms. Builder. Each firearm is carried empty plus magazines full magazines and the named attachments, on top of kit_kg of other equipment, costed by the LCDA backpacking equation (Looney et al. 2022) or, with model: 'pandolf', the Pandolf equation (1977). Masses come from the catalogue: a firearm missing its empty or loaded weight is answered with an error in place of its cost, and the others are still compared. Energy expenditure only: neither model predicts fatigue, marksmanship or time to exhaustion.
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+
client.firearms.recoil()
Compare the free recoil of each of up to 5 firearms firing a load. Builder. By the free recoil formula SAAMI publishes: the bullet's momentum, and the powder gas's at SAAMI's gas velocity factor for the class of firearm, over the firearm's recorded mass. The muzzle velocity is the one computed for each firearm's own barrel. The catalogue holds no powder charge: without powder_charge_g only the bullet is counted and every figure is a lower bound (recoil.lowerBound). Free recoil, not felt recoil.
Your API key. Authorization: Bearer <key> is accepted in its place.
stringrequired
Comma-separated firearm slugs, maximum 5.
Example
string
The load every firearm fires. Without it, each fires the load its ballistic profile uses.
Example
stringdefaultloaded
Which recorded weight the firearm recoils with: loaded or empty.
Accepts
Example
number
The load's powder charge in grams. Needs ammo_id. Without it the figures are a lower bound.
Range
0 – 100
string
The SAAMI class whose gas velocity factor applies, in place of the one read from each firearm's category: rifle (high powered rifles, 1.75), shotgun (shotguns (average length), 1.5), shotgun_long_barrel (shotguns (long barrel), 1.25), handgun (pistol & revolvers, 1.5).
Accepts
application/json
object
The response payload.
object
The formula behind every figure in the answer.
string
The method the figures were computed with.
string
The method by name.
string
The equation as written, with its units, so the figures can be reproduced.
object[]
Where the formula and its factors are from.
object
SAAMI's gas velocity factor for each class, as a multiple of the muzzle velocity.
object
The shot every firearm was answered for.
string
Which recorded weight was asked for.
number | null
The powder charge given, in grams. Null when none was.
string | null
The class given in the query. Null when each firearm's class came from its category.
boolean
True when no powder charge was given, so every figure is a lower bound.
string[]
The query parameters not sent, answered from their defaults.
object[]
One result per firearm, in the order their ids were given.
object
The firearm this result is for.
object | null
The load fired: the one named by ammo_id, or the one /v1/firearms/{id}/load fires this firearm with. Null when there is none.
object
The mass that recoils.
number | null
The load's muzzle velocity from this firearm's barrel, in m/s.
object
The powder gas term.
object | null
The free recoil. Null when a figure it needs is not recorded; error says which.
object | null
Against the option with the least recoil energy. Null on that option, on a lone firearm, and where no recoil was computed.
string[]
What an answer assumed in place of a missing figure, or why the gas was not counted.
string | null
Why this firearm could not be answered. Null when it was.
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+
client.firearms.pointBlank()
Compare the maximum point-blank range and supersonic range of up to 5 firearms. Builder. On the trajectory the ballistic profile flies (the same load, the firearm's own barrel, the same solver, the ICAO standard atmosphere): the furthest distance the bullet stays within half target_mm of the line of sight, the zero that gives it, and how far it stays supersonic.
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+
client.firearms.ammoLoad()
Compare how much ammunition each of up to 5 firearms carries per kilogram. Builder. Derived figures (a full magazine as loaded less empty weight, rounds per kilogram, what budget_kg holds) and estimated ones (a basic load's mass by the fitted cartridge-mass model, with its error as a range) are labelled and never mixed. A derived magazine lighter than its rounds is reported with a warning.
Your API key. Authorization: Bearer <key> is accepted in its place.
stringrequired
Comma-separated firearm slugs, maximum 5.
Example
string
A load whose bullet the estimate uses, for the firearms that fire its cartridge. Without it, each cartridge's typical bullet.
Example
numberdefault5
A weight of full magazines to fill, in kg.
Range
0.1 – 100
Example
integerdefault7
Full magazines in the estimated basic load.
Range
0 – 50
Example
integer
Rounds in the estimated basic load. Default: magazines times the capacity.
Range
1 – 10000
application/json
object
The response payload.
object
The method behind every figure in the answer.
string
The method the figures were computed with.
string
The method by name.
string
The arithmetic and the model as written, with units, so the figures can be reproduced.
number
The model's largest error on its reference cartridges, in percent: the range every estimate carries.
number[]
The smallest and largest case envelope the model was fitted on, in cm³.
object[]
The cartridges the model was fitted to.
object
The load every firearm was answered for.
number
The weight budget in kg.
integer
Full magazines in the estimated basic load.
integer | null
Rounds in the estimated basic load, as given. Null when each firearm's came from its capacity.
string | null
The load named, if any.
string[]
The query parameters not sent, answered from their defaults.
object[]
One result per firearm, in the order their ids were given.
object
The firearm this result is for.
object | null
The cartridge the estimate is for. Null when the firearm records none.
object | null
A full magazine, derived. Null when the feed is not detachable or a weight or the capacity is not recorded.
object | null
What budget_kg of full magazines holds. Null when no full magazine was derived.
object | null
A basic load's mass by the cartridge-mass model. Null when the cartridge lacks the figures the model needs.
object | null
Against the option that carries the most rounds per kilogram, leaving out any magazine the model finds lighter than its rounds. Null on that option, on a lone firearm, and where no magazine was derived.
string[]
Why a figure is missing, or why a derived one is doubtful.
string | null
Why nothing could be computed for this firearm. Null when anything was.
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+
client.firearms.gameMeta()
Retrieve game metadata for firearms (archetypes, stat ranges, etc.).
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.
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+
client.firearms.filterOptions()
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.
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+
client.firearms.random()
Get a random firearm, optionally filtered by category or country.
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
application/json
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.
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.
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
application/json
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.
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.
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
application/json
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[]
Every feature this firearm carries, not only the one filtered on.
string | null[]
The drawn icon each of features borrows, as its URL on the assets CDN (a WebP that loads without a key), in the same order, or null for a feature no drawing fits. Null where features is.
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.
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
application/json
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.
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.
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.
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.
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+
client.firearms.timeline()
Get firearms arranged in a chronological timeline.
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
application/json
TimelineEntry[]
One page of results
string
URL-safe slug identifying the firearm, e.g. glock-g17-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.
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.
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.
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-g17-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.
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[]
Safety mechanisms the design carries.
string[]
Notable features of the design.
string[]
How the firearm is fed.
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[]
Other names and designations the same firearm is known by.
string[]
Firing modes the selector offers.
object[]
Conflicts the firearm saw service in.
string
The conflict.
string
When it ran, as written.
string[]
The belligerents.
object | null
How many were made, and over what period.
integer | null
Units believed produced.
string | null
The production run, as written.
string | null
What the estimate covers.
string | null
Historical trivia / game-dev flavor text
string[]
Source URLs the record was compiled from. Check a specific figure against these rather than against dataConfidence. The same list is in provenance.sources.
string | null
When a source was last read against the record's figures. Null until one has been. The same value is in provenance.verifiedAt.
string[]
The figures a source confirmed: read off the manufacturer's own page, within the published tolerance, and accepted by a person. The same list is in provenance.verifiedFields.
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.
string | null
The first cited page on the record's own manufacturer's website, or null when it cites none. A page on another maker's site does not count. Cited from the maker is not the same as checked against it: verifiedFields names the figures that were read against a source.
string
How far the record's figures are backed, strongest first, for a badge: verified when at least one figure was read against a source (verifiedFields), maker when it cites a page on its own manufacturer's site (makerSource), authority when it cites a maker, standards body or government page, secondary when it cites only press, retailers, references or forums, none when it cites nothing. Derived from the fields beside it.
object
The checks the record has been through, on a single record's response only: every task the data agent (Redback) or a person was given about it, what each proposed, the pages it read, and whether a person accepted it. Nothing an agent proposes reaches the record until a person accepts it, so this is the trail behind verifiedFields. Who reviewed is not published; an agent's instance name is.
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.
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.
URL-safe slug identifying the firearm, e.g. glock-g17-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.
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-g17-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.
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.
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
application/json
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.
Ammunition load to chamber. Defaults to the firearm default load, then the first common load for its primary caliber.
Max length
255
Example
integer
Zero distance in metres, where the bullet crosses the line of sight. Defaults to 25 for a handgun and 100 for a long gun.
Range
10 – 1000
Example
number
Line of sight above the bore, in mm. Defaults to 20 for a handgun and 38 for a long gun.
Range
0 – 150
Example
application/json
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-g17-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.
Zeroing
How the gun is assumed sighted for pathCm. Neither figure is recorded per gun, so each is an assumption the caller may override with zero_m and sight_height_mm: a handgun zeroed at 25 m with its sights 20 mm above the bore, a long gun at 100 m with an optic 38 mm above it.
number
The distance at which the bullet crosses the line of sight, in m.
number
The line of sight above the bore, in mm.
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
Drop below the bore line at this distance, in cm: the fall under gravity alone, with no sighting.
number
Height relative to the line of sight at this distance, in cm, negative below: how a drop table reads, for the answer's zeroing (the gun zeroed at zeroM with its sights sightHeightMm above the bore). Starts at minus the sight height at the muzzle and is 0 at the zero.
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.
Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.
Auth RequiredExplorer+
client.firearms.popular()
List the most viewed firearms over a trailing window.
popular(params?: { days?: number; limit?: number }): Promise<APIResponse<PopularFirearm[]>>
GET/v1/popular/firearms
Explorer+
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
application/json
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.
Your API key. Authorization: Bearer <key> is accepted in its place.
stringrequired
The name to resolve, up to 200 characters.
Max length
200
Example
application/json
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.
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.
Your API key. Authorization: Bearer <key> is accepted in its place.
application/json
string[]required
The names to resolve. Between 1 and 50, each up to 200 characters.
application/json
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.
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
string
Only these firearms, as a comma-separated list of ids (at most 24). A firearm with no imagery is left out of the answer.
Example
application/json
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.
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+
client.firearms.listMedia()
Every asset on a firearm, with credit and derivative sizes.
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.
WebP by default: display is full size with transparency, thumb a small preview, full the uploaded file (usually PNG). A missing derivative falls back to the original
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
application/json
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).
MediaItemKind
What kind of asset a media listing item is: a stored kind, or feature_icon, the drawn icon for one of the firearm's features.
string
On a feature_icon only: the tag in the firearm's features this drawing illustrates, exactly as the record carries it.
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.
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.
WebP by default: display is full size with transparency, thumb a small preview, full the uploaded file (usually PNG). A missing derivative falls back to the original
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
application/json
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).
MediaItemKind
What kind of asset a media listing item is: a stored kind, or feature_icon, the drawn icon for one of the firearm's features.
string
On a feature_icon only: the tag in the firearm's features this drawing illustrates, exactly as the record carries it.
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.
Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.
Auth RequiredBuilder+
client.firearms.getImageAsset()
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}
Builder+
stringheaderrequired
Your API key. Authorization: Bearer <key> is accepted in its place.
WebP by default: display is full size with transparency, thumb a small preview, original the uploaded file (usually PNG). A missing derivative falls back to the original
Accepts
Example
application/json
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.
ISO 3166-1 alpha-2 code; hides sellers who do not ship there
Example
application/json
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 | null
The domain the shop has proved it controls, by a DNS record or a file on the site, re-checked daily. Null when it has not, which is not a sign the shop is untrustworthy: most have simply not done it yet.
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.
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.
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
application/json
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.