# Fills and cancellations of your buy orders (v2)

`GET /v2/buy-order-history`

Your buy-order events, newest first by default:



kind = filled: an order bought a listing. item_id is the listing bought, item_price what you paid, reason is null.
kind = cancelled: an order was closed without buying. reason is insufficient_funds (your balance could not pay for a listing) or user (you removed it). item_id is null and item_price 0.

order_id is the order the event belongs to; it is null on events recorded before orders were linked. price is the order&#39;s price at the event. item_id is a string: item ids are larger than 2^53.


count is the total of events that match game and kind.


Errors. Refusals are HTTP 200 with {"success": false, "msg": "…", "code": "…"}. Branch on code: it is stable, msg is human text. Codes this method answers: invalid_request, error. The full list is on [POST /v2/create-buy-order](/api/buy-order/create-buy-order-v2). A missing or wrong API key is HTTP 403; the write rate limit is HTTP 429.

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) |
| `game` | query | enum | optional | csgo, dota2, rust or tf2; absent = all games |
| `kind` | query | enum | optional | filled or cancelled; absent = both |
| `skip` | query | integer | optional | Events to skip, up to 10000 |
| `limit` | query | integer | optional | Events per page, 1 to 100. Default 50 |
| `sort` | query | enum | optional | DESC (default, newest first) or ASC |

## Example (curl)

```bash
curl -X GET 'https://api.waxpeer.com/v2/buy-order-history?api=%7B%7BAPI_KEY%7D%7D&game=csgo&kind=filled&skip=0&limit=100&sort=DESC'
```

## Example response

```json
{
  "success": true,
  "history": [
    {
      "id": 9,
      "order_id": 123,
      "name": "AK-47 | Redline (Field-Tested)",
      "game": "csgo",
      "kind": "filled",
      "reason": null,
      "price": 12500,
      "item_price": 11800,
      "item_id": "53120456789",
      "created": "2026-10-19T10:05:00Z"
    },
    {
      "id": 8,
      "order_id": 120,
      "name": "AWP | Asiimov (Field-Tested)",
      "game": "csgo",
      "kind": "cancelled",
      "reason": "insufficient_funds",
      "price": 95000,
      "item_price": 0,
      "item_id": null,
      "created": "2026-10-19T09:40:00Z"
    }
  ],
  "count": 2
}
```

## Responses

- `200` Successful operation or refusal

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `success` | boolean | optional | Whether the operation succeeded |
| `history` | array<object> | optional | Events |
| `history.id` | integer | optional | Identifier |
| `history.order_id` | integer | optional | Order id; null on old events |
| `history.name` | string | optional | Full item market hash name |
| `history.game` | string | optional | csgo, dota2, rust or tf2; absent = all games |
| `history.kind` | enum | optional | filled or cancelled |
| `history.reason` | enum | optional | Cancellation reason: insufficient_funds or user; null on a fill |
| `history.price` | integer | optional | Order price at the event (1000 = $1) |
| `history.item_price` | integer | optional | Price paid for the item (1000 = $1); 0 on a cancellation |
| `history.item_id` | string | optional | Item bought, as a string; null on a cancellation |
| `history.created` | string | optional | When the event happened (RFC 3339) |
| `count` | integer | optional | Total matching events |
| `msg` | string | optional | Why the request was refused (only when success is false) |
| `code` | enum | optional | Stable refusal code (only when success is false) |


## 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).
