# Check up to 1000 item_ids at once, with the CSV snapshot fields

`POST /v1/check-availability`

Send up to 1000 item ids in the JSON body. Every listing that is for sale now comes back with the fields of its row in the CSV snapshot (GET /v1/prices/snapshot?format=csv), plus float, paint_index, phase and sticker_names. The data is read live, not from the snapshot cache.


The listings returned are the ones the CSV contains for the same include_hold / include_manual; other ids are left out. Results are in ascending item_id order. merchant is returned only to accounts that see supply sources in the CSV.


Send ids as strings: item ids are larger than 2^53. An id that is not a whole number is ignored; the others are still answered.


Errors (HTTP 200, success: false): invalid body, missing item_ids, too many items (more than 1000).


GET /v1/check-availability is unchanged.

Prices are integers. `1000` = `1 USD`.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `api` | query | string | required | Your [WAXPEER API key](https://waxpeer.com/profile/user?tab=security) |
| `include_hold` | query | string | optional | 1 / true: also return trade-locked listings (delivery=hold, with unlock_at and send_until), as on the CSV. |
| `include_manual` | query | string | optional | 1 / true: also return 12-hour manual-delivery P2P listings (delivery=manual), as on the CSV. |

## Request body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `item_ids` | array<string> | required | 1 to 1000 item ids, as strings or numbers |

```json
{
  "item_ids": [
    "27165625733",
    "53927617185"
  ]
}
```

## Example (curl)

```bash
curl -X POST 'https://api.waxpeer.com/v1/check-availability?api=%7B%7BAPI_KEY%7D%7D' \
  -H 'Content-Type: application/json' \
  -d '{
  "item_ids": [
    "27165625733",
    "53927617185"
  ]
}'
```

## Example response

```json
{
  "success": true,
  "items": [
    {
      "item_id": "27165625733",
      "name": "★ Karambit | Fade (Factory New)",
      "price": 1687470,
      "auto": false,
      "inspect": "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S76561198000000001A27165625733D1234567890",
      "unlock_at": "2026-10-22T09:00:00Z",
      "send_until": "2026-10-23T09:00:00Z",
      "class_id": "310854699",
      "instance_id": "302028390",
      "steam_id": "76561198000000001",
      "delivery": "hold",
      "float": 0.0123,
      "paint_index": 38,
      "phase": null,
      "sticker_names": [
        "Crown (Foil)"
      ]
    },
    {
      "item_id": "53927617185",
      "name": "★ Bayonet | Gamma Doppler (Factory New)",
      "price": 1234500,
      "auto": true,
      "inspect": "steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S76561199883497268A53927617185D9876543210",
      "unlock_at": null,
      "send_until": null,
      "class_id": "7993038249",
      "instance_id": "480085569",
      "steam_id": "",
      "delivery": "instant",
      "float": 0.0081,
      "paint_index": 571,
      "phase": "Phase 2",
      "sticker_names": null
    }
  ]
}
```

## Responses

- `200` Successful operation

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `success` | boolean | optional | Whether the operation succeeded |
| `items` | array<object> | optional | Array of items |
| `items.item_id` | string | optional | Unique Waxpeer item identifier (item_id) |
| `items.name` | string | optional | Full item market hash name |
| `items.price` | number | optional | Item price in integer format (1000 = $1.00 USD) |
| `items.auto` | boolean | optional | true when the listing delivers instantly |
| `items.inspect` | string | optional | Steam inspect link; null when not available |
| `items.unlock_at` | string | optional | RFC 3339 UTC time when the Steam trade lock ends and item can be sent. null for regular items |
| `items.send_until` | string | optional | RFC 3339 UTC delivery deadline |
| `items.class_id` | string | optional | Steam class id; empty string when not known |
| `items.instance_id` | string | optional | Steam instance id; empty string when not known |
| `items.steam_id` | string | optional | SteamID64 of the account holding the item; empty string when not known |
| `items.merchant` | string | optional | Supply source; returned only to accounts that see supply sources |
| `items.delivery` | enum | optional | How the listing ships: instant, regular, hold or manual (the CSV delivery column) |
| `items.float` | number | optional | Item wear float value (CS:GO) |
| `items.paint_index` | number | optional | Item paint index |
| `items.phase` | string | optional | Doppler phase name (e.g. Phase 1, Ruby, Emerald) |
| `items.sticker_names` | array<string> | optional | Names of applied stickers |


## Notes for agents

- Auth is the query parameter `api`, not an Authorization header.
- See [/statuses.md](/statuses.md) for numeric trade status plus `is_released` / `release_date`. `escrow_status` is site-only.
- Prefer GET /v2/search-items-by-name over v1.
- Prefer GET /v2/get-items-list over v1 (cursor keyset pagination without the 5000 row cap). Pass next_cursor only while has_more is true.
- Prefer POST /v2/my-history over v1 (faster on long histories, ordered by trade id). On buy rows, price is the amount you paid.
- POST /v2/my-history: status (number or array) and reason (string or array) filters need start and end at most 31 days apart. Every trade has reason, reversed_by (buyer / seller / null) and penalties (null when nothing was charged)
- POST /v1/check-availability: up to 1000 item_ids in a JSON body (send strings). Each listing for sale returns its CSV snapshot fields plus float, paint_index, phase, sticker_names, read live. include_hold / include_manual as on the CSV
- Socket.IO game item events carry inspect (Steam inspect link, null when none) and delivery (instant / regular / hold / manual)
- Buy orders: use the /v2 routes. POST /v2/create-buy-order takes a JSON body (name, game, price, amount 1 to 250, allow_trade_locked, and CS2 filters: float_min/float_max, paint_seeds, phase, stickers (id, slot), charm_id, charm_pattern_min/max); api stays in the query. Orders fill automatically from listings at or below the price.
- Buy-order refusals are HTTP 200 `success: false` + `msg` + `code`: branch on `code` (price_above_balance, exposure_limit when open orders would exceed 10 × balance, too_many_orders at 1000 open, invalid_amount, invalid_filters, …). Create, edit and both removals share 10 writes per 10 seconds (HTTP 429).
- The v1 buy-order paths are deprecated and answer with the v2 contract; successful v1 answers also keep v1 field names (`offers` next to `orders`, `id`, `count`, `item_name`). Public lists include filtered orders: compare `filters` with the item before reading an order price as an offer for it. In GET /v2/buy-order-history, kind=cancelled with reason=insufficient_funds means the balance could not pay.
- Trade-locked listings are omitted unless you pass include_hold=1. They then include unlock_at and send_until (RFC 3339 UTC).
- Buy a trade-locked listing only by exact item_id with allow_trade_locked (query 1 on GET /v1/buy-one-p2p, body true on POST /v1/buy). GET /v1/buy-one-p2p-name never sells hold items.
- CSV snapshot: GET /v1/prices/snapshot?format=csv (gzip). Shared header `item_id,name,price,auto,inspect,unlock_at,send_until,class_id,instance_id,steam_id,merchant,delivery`. include_hold=1 adds trade-locked rows (fills unlock_at/send_until; delivery=hold). include_manual=1 adds 12h manual P2P rows (delivery=manual; merchant empty on those rows). compact is JSON-only.
- Do not use GET /v1/ready-to-transfer-p2p; use the [trade websocket](/websocket.md).
