> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polynode.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Trade History (Market)

> Complete onchain trade history for any market token.

Returns every onchain trade fill for a specific market token, enriched with market metadata.

<Tip>
  **Want the entire market in one call?** Use [Trade History (Market) — Bulk](/api-reference/onchain/market-trades-all) (Growth plan and above). Returns up to 250K trades in a single response, no pagination.
</Tip>

## Quick start — get the most recent 100 trades

```bash theme={null}
curl "https://api.polynode.dev/v2/onchain/markets/{token_id}/trades?limit=100" \
  -H "x-api-key: YOUR_KEY"
```

Default `limit=100`, max `limit=1000`. That's all most apps need.

## Get every trade in the market (full history)

To walk the entire history, add `?cursor=` (empty value) to the first request, then **for each next page, copy `pagination.cursor` from the response back into the URL**. Stop when `pagination.has_more` is `false`.

Three complete copy-paste scripts that walk an entire market:

<CodeGroup>
  ```python Python theme={null}
  import requests

  API_KEY = "YOUR_KEY"
  TOKEN_ID = "21743669032210695168079601505378236205866986767926346409604806906483294819314"

  def get_all_trades(token_id):
      cursor = ""           # empty string = first page
      all_trades = []
      while True:
          r = requests.get(
              f"https://api.polynode.dev/v2/onchain/markets/{token_id}/trades",
              params={"limit": 1000, "cursor": cursor},
              headers={"x-api-key": API_KEY},
          ).json()
          all_trades.extend(r["trades"])
          if not r["pagination"]["has_more"]:
              break
          cursor = r["pagination"]["cursor"]   # feed this into the next request
      return all_trades

  trades = get_all_trades(TOKEN_ID)
  print(f"got {len(trades)} trades")
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "YOUR_KEY";
  const TOKEN_ID = "21743669032210695168079601505378236205866986767926346409604806906483294819314";

  async function getAllTrades(tokenId) {
    let cursor = "";              // empty string = first page
    const allTrades = [];
    while (true) {
      const url = `https://api.polynode.dev/v2/onchain/markets/${tokenId}/trades`
                + `?limit=1000&cursor=${encodeURIComponent(cursor)}`;
      const r = await fetch(url, { headers: { "x-api-key": API_KEY } }).then(r => r.json());
      allTrades.push(...r.trades);
      if (!r.pagination.has_more) break;
      cursor = r.pagination.cursor;   // feed this into the next request
    }
    return allTrades;
  }

  const trades = await getAllTrades(TOKEN_ID);
  console.log(`got ${trades.length} trades`);
  ```

  ```bash bash theme={null}
  KEY="YOUR_KEY"
  TOKEN_ID="21743669032210695168079601505378236205866986767926346409604806906483294819314"

  CURSOR=""
  TOTAL=0
  while true; do
    RESP=$(curl -s "https://api.polynode.dev/v2/onchain/markets/$TOKEN_ID/trades?limit=1000&cursor=$CURSOR" \
      -H "x-api-key: $KEY")
    COUNT=$(echo "$RESP" | python3 -c "import json,sys;print(json.load(sys.stdin)['count'])")
    HAS_MORE=$(echo "$RESP" | python3 -c "import json,sys;print(json.load(sys.stdin)['pagination']['has_more'])")
    TOTAL=$((TOTAL + COUNT))
    echo "got $COUNT trades, total: $TOTAL"
    [ "$HAS_MORE" = "False" ] && break
    CURSOR=$(echo "$RESP" | python3 -c "import json,sys;print(json.load(sys.stdin)['pagination']['cursor'])")
  done
  ```
</CodeGroup>

**Real run** (heavy market, walked live with the Python script above):

```
got 1000 trades  (total: 1000)
got 1000 trades  (total: 2000)
got 1000 trades  (total: 3000)
...
got 1000 trades  (total: 20000)
DONE. 20,000 trades in 24 seconds.
```

Each page takes \~1 second regardless of how deep you go — the loop just keeps running until `has_more` is `false`.

## Request

```
GET /v2/onchain/markets/{token_id}/trades?limit=100
GET /v2/onchain/markets/{token_id}/trades?limit=1000&cursor=<value-from-prior-response>
```

| Parameter  | Type    | Location | Description                                                                                                                                                         |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token_id` | string  | path     | CTF token ID (numeric string)                                                                                                                                       |
| `limit`    | integer | query    | Max results per page (default 100, max 1000)                                                                                                                        |
| `cursor`   | string  | query    | Pass empty string `?cursor=` for first page, then echo back `pagination.cursor` from each response. Required to walk past the first page reliably on large markets. |
| `offset`   | integer | query    | Alternative to cursor: skip first N. Fast for the first \~25K results then degrades. Use `cursor` for anything bigger.                                              |

## Response

