Quick start
All routes are read-only and return JSON. Use /api/v1 for new integrations; the unversioned /api prefix remains available for compatibility. Every file in the repository’s data/ directory becomes a dataset endpoint automatically.
curl https://gzw-data.dev/api/v1/weaponsconst response = await fetch("https://gzw-data.dev/api/v1/weapons");
const payload = await response.json();import requests
payload = requests.get("https://gzw-data.dev/api/v1/weapons").json()Use the JavaScript / TypeScript package
Skip handwritten fetch code with the zero-dependency client for Node.js 18+, browsers, JavaScript and TypeScript.
npm install @zoniboy/gzw-data-clientimport { GzwDataClient } from "@zoniboy/gzw-data-client";
const gzw = new GzwDataClient();
const weapons = await gzw.dataset("weapons").list();
console.log(weapons.data);Get one record
Dataset records can be fetched directly by exact ID:
curl https://gzw-data.dev/api/v1/weapons/ak-12The JavaScript client exposes the same route through dataset.get(id).
Dataset metadata
Inspect generated field metadata without downloading a full dataset:
curl https://gzw-data.dev/api/v1/metadata/weaponscurl https://gzw-data.dev/api/v1/schema/weaponsThe response includes item count, observed fields, detected types, optional/nullable flags and a stable example value. Use /api/v1/schema/{dataset} when a code generator or validator needs one machine-readable dataset schema.
Version information
Inspect the API version, current data snapshot, dataset count, and canonical integration links without loading a full dataset.
curl https://gzw-data.dev/api/v1/versioncurl https://gzw-data.dev/api/v1/changesChanges compare dataset counts with the latest stored snapshot. The first snapshot reports no changes until a second snapshot exists.
Endpoints
— datasets are currently exposed. This list is populated from the live API, so new scraper categories appear here automatically.
Filters, search & pagination
Query any dataset with the same small set of composable parameters. Filters match string fields and can be combined with pagination.
https://gzw-data.dev/api/v1/keys?type=Keycard&search=alpha&page=1&per_page=20Response format
All successful responses include data, source, timestamp and dataVersion. Paginated routes add count, page, perPage, total and totalPages. Unpaginated collections omit only the pagination fields. Single-record routes return an object in data, not an array.
{
"data": [ ... ],
"count": 10,
"page": 1,
"perPage": 50,
"total": 2141,
"totalPages": 43,
"source": "GZW Data API",
"timestamp": "2026-09-20T08:00:00.000Z",
"dataVersion": "2026-09-14T13:05:54.486874Z"
}Error envelope
HTTP errors use the same stable shape: error.code, error.message, optional route details, source, timestamp and dataVersion. Common codes include DATASET_NOT_FOUND, RECORD_NOT_FOUND, METHOD_NOT_ALLOWED, RATE_LIMITED and INTERNAL_ERROR. The complete contract is available in API_CONTRACT.md.
Limits & cache
Rate limit
Best-effort: 100 requests/minute/IP. The sliding-window counter lives in the memory of each warm Vercel function instance, so it is not a strict global quota across all instances. Responses expose X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A blocked request returns 429 with Retry-After. Cache responses and respect the retry delay.
Cache behavior
Data endpoints send Cache-Control: public, max-age=300. Cache in your client when you can; the wiki-backed data is refreshed by the weekly scraper.
Support & security
support@gzw-data.devGeneral questions and support
security@gzw-data.devPrivate vulnerability reports
