API
ReferenceMarket data

Single listing

GET
/public/v1/listings/{id}

One active listing by its id, with the same per-game item fields as GET /public/v1/listings. Use it to re-check a listing you already know about — after a listing.price_changed event, or right before a purchase — instead of paging the whole book. Returns 404 LISTING_NOT_FOUND once the listing is sold or delisted, which is the cheapest way to confirm a listing is gone.

AuthorizationBearer <token>

API key generated from your account settings on the website. Send as Authorization: Bearer csd_....

In: header

Path Parameters

id*number

Listing id

Response Body

application/json

curl -X GET "https://example.com/public/v1/listings/0"
{  "id": 1,  "app_id": 1,  "market_hash_name": "string",  "price": -9007199254740991,  "amount": -9007199254740991,  "commodity": true,  "created_at": "2019-08-24T14:15:22Z",  "steam_asset_id": "string",  "icon_url": "string",  "trade_locked_until": "2019-08-24T14:15:22Z",  "cs_weapon": "string",  "cs_type": "string",  "cs_wear": "string",  "cs_rarity": "string",  "cs_collection": "string",  "cs_is_stattrak": true,  "cs_is_souvenir": true,  "cs_is_highlight": true,  "cs_inspect_link": "string",  "cs_paint_wear": 0,  "cs_paint_seed": -9007199254740991,  "cs_paint_index": -9007199254740991,  "cs_fade_percentage": 0,  "cs_blue_percentage": 0,  "cs_stickers": [    {      "slot": -9007199254740991,      "sticker_id": -9007199254740991,      "name": "string",      "image": "string",      "wear": 0,      "scale": 0,      "rotation": 0,      "tint_id": -9007199254740991,      "offset_x": 0,      "offset_y": 0,      "offset_z": 0,      "pattern": -9007199254740991    }  ],  "cs_keychains": [    {      "slot": -9007199254740991,      "sticker_id": -9007199254740991,      "name": "string",      "image": "string",      "wear": 0,      "scale": 0,      "rotation": 0,      "tint_id": -9007199254740991,      "offset_x": 0,      "offset_y": 0,      "offset_z": 0,      "pattern": -9007199254740991    }  ],  "rust_category": "string",  "rust_type": "string",  "rust_collection": "string",  "dota_rarity": "string",  "dota_hero": "string",  "dota_quality": "string",  "dota_type": "string",  "dota_slot": "string",  "dota_collection": "string",  "dota_event": "string",  "tf2_classes": [    "string"  ],  "tf2_quality": "string",  "tf2_effect": "string",  "tf2_wear": "string",  "tf2_spells": [    "string"  ],  "tf2_warpaint": "string",  "tf2_sheen": "string",  "tf2_collection": "string",  "tf2_grade": "string",  "tf2_paint_color": "string",  "tf2_attributes": {    "craftable": true,    "uncraftable": true,    "festivized": true,    "strange_parts": true,    "holiday_restricted": true  },  "tf2_wiki_link": "string",  "tf2_inspect_link": "string",  "tf2_type": "string"}

Book snapshot GET

Every active listing in one response, plus `seq` (an `int64`), the sequence number of the last WebSocket event published before the snapshot was taken. Use it to seed a local book: buffer WebSocket events, load the snapshot, drop events with `seq <=` the snapshot's, apply the rest. Optional `app_id` filter, worth passing since it cuts a large payload down to the game you trade. Rows are deliberately lean: price/amount state only, no per-game item fields; item detail comes from `GET /public/v1/listings` or the `listing.created` events. Snapshots are cached for 10 seconds and carry an `ETag`, so a repeat call within that window is free; the cached `seq` is the one the snapshot is valid at, which is all the sync protocol needs. Heavily rate-limited: it exists for (re)synchronization, not polling. If you want item prices rather than individual live listings, use `GET /public/v1/prices/all` instead, which is far cheaper for both of us.

Listings GET

Paginated active listings, newest first, each with the full per-game item fields (`cs_paint_wear`, `cs_paint_seed`, `cs_stickers`, `cs_inspect_link`, and the Rust/Dota/TF2 equivalents); fields for other games are `null`. Filter by `app_id` (730 = CS2, 252490 = Rust, 570 = Dota 2, 440 = TF2); anything finer (float ranges, stickers) is meant to be filtered client-side. Prices are integers in cents. Pass `cursor` (a listing id) to page stably through a churning book: each response's `next_cursor` is the value for the next request, `null` when exhausted. `page` remains available for offset pagination. `limit` accepts only `500` or `1000`, and the route allows one request per second — page in bulk rather than polling small pages.