---
title: "Fills"
method: GET
path: "/gateway/v1/hyperliquid/fills"
tags: ["Hyperliquid"]
---

# Fills

`GET /gateway/v1/hyperliquid/fills`

Returns a wallet's individual fills (fill-level executions), newest first by default, with realized PnL, fees, and direction (`crossed`=true marks a taker fill that took liquidity). For closed round-trip trades (one row per open→close position, with per-trade P&L incl. funding), use `/hyperliquid/trades` instead — funding is NOT attributable at fill level.

Default `order=desc` is a recent-capped window (no `offset`): up to `limit` of the most-recent fills; page back by setting `to` to the oldest `time` you received (or `to_ms`+`to_fill_id` for millisecond-exact paging). For COMPLETE history with no cap, use `order=asc` with `from` and follow `meta.next_cursor`. `symbol` filters to one market (applied client-side, so with `order=desc` it only filters the recent window — pair with `from`/`to` to reach older history).

## Query parameters

- `address` string, required — Wallet address: a 0x EVM address or an ENS name (e.g. vitalik.eth). Solana addresses are not supported.
- `from` string — Window start (Unix seconds or a date). With the default order=desc, results cover the window forward from this point and are capped at ~2000 of the earliest fills in range (narrow the range to see the most-recent fills). With order=asc this is the start of a complete-history walk: follow meta.next_cursor to page through every fill in the window with no cap.
- `to` string — Window end (Unix seconds or a date), inclusive. Defaults to now. With order=desc, page back within the most-recent results by setting this to the oldest time you received (prefer to_ms for millisecond precision); with order=asc it bounds the walk.
- `to_ms` integer — Window end in Unix milliseconds, for millisecond-precise desc paging: pass the time_ms of the oldest fill you received to fetch the next page. On its own the boundary is exclusive (fills AT to_ms are dropped), so when more than limit fills share one millisecond the remainder is skipped — pair it with to_fill_id to page losslessly through a boundary millisecond. Takes precedence over to (which is ignored when to_ms is set). Like to, it pages within the recent (~2000-fill) window. desc-only: rejected with order=asc (use cursor instead).
- `to_fill_id` string — Cursor tiebreak for to_ms: pass the fill_id of the oldest fill you received alongside its time_ms as to_ms. The next page then resumes strictly after that (time_ms, fill_id) pair — fills at the boundary millisecond with a lower fill_id are included instead of skipped, so paging never loses fills that share a millisecond. Requires to_ms; desc-only. Equivalent to following meta.next_cursor, which encodes the same position. An empty page can mean the window is exhausted (set from to reach older history), not that no older fills exist.
- `order` 'desc' | 'asc' — desc (default): newest first — the recent feed, or the earliest-anchored ~2000-fill slice when from is set. asc: oldest first, a complete-history walk from from (required) up to to — each page links the next via meta.next_cursor with no result cap, the reliable mode for full trade-history or PnL reconstruction.
- `cursor` string — Opaque continuation token from a previous response's meta.next_cursor. It encodes the paging direction, position, and window, so pass it with only symbol and limit — combining it with from, to, to_ms, or to_fill_id is rejected with 400.
- `symbol` string — Filter to one market (exact match, e.g. xyz:GOLD). Applied client-side: with order=desc it filters after the recent cap (pair it with from/to so older fills are not missed); with order=asc the cursor walk scans past non-matching fills, so a page may return fewer than limit items (or none) while meta.next_cursor still advances.
- `limit` integer — Page size (1-100).

## Response `200`

OK

- CursorDataResponseHyperliquidFill
  - `$schema` string, uri — A URL to the JSON Schema for this object.
  - `data` HyperliquidFill[], nullable, required
    - `closed_pnl` number, double, required — Realized profit/loss, USD. 0 on fills that only open or increase a position (see direction) — realized PnL is booked on closing or reducing fills.
    - `crossed` boolean, required — true = taker (this fill took liquidity); false = maker (provided liquidity / rebate)
    - `direction` string, required — e.g. Open Long, Close Short
    - `fee` number, double, required — Fee paid, USD (negative = rebate)
    - `fee_token` string, required — Fee token (e.g. USDC)
    - `fill_id` string, required — Stable unique identifier for this fill. Pass the oldest fill's value back as to_fill_id (alongside its time_ms as to_ms) to page losslessly, and use it to de-duplicate fills across pages — time and hash are NOT unique (many fills can share a second and an on-chain hash).
    - `hash` string, required — On-chain transaction hash (the zero hash when is_internal is true). NOT unique per fill — one transaction can settle many fills.
    - `is_internal` boolean, required — true for fills not tied to a standard on-chain order (zero transaction hash)
    - `price` number, double, required — Fill price
    - `side` string, required — buy or sell
    - `size` number, double, required — Amount filled
    - `start_position` number, double, required — Position size before this fill
    - `symbol` string, required — Market id
    - `time` integer, required — When it filled (Unix seconds). Second-granular; use time_ms for precise ordering and for paging via to_ms.
    - `time_ms` integer, required — When it filled (Unix milliseconds). Use for precise ordering/dedup; pass the oldest value back as to_ms (paired with its fill_id as to_fill_id) to page to the next page without losing fills.
    - `tx_index` integer, required — Position of the fill's transaction within its block. (time_ms, tx_index) is unique per fill and is the key cursor paging advances on; 0 is a valid value (first transaction in the block).
  - `meta` CursorMeta, required
    - `cached` boolean, required — Whether this response was served from cache
    - `credits_used` integer, required — Credits deducted for this request
    - `empty_reason` string — Hint explaining why the data array is empty, when applicable
    - `has_more` boolean, required — Whether more items exist beyond the current page.
    - `limit` integer, required — Maximum number of items returned in this response
    - `next_cursor` string — Opaque cursor token for fetching the next page. Empty when no more pages exist.
    - `watermark` integer — Warehouse watermark (Unix seconds) this response was computed at, on warehouse-backed endpoints (e.g. Hyperliquid /trades) — rows up to this time come from the warehouse, newer rows from the live tail. Omitted elsewhere.

## Other responses

- `default` — Error

---

[API](https://skmtc.dev/asksurf/apis/asksurf-public-rest-api.md) · [All operations](https://skmtc.dev/asksurf/apis/asksurf-public-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/asksurf/asksurf-public-rest-api/revisions/4153a9cb5145/schema)
