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.
Properties
| Name | Type | Description |
|---|---|---|
| id | string | URL-safe slug identifying the firearm. Stable: it is what a mirror keys on. |
| name | string | Display name, as the maker writes it. |
| manufacturer_id | stringnull | Slug of the manufacturer. `manufacturerId` on the camelCase endpoints. |
| category_id | stringnull | Slug of the category. `categoryId` on the camelCase endpoints. |
| manufacturer_name | stringnull | Display name of the manufacturer, joined in so a result row needs no second call. |
| category_name | stringnull | Display name of the category. |
| category_slug | stringnull | Slug of the category again, under the name the search view uses. Same value as `category_id`. |
| year_introduced | integernull | Year the model was introduced. |
| status | object | 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 |
| country_of_origin | stringnull | ISO 3166-1 alpha-2 code of the country of origin. |
| action_type | stringnull | 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. |
| weight_empty_g | numbernull | Unloaded weight in grams, without magazine. |
| barrel_length_mm | numbernull | Barrel length in millimetres, measured from the breech face. |
| svg_line_art_url | stringnull | Line-art silhouette, or null where none has been drawn. |
| model_3d_url | stringnull | GLB model, or null where none is on file. |
| favorite_count | integer | How many accounts have favorited this record. |
| rank | numbernull | 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 plai |
| images | array | Every image this firearm has, silhouette first. Empty when none are on file. |
| matched_name | stringnull | 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 mo |
| matched_name_kind | stringnull | `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. |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/gunspec-io/json-schema/gunspec-io-firearm-search-result-schema.json",
"title": "FirearmSearchResult",
"description": "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.",
"x-generated": "2026-10-30",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/gunspec-io-openapi.json#/components/schemas/FirearmSearchResult",
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "URL-safe slug identifying the firearm. Stable: it is what a mirror keys on."
},
"name": {
"type": "string",
"description": "Display name, as the maker writes it."
},
"manufacturer_id": {
"type": [
"string",
"null"
],
"description": "Slug of the manufacturer. `manufacturerId` on the camelCase endpoints."
},
"category_id": {
"type": [
"string",
"null"
],
"description": "Slug of the category. `categoryId` on the camelCase endpoints."
},
"manufacturer_name": {
"type": [
"string",
"null"
],
"description": "Display name of the manufacturer, joined in so a result row needs no second call."
},
"category_name": {
"type": [
"string",
"null"
],
"description": "Display name of the category."
},
"category_slug": {
"type": [
"string",
"null"
],
"description": "Slug of the category again, under the name the search view uses. Same value as `category_id`."
},
"year_introduced": {
"type": [
"integer",
"null"
],
"description": "Year the model was introduced."
},
"status": {
"anyOf": [
{
"$ref": "#/$defs/FirearmStatus"
},
{
"type": "null"
}
],
"description": "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."
},
"country_of_origin": {
"type": [
"string",
"null"
],
"description": "ISO 3166-1 alpha-2 code of the country of origin."
},
"action_type": {
"type": [
"string",
"null"
],
"description": "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."
},
"weight_empty_g": {
"type": [
"number",
"null"
],
"description": "Unloaded weight in grams, without magazine."
},
"barrel_length_mm": {
"type": [
"number",
"null"
],
"description": "Barrel length in millimetres, measured from the breech face."
},
"svg_line_art_url": {
"type": [
"string",
"null"
],
"description": "Line-art silhouette, or null where none has been drawn."
},
"model_3d_url": {
"type": [
"string",
"null"
],
"description": "GLB model, or null where none is on file."
},
"favorite_count": {
"type": "integer",
"description": "How many accounts have favorited this record."
},
"rank": {
"type": [
"number",
"null"
],
"description": "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."
},
"images": {
"type": "array",
"description": "Every image this firearm has, silhouette first. Empty when none are on file.",
"items": {
"$ref": "#/$defs/InlineMediaItem"
}
},
"matched_name": {
"type": [
"string",
"null"
],
"description": "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."
},
"matched_name_kind": {
"type": [
"string",
"null"
],
"enum": [
"alternate",
"edition",
null
],
"description": "`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."
}
},
"required": [
"id",
"name"
],
"$defs": {
"FirearmStatus": {
"type": "string",
"enum": [
"in_production",
"discontinued",
"out_of_production",
"in_service",
"limited_production",
"prototype"
],
"description": "Production status of a firearm. Closed: these are every value the catalog holds."
},
"InlineMediaItem": {
"type": "object",
"description": "One image attached to a firearm, inlined on list-shaped responses so a client can render a gallery without a second request. `url` is absolute and directly fetchable. For the full envelope, including credits, licence, dimensions and data-URI encoding, use `/v1/firearms/{id}/media`.",
"properties": {
"id": {
"type": "integer",
"description": "Autoincrementing image id."
},
"url": {
"type": "string",
"description": "Absolute, directly fetchable URL."
},
"kind": {
"$ref": "#/$defs/MediaKind"
},
"alt": {
"type": [
"string",
"null"
],
"description": "Alt text, where one has been written. Null otherwise, so do not render an empty string."
},
"width": {
"type": [
"integer",
"null"
],
"description": "Pixel width, where it is known."
},
"height": {
"type": [
"integer",
"null"
],
"description": "Pixel height, where it is known."
}
},
"required": [
"id",
"url",
"kind"
]
},
"MediaKind": {
"type": "string",
"enum": [
"silhouette",
"render",
"photo",
"schematic",
"model"
],
"description": "What kind of asset a media row is."
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/gunspec-io-firearm-search-result"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.