GunSpec API
Everything you need to integrate firearms specification data into your app, game, or research project: a REST API with a free tier, typed SDKs and a live console.
https://api.gunspec.io- 9,162Firearms
- 1,003Manufacturers
- 605Calibers
- 133Operations across 124 paths
133 operations across 124 endpoints: a path that answers both GET and PUT is one endpoint and two operations, so the two figures never match. The reference counts operations; the SDKs, the agent packs and the website count endpoints.
Four steps to a first response
Ten minutes from nothing to a list of firearms in your terminal, with the refusals you will meet on the way explained before you meet them.
- 1
Get a free key
Every catalog call carries a key; 17 operations answer without one, listed on the Authentication page. A free Explorer key takes a minute and is enough to build against. Send it as
X-API-Key, or asAuthorization: Bearer. Both work everywhere.- Requests / month
- 200
- Requests / min
- 10
- Requests / day
- 50
- Pages deep
- 5
- 2
Make your first request
The list endpoint is the one to try first: it takes no arguments, answers on every plan, and shows the envelope every other list uses.
per_page=3keeps the output short.cURL
curl -H "X-API-Key: your_api_key" \ "https://api.gunspec.io/v1/firearms?per_page=3" - 3
Read the response
Every
/v1JSON success is the same envelope:success,data, and on a list,pagination. Two things sit outside it on purpose. The/healthand/readyprobes answer a flat{ status }body, since a load balancer reads them and never a client. A handful of operations answer with a file or a redirect instead: the bullet diagram, raw media and 3D model downloads, and the seller click tracker’s 302, all listed on the media page. The sample below is what an Explorer key receives, 5 fields per row, built from the spec’s own examples.GET /v1/firearms on Explorerjson{ "success": true, "data": [ { "id": "glock-17-gen5", "name": "Glock 17 Gen5", "manufacturerId": "glock", "updatedAt": "2026-09-10 06:42:19", "version": "a3f1c2d4e5b6a7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2" }, /* two more rows */ ], "pagination": { "page": 1, "per_page": 3, "limit": 3 }}datais one page. Walk the rest withpageand stop on a short page; the pagination page has the loop that works on every plan.pagination.totalandtotalPagesare absent on Explorer: the free plan does not see how big the catalog is. They appear from Builder up.- Explorer rows carry 5 fields. The full record, including dimensions, ballistics, materials and media, is in the field reference and unlocks with a paid plan.
- 4
Handle a refusal
A refused request is the same envelope with
success: falseand anerrorcarrying a stablecode, a specificreason, a message and arequest_id. These four are the ones a first integration meets, in the order it meets them.- 401
KEY_MISSINGNo API key was sent. Send your key in the
X-API-Keyheader. The credential is valid and its plan is below what this endpoint needs.
details.requiredTiernames the plan. Upgrade the plan. A new key on the same plan will get the same answer.- 429
RATE_LIMITEDToo many requests this minute for the plan. Wait for
Retry-Afterseconds, then retry. The plan's daily request allowance is used up. It resets at midnight UTC. Wait for the reset, or upgrade for a larger allowance.
Pick your path
Where to go next depends on what you are building. Each card is one page.
The basics
Eight things every integration meets, one line each. The linked page has the rest.
- AuthenticationX-API-Key or Bearer; 401 is your credential, 403 is your plan.
- Paginationpage and per_page; stop on a short page, not on totalPages.
- ErrorsOne envelope, a stable code, a specific reason, a request id.
- Rate limitsPer minute, per day and per month, with Retry-After on a 429.
- CachingETag on every catalog response; a 304 costs no daily quota.
- WebhooksSigned deliveries when the catalog changes, on Studio and up.
- Versioning/v1 is the contract; additive changes land, breaking ones move.
- SecurityWhat protects the platform and how to report a weakness.