```json theme={null}
{
  "token_id": "110959653450933276250915064669875552310439627880508793089816880777942697720191",
  "source": "onchain",
  "count": 3,
  "market": "US x Iran ceasefire extended by April 22, 2026?",
  "slug": "us-x-iran-ceasefire-extended-by-april-22-2026",
  "outcome": "No",
  "image": "https://polymarket-upload.s3.us-east-2.amazonaws.com/us-x-iran-ceasefire-by-Cgmx3GCuOwjs.jpg",
  "condition_id": "0x1d2787cb8aed975d092b2799ed6f4083e9445f7420cdc09e9d47e7d54356c6cd",
  "pagination": {
    "limit": 3,
    "has_more": true,
    "cursor": "1777595648:0xeae6ca0aeb75fc866ddb29d3a4b2cd15382895b923fe05b9315445d6346d1c47_0x49ddd1e169186d350488e3d62f58452fe76862c5f81f33987e659759e2c66100"
  },
  "trades": [
    {
      "tx_hash": "0x044dc412fa97d972fae1e77f8a30e769b7bea339cc3a27b5045e5668b513a520",
      "order_hash": "0x6b3d58dcf19f26a0b2f325bc43dc793765d1abeedfc449a3c5be38b6523613c9",
      "timestamp": 1777595650,
      "maker": "0x84571f1bf97a5c710cbe51daff2dd4556cc887fd",
      "taker": "0xe111180000d2663c0091e4f400237545b87b996b",
      "maker_asset_id": "0",
      "taker_asset_id": "110959653450933276250915064669875552310439627880508793089816880777942697720191",
      "maker_amount": 617.382,
      "taker_amount": 618,
      "fee": 0,
      "direction": "BUY",
      "side": "maker"
    }
  ]
}
```

| Field                     | Type    | Description                                                   |
| ------------------------- | ------- | ------------------------------------------------------------- |
| `count`                   | integer | Number of trades in this response                             |
| `pagination.has_more`     | boolean | `true` if more pages available — keep paginating              |
| `pagination.cursor`       | string  | Pass this back as `?cursor=<value>` for the next page         |
| `market`                  | string  | Market question                                               |
| `slug`                    | string  | Market slug                                                   |
| `outcome`                 | string  | Outcome label for this token                                  |
| `image`                   | string  | Market image URL                                              |
| `condition_id`            | string  | Market condition ID                                           |
| `trades[].tx_hash`        | string  | Transaction hash                                              |
| `trades[].order_hash`     | string  | Order hash that was filled                                    |
| `trades[].timestamp`      | number  | Unix timestamp                                                |
| `trades[].maker`          | string  | Maker wallet                                                  |
| `trades[].taker`          | string  | Taker wallet                                                  |
| `trades[].maker_asset_id` | string  | Asset the maker provided (`"0"` = USDC)                       |
| `trades[].taker_asset_id` | string  | Asset the taker provided                                      |
| `trades[].maker_amount`   | number  | Amount maker provided                                         |
| `trades[].taker_amount`   | number  | Amount taker provided                                         |
| `trades[].fee`            | number  | Fee (USDC)                                                    |
| `trades[].direction`      | string  | `"BUY"` or `"SELL"` from the buyer's perspective on this fill |
| `trades[].side`           | string  | Always `"maker"` for this endpoint                            |


## OpenAPI

````yaml GET /v2/onchain/markets/{token_id}/trades
openapi: 3.1.0
info:
  title: PolyNode API
  description: >-
    Real-time Polymarket data API with decoded mempool settlements, OHLCV
    candles, and full Polygon JSON-RPC proxy.
  contact:
    name: PolyNode
    url: https://polynode.dev
  license:
    name: ''
  version: 2.0.0
servers:
  - url: https://api.polynode.dev
    description: Production
security:
  - api_key: []
paths:
  /v2/onchain/markets/{token_id}/trades:
    get:
      tags:
        - Onchain
      summary: Market trade history (onchain)
      description: Complete onchain trade history for a market token.
      operationId: onchain_market_trades
      parameters:
        - name: token_id
          in: path
          required: true
          schema:
            type: string
          description: CTF token ID
        - name: limit
          in: query
          schema:
            type: integer
            default: 100
          description: Max results (max 1000)
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
          description: Skip first N results
        - name: cursor
          in: query
          schema:
            type: string
          description: >-
            Cursor pagination. Pass empty string `?cursor=` for the first page,
            then echo back `pagination.cursor` from each response. Format:
            `<lastTs>:<lastId>`. Each page loads at the same speed regardless of
            depth — recommended over offset for paging beyond ~25K results.
      responses:
        '200':
          description: Trade fills
        '401':
          description: Unauthorized
      security:
        - apiKey: []
components:
  securitySchemes:
    api_key:
      type: apiKey
      in: header
      name: x-api-key

````