Read-only access to Counter-Strike 2 item data, derived from the game files.
Base URL /api/v1. The machine-readable description lives at
/api/v1/openapi.yaml (OpenAPI 3.1) and is
the authority; this page is the short version.
market_hash_name is always English and is the string Steam uses.
name is whatever language you asked for. Looking a localised name up on the
market finds nothing, which is the confusion this API exists to prevent.
Slugs are unique within a resource type and not across them:
revolution-case answers on /items, /variants and
/containers, and means a different thing on each. Every reference in a
response therefore carries a type next to its id — build URLs
from those two together, never from the id alone.
image_url is a path under /items/ and is absent for a few
entities the archive has no art for; wear
exists only on a finish; name is missing for the few entities Valve ships
without an English string. The keys are always present.
| Endpoint | What it gives you |
|---|---|
| GET /meta | Dataset version, build time and counts |
| GET /locales | Languages, with coverage measured against English |
| GET /resolve?name= | A name to one variant. Any supported language, or a market hash name |
| GET /search?q= | Prefix completions, minimum two characters |
| GET /categories | Root sections of the tree |
| GET /categories/{slug} | One section: children, breadcrumbs, paginated items |
| GET /items | Items, filtered by kind, rarity, category or collection |
| GET /items/{slug} | One item, its variants and its neighbours |
| GET /variants/{slug} | One market listing |
| GET /collections | Collections |
| GET /collections/{slug} | One collection and what is in it |
| GET /containers | Cases, capsules and packages |
| GET /containers/{slug} | One container and what drops out of it |
| GET /tournaments | Tournaments |
| GET /tournaments/{slug} | One tournament and its stickers |
| GET /rarities | The rarity ladder |
curl -s "https://cs-items.udev.run/api/v1/resolve?name=Revolution%20Case"
# Russian in, English market name out
curl -s "https://cs-items.udev.run/api/v1/resolve?name=%D0%9A%D0%B5%D0%B9%D1%81%20%C2%AB%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%BC%C2%BB"
curl -s "https://cs-items.udev.run/api/v1/items?filter[kind]=knife&per_page=5"
?locale= wins over Accept-Language. An unsupported explicit
locale is a 422 rather than a quiet fallback, so you cannot cache the wrong
language under the right key; an Accept-Language we cannot match falls back
to English without complaint.
Every response carries an ETag covering the dataset version, the path and
the language, plus X-Dataset-Version. Send the ETag back as
If-None-Match and you will get a 304.
Reads are public and rate limited by IP. A token raises the ceiling rather than granting
access; ask the maintainer for one. A 429 carries Retry-After.
One shape for every failure. Branch on code, which is stable; message is prose and may change.
{
"error": {
"code": "not_found",
"message": "No item matches that name.",
"details": { "suggestions": [ ... ] }
}
}
/api/items and
/api/user read the raw extraction rather than the published dataset. They
still answer, now rate limited and with a page-size ceiling, and every response carries
Deprecation, Sunset and a Link to the replacement.
They stop answering on 2027-03-03.
Use /api/v1/items.