Appearance
Available Items
GET /api/v1/merchant/purchase/available
Returns available items with purchase prices for a given game.
Request
Headers
| Header | Required | Description |
|---|---|---|
X-Api-Key | ✅ | Your merchant API key |
Accept | — | application/json |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
game | string | ✅ | Game code: csgo, rust, dota2, tf2 |
full | boolean | — | When true, returns individual items with full details. Default (omitted or false) returns items grouped by name |
extended | boolean | — | When true, includes class_id, instance_id, float, inspect_url, phase fields in each item (full format only) |
page | integer | — | Fetch one page of the catalogue instead of all of it. 1 to 16. Omit for the whole catalogue in a single response |
Pagination
The full catalogue is large enough that taking it in one response is awkward. Pass page to walk it in parts instead.
There are always 16 pages, for every game and every merchant. A page is not a range of positions ("items 100 000 to 200 000"): it is a fixed slice of the catalogue keyed by item id. That is what makes a walk safe — items sold or added between two of your requests do not shift anything, so a walk from page 1 to page 16 never skips an item and never returns one twice, even if the catalogue changes underneath you.
Pages are not equal in size: each holds a fixed slice of the catalogue, not a fixed number of items, so a page of a large game carries more than a page of a small one.
bash
curl "https://api.skinslink.com/api/v1/merchant/purchase/available?game=csgo&full=true&extended=true&page=1" \
-H "X-Api-Key: your-api-key" \
--compressedA paginated response carries the same items as an unpaginated one, with the walk's fields in front of them:
json
{
"success": true,
"message": "Successfully retrieved purchase prices",
"data": {
"game": "csgo",
"total": 48000,
"page": 1,
"total_pages": 16,
"count": 3010,
"next": "https://api.skinslink.com/api/v1/merchant/purchase/available?extended=true&full=true&game=csgo&page=2",
"previous": null,
"items": [ ... ],
"last_update_at": "2026-08-21T14:00:00Z"
}
}| Field | Type | Description |
|---|---|---|
page | integer | The page you asked for |
total_pages | integer | Always 16 |
count | integer | Items on this page. Note this is not the catalogue size — that is total |
total | integer | Items in the whole catalogue available to you |
next | string | null | URL of the next page, null on the last one |
previous | string | null | URL of the previous page, null on the first one |
Follow next until it is null, or loop pages 1 through 16 — a page past the last one simply returns an empty items list rather than an error.
Two things worth knowing:
503means retry, not failure. A page is served from the pre-built catalogue only. While it is being rebuilt you get503with aRetry-Afterheader; wait that long and ask for the same page again. Your walk continues where it left off.- An item added after you passed its page arrives on your next walk, not this one. Nothing is lost — it simply appears one cycle later.
With full=false the response is small enough that pagination has nothing to do: it comes back as page 1 of 1, so the same loop works against both modes.
ETag is per page: send it back as If-None-Match and an unchanged page answers 304 with no body.
Response
Grouped format (default)
json
{
"success": true,
"message": "Successfully retrieved purchase prices",
"data": {
"game": "csgo",
"total": 542,
"items": [
{
"name": "AK-47 | Redline",
"count": 3,
"price": 11.20,
"game": "csgo",
"image_url": "https://steamcommunity-a.akamaihd.net/economy/image/class/730/..."
}
]
}
}Full format (full=true)
json
{
"success": true,
"message": "Successfully retrieved purchase prices",
"data": {
"game": "csgo",
"total": 1847,
"items": [
{
"id": "38029384123",
"name": "AK-47 | Redline (Field-Tested)",
"price": 12.45,
"image_url": "https://steamcommunity-a.akamaihd.net/economy/image/class/730/...",
"exterior": "Field-Tested",
"rarity": "Classified",
"rarity_color": "#8650AC"
}
]
}
}Response Fields (grouped)
| Field | Type | Description |
|---|---|---|
game | string | Game code |
total | integer | Number of unique item names |
items | array | List of items grouped by name |
items[].name | string | Item name |
items[].count | integer | Number of items available with this name |
items[].price | number | Minimum price among items with this name (USD) |
items[].game | string | Game code |
items[].image_url | string | Steam CDN image URL |
Response Fields (full)
| Field | Type | Description |
|---|---|---|
game | string | Game code |
total | integer | Total number of available items |
items | array | List of available items with prices |
items[].id | string | ID — use this in Create Purchase |
items[].name | string | Item market name |
items[].price | number | Purchase price (USD) |
items[].image_url | string | Steam CDN image URL |
items[].exterior | string | null | Item exterior condition (e.g. "Field-Tested", "Minimal Wear"). Omitted if unavailable |
items[].rarity | string | null | Item rarity name. Omitted if unavailable |
items[].rarity_color | string | null | Rarity color hex code. Omitted if unavailable |
items[].class_id | integer | null | Steam class ID. Only present when extended=true |
items[].instance_id | integer | null | Steam instance ID. Only present when extended=true |
items[].asset_id | string | null | Steam asset ID, as a string. Only present when extended=true |
items[].float | number | null | Item float value. Only present when extended=true |
items[].paint_seed | integer | null | Paint seed (pattern index). Only present when extended=true |
items[].inspect_url | string | null | Steam inspect link. Only present when extended=true |
items[].phase | string | null | Item phase (e.g. "Ruby", "Sapphire"). Only present when extended=true |
Where asset_id, float and paint_seed come from
These three are not part of every item's record. Where an item carries an inspect_url, we read them straight out of that link, so they are present even when the item reached the catalogue without them. Where there is no inspect link there is nothing to read, and the fields are absent — so expect them on much of the CS2 catalogue, but not on all of it.
Two cases where a link is present but a field still is not: some inspect links are generated for items already held in stock and name no particular asset, so asset_id is absent rather than wrong; and items that are not painted — stickers, cases, capsules — have no float or paint_seed to report. Treat every one of the three as optional.
item_id is not an asset ID: it identifies the offer in our catalogue and is what you pass to Create Purchase. Use asset_id when you need to line an item up against Steam.
The inspect link is always passed through untouched, so anything we do not surface — stickers, keychains, name tags, StatTrak counts — you can decode from it yourself.
Example
Get all available CS2 items
bash
curl "https://api.skinslink.com/api/v1/merchant/purchase/available?game=csgo" \
-H "X-Api-Key: your-api-key" \
-H "Accept: application/json"Get full item details
bash
curl "https://api.skinslink.com/api/v1/merchant/purchase/available?game=csgo&full=true" \
-H "X-Api-Key: your-api-key" \
-H "Accept: application/json"Get full item details with extended info (float, class_id, etc.)
bash
curl "https://api.skinslink.com/api/v1/merchant/purchase/available?game=csgo&full=true&extended=true" \
-H "X-Api-Key: your-api-key" \
-H "Accept: application/json"WARNING
Prices and availability are point-in-time and may change between lookup and purchase creation. Items are re-priced at purchase time.
Errors
| Status | Message | Cause |
|---|---|---|
400 | invalid game code | Invalid or missing game parameter |
400 | validation error | Missing or invalid fields |
401 | missing authorization header | X-Api-Key header not provided |
401 | invalid API key | API key not found or inactive |
403 | merchant account is disabled | Merchant account deactivated |
403 | invalid IP: <ip> | Request IP not in whitelist |
400 | page must be 1 or greater | page is zero, negative or not a number |
503 | internal error | Pricing service temporarily unavailable — retry |
503 | catalogue page is being rebuilt, retry shortly | Only when page is used. Wait for Retry-After seconds and repeat the same request |
