[start, end): every trade, liquidation, deleverage, or settlement leg with the position before and after, in timestamp order. end is clamped to meta.built_through. A window too large to answer in time returns an error asking for a narrower one. The change log starts October 13, 2025; hourly history starts June 7, 2026 18:00 UTC (later for some dexes); live snapshots refresh every 5 minutes. Billed at 1 credit per 1,000 rows returned, minimum 1 credit per request.
Route Metadata
| Field | Value |
|---|---|
| Method | GET |
| Path | /v1/hyperliquid/hip3/wallets/{address}/positions/changes |
| operationId | getHip3WalletPositionChanges |
| Tag | HIP-3 Builder Perps - Positions |
| Family | HIP-3 |
| Deprecated or legacy | no |
Request Parameters
Path Parameters
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges path parameters",
"type": "object",
"required": [
"address"
],
"properties": {
"address": {
"description": "Wallet address: 0x followed by 40 hex characters (case-insensitive).",
"type": "string",
"pattern": "^0x[0-9a-fA-F]{40}$",
"example": "0x31ca8395cf837de08b24da3f660e77761dfb974b",
"x-parameter-location": "path"
}
}
}
Query Parameters
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges query parameters",
"type": "object",
"properties": {
"start": {
"description": "Inclusive start in Unix milliseconds. Defaults to 24 hours before `end`.",
"type": "integer",
"format": "int64",
"x-parameter-location": "query"
},
"end": {
"description": "Exclusive end in Unix milliseconds. Defaults to now.",
"type": "integer",
"format": "int64",
"x-parameter-location": "query"
},
"symbol": {
"description": "Only this market, in `dex:COIN` form (e.g. xyz:TSLA). Must agree with `dex` when both are set.",
"type": "string",
"x-parameter-location": "query"
},
"dex": {
"description": "Restrict to one HIP-3 dex (for example `xyz`).",
"type": "string",
"example": "xyz",
"x-parameter-location": "query"
},
"limit": {
"description": "Maximum rows per page (default 500, max 5000).",
"type": "integer",
"default": 500,
"minimum": 1,
"maximum": 5000,
"x-parameter-location": "query"
},
"cursor": {
"description": "Cursor from the previous response `meta.next_cursor`. Keep every other parameter unchanged.",
"type": "string",
"x-parameter-location": "query"
}
}
}
Response Contracts
Status 200
Get HIP-3 wallet position changesapplication/json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges response 200",
"description": "Position change log legs in timestamp order.",
"type": "object",
"required": [
"data",
"meta",
"success"
],
"properties": {
"data": {
"type": "array",
"items": {
"description": "One leg of the position change log: a trade, liquidation, auto-deleverage, or settlement that changed (or touched) a position, with the position before and after. Hyperliquid legs carry `direction`, `closed_pnl`, `crossed`, and `seq`; Lighter legs carry `realized_pnl`, `is_maker`, and the Lighter fields at the end.",
"type": "object",
"required": [
"cause",
"coin",
"continuity",
"end_position",
"entry_price_after",
"event_type",
"fee",
"fee_token",
"finalized",
"opened_at",
"order_id",
"price",
"side",
"size",
"start_position",
"symbol",
"timestamp",
"trade_id"
],
"properties": {
"account_index": {
"description": "Lighter only: account index as a string.",
"type": "string",
"example": "513030"
},
"account_kind": {
"description": "Lighter only: `user`, `insurance`, `settlement`, or `system`.",
"type": "string",
"example": "user"
},
"block_number": {
"description": "Hyperliquid and HIP-3 only, present when known (from September 17, 2026): block that executed the leg.",
"type": "integer",
"format": "int64",
"example": 745512345
},
"cause": {
"description": "Why the leg happened: `trade`, `liquidation`, `liquidation_counterparty`, `adl`, `settlement`, or `unknown`.",
"type": "string",
"example": "trade"
},
"closed_pnl": {
"description": "Hyperliquid and HIP-3 only: realized PnL of the leg in USD.",
"type": "string",
"nullable": true,
"example": "19.9"
},
"coin": {
"description": "Alias of `symbol`.",
"type": "string",
"example": "BTC"
},
"continuity": {
"description": "`ok` when `start_position` continues the previous leg exactly, `inferred` when it was bridged, `first_seen` for the first leg recorded for the account and market, `quarantined` when the chain is broken and the leg is held out of position state.",
"type": "string",
"enum": [
"ok",
"inferred",
"first_seen",
"quarantined"
],
"example": "ok"
},
"crossed": {
"description": "Hyperliquid and HIP-3 only: true when this account was the taker.",
"type": "boolean",
"example": true
},
"dex": {
"description": "HIP-3 only: dex of the market.",
"type": "string",
"example": "xyz"
},
"direction": {
"description": "Hyperliquid and HIP-3 only: direction label as reported by Hyperliquid (for example `Close Short`).",
"type": "string",
"example": "Close Short"
},
"end_position": {
"description": "Signed position size after the leg.",
"type": "string",
"nullable": true,
"example": "-0.25"
},
"entry_price_after": {
"description": "Average entry price after the leg. Null when the position is flat after it.",
"type": "string",
"nullable": true,
"example": "64210.5"
},
"event_index": {
"description": "Hyperliquid and HIP-3 only, present with `block_number`: execution order within the block.",
"type": "integer",
"example": 12
},
"event_type": {
"description": "Effect on the position: `open`, `increase`, `reduce`, `close`, or `flip`. Lighter also reports `settlement` (the settlement counterparty side of a market settlement) and `unchanged`.",
"type": "string",
"example": "reduce"
},
"fee": {
"description": "Fee paid for the leg (negative is a rebate).",
"type": "string",
"nullable": true,
"example": "0.4875"
},
"fee_rate": {
"description": "Lighter only: fee rate as a decimal ratio.",
"type": "string",
"nullable": true,
"example": "0.00002"
},
"fee_token": {
"description": "Asset the fee is paid in: USDC on Hyperliquid and Lighter mainnet, USDG on Lighter on Robinhood Chain.",
"type": "string",
"example": "USDC"
},
"fee_usdc": {
"description": "Lighter only: fee in the quote asset, computed from the notional and the fee rate.",
"type": "string",
"nullable": true,
"example": "0.325"
},
"finalized": {
"description": "True when the leg is final and will not be re-derived.",
"type": "boolean",
"example": true
},
"is_maker": {
"description": "Lighter only: true when this account was the maker.",
"type": "boolean",
"example": false
},
"opened_at": {
"description": "Start of the position lifecycle this leg belongs to. Null when it opened before coverage.",
"type": "string",
"format": "date-time",
"nullable": true
},
"order_id": {
"description": "Order ID of this account.",
"type": "integer",
"format": "int64",
"nullable": true,
"example": 844421856609148
},
"position_size_after": {
"description": "Lighter only: alias of `end_position`.",
"type": "string",
"example": "-0.25"
},
"position_size_before": {
"description": "Lighter only: alias of `start_position`.",
"type": "string",
"example": "-0.5"
},
"price": {
"description": "Execution price.",
"type": "string",
"nullable": true,
"example": "65010.2"
},
"realized_pnl": {
"description": "Lighter only: realized PnL of the leg in the quote asset (0 on open and increase).",
"type": "string",
"example": "19.9"
},
"seq": {
"description": "Hyperliquid and HIP-3 only: order of legs that share a timestamp.",
"type": "integer",
"example": 0
},
"side": {
"description": "Side of this account in the trade, exactly as on the trades routes: `B` (buy) or `A` (sell).",
"type": "string",
"enum": [
"B",
"A"
],
"example": "B"
},
"size": {
"description": "Traded size in base units.",
"type": "string",
"nullable": true,
"example": "0.25"
},
"start_position": {
"description": "Signed position size before the leg.",
"type": "string",
"nullable": true,
"example": "-0.5"
},
"symbol": {
"description": "Market symbol (HIP-3: `dex:COIN`).",
"type": "string",
"example": "BTC"
},
"timestamp": {
"description": "Execution time (UTC).",
"type": "string",
"format": "date-time",
"example": "2026-09-25T14:03:11.482Z"
},
"trade_id": {
"description": "Trade ID, shared by both legs of a trade.",
"type": "integer",
"format": "int64",
"example": 26121110211
},
"usdc_amount": {
"description": "Lighter only: notional of the leg in the quote asset.",
"type": "string",
"example": "16252.55"
}
}
}
},
"meta": {
"description": "Response metadata of the account positions routes. Every instant is RFC 3339 UTC with milliseconds and comes from the data, never the request time.",
"type": "object",
"required": [
"count",
"request_id"
],
"properties": {
"as_of": {
"description": "Instant the returned state describes: the snapshot tick or hour, or the requested as-of time.",
"type": "string",
"format": "date-time"
},
"built_through": {
"description": "Every event before this instant is built into the change log and as-of state. Reads are clamped to it.",
"type": "string",
"format": "date-time"
},
"clamped_to": {
"description": "Boundary the read was clamped to (`built_through`). Present only when clamped.",
"type": "string",
"format": "date-time"
},
"count": {
"description": "Number of records returned.",
"type": "integer"
},
"coverage_from": {
"description": "Coverage start, present with `notice` when the request falls before coverage or the address has no recorded activity.",
"type": "string",
"format": "date-time"
},
"finalized_through": {
"description": "Every event before this instant is final and will not be re-derived (Lighter: the trade finalization watermark). Never later than `built_through`.",
"type": "string",
"format": "date-time"
},
"next_cursor": {
"description": "Signed cursor for the next page, bound to the request. Pass it back with the same parameters. A market cursor pins its snapshot; if that snapshot is replaced or expires the next page answers 409 `snapshot_advanced`.",
"type": "string",
"nullable": true
},
"notice": {
"description": "Human-readable advisory: before coverage, no recorded activity, or a stale snapshot.",
"type": "string"
},
"quality": {
"description": "Completeness of the snapshot the response was read from: `complete`, `partial`, or `degraded`. Rows carry their own `quality`. On Lighter and Robinhood Chain, snapshots from the latest day, before the venue's daily trade reconcile, can read `degraded` while their rows read `preliminary`; they read `complete` once the reconcile has run.",
"type": "string"
},
"request_id": {
"description": "Unique request ID for support.",
"type": "string",
"format": "uuid"
},
"requested_end": {
"description": "The `end` or `timestamp` the caller asked for, echoed when the read was clamped.",
"type": "string",
"format": "date-time"
},
"snapshot_ts": {
"description": "Committed snapshot the response was read from. Market routes echo the resolved `hour` here.",
"type": "string",
"format": "date-time"
},
"source": {
"description": "How the rows were produced: `snapshot` (live or hourly snapshot), `reconstructed` (as-of state between snapshots), or `changes` (change log).",
"type": "string",
"enum": [
"snapshot",
"reconstructed",
"changes"
]
},
"stale": {
"description": "True on current reads when the latest snapshot is older than 12 minutes; paired with `notice`.",
"type": "boolean"
},
"totals": {
"description": "Market listings, first page only: aggregates over the whole filtered result set, not just this page.",
"allOf": [
{
"description": "Long and short aggregates of every open position in one market at one snapshot. Averages cover only positions with a known entry (`*_positions_with_entry`). Shares are decimal ratios of the side or total value held by the ten largest positions.",
"type": "object",
"required": [
"coin",
"long_avg_entry_price",
"long_count",
"long_positions_with_entry",
"long_size",
"long_top10_value_share",
"long_value",
"quality",
"short_avg_entry_price",
"short_count",
"short_positions_with_entry",
"short_size",
"short_top10_value_share",
"short_value",
"snapshot_ts",
"symbol",
"top10_value_share"
],
"properties": {
"coin": {
"description": "Alias of `symbol`.",
"type": "string",
"example": "BTC"
},
"dex": {
"description": "HIP-3 only.",
"type": "string",
"example": "xyz"
},
"long_avg_entry_price": {
"description": "Size-weighted average entry of long positions with a known entry.",
"type": "string",
"nullable": true,
"example": "63120.4"
},
"long_count": {
"type": "integer",
"format": "int64",
"example": 18234
},
"long_positions_with_entry": {
"type": "integer",
"format": "int64",
"example": 18230
},
"long_size": {
"description": "Total long size in base units.",
"type": "string",
"example": "8123.45"
},
"long_top10_value_share": {
"description": "Share of long value held by the ten largest long positions.",
"type": "string",
"nullable": true,
"example": "0.412345"
},
"long_value": {
"description": "Total long value in USD. Null when any long position has no mark.",
"type": "string",
"nullable": true,
"example": "528000000.5"
},
"quality": {
"description": "`complete`, `partial`, or `degraded`, from this market's own rows.",
"type": "string",
"example": "complete"
},
"short_avg_entry_price": {
"description": "Size-weighted average entry of short positions with a known entry.",
"type": "string",
"nullable": true,
"example": "66210.9"
},
"short_count": {
"type": "integer",
"format": "int64",
"example": 15102
},
"short_positions_with_entry": {
"type": "integer",
"format": "int64",
"example": 15100
},
"short_size": {
"description": "Total short size in base units.",
"type": "string",
"example": "8120.1"
},
"short_top10_value_share": {
"description": "Share of short value held by the ten largest short positions.",
"type": "string",
"nullable": true,
"example": "0.385"
},
"short_value": {
"description": "Total short value in USD. Null when any short position has no mark.",
"type": "string",
"nullable": true,
"example": "527800000.25"
},
"snapshot_ts": {
"description": "Snapshot the aggregates describe.",
"type": "string",
"format": "date-time",
"nullable": true
},
"symbol": {
"type": "string",
"example": "BTC"
},
"top10_value_share": {
"description": "Share of total value held by the ten largest positions.",
"type": "string",
"nullable": true,
"example": "0.301"
}
}
}
]
}
}
},
"success": {
"type": "boolean",
"example": true
}
}
}
Status 400
Invalid requestapplication/json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges response 400",
"description": "Error response",
"type": "object",
"properties": {
"code": {
"description": "HTTP status code",
"type": "integer"
},
"error": {
"description": "Error message",
"type": "string"
},
"error_code": {
"description": "Machine-readable error code. Common values: `invalid_query_params` (a query parameter failed to parse or validate) and `invalid_path_params` (a path parameter failed to parse). Other endpoint-specific codes exist; treat unknown codes as generic errors of the given HTTP status.",
"type": "string"
},
"request_id": {
"description": "Unique request ID for support",
"type": "string",
"format": "uuid"
}
}
}
OpenAPI example
{
"code": 400,
"error": "Failed to deserialize query string: limit: invalid digit found in string",
"error_code": "invalid_query_params",
"request_id": "3f2a9c71-5b0e-4d68-9a4c-7e1d2b6f8a05"
}
Status 401
Authentication requiredapplication/json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges response 401",
"description": "Error response",
"type": "object",
"properties": {
"code": {
"description": "HTTP status code",
"type": "integer"
},
"error": {
"description": "Error message",
"type": "string"
},
"error_code": {
"description": "Machine-readable error code. Common values: `invalid_query_params` (a query parameter failed to parse or validate) and `invalid_path_params` (a path parameter failed to parse). Other endpoint-specific codes exist; treat unknown codes as generic errors of the given HTTP status.",
"type": "string"
},
"request_id": {
"description": "Unique request ID for support",
"type": "string",
"format": "uuid"
}
}
}
OpenAPI example
{
"code": 401,
"error": "Missing or invalid API key. Provide X-API-Key header."
}
Status 404
Resource not foundapplication/json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges response 404",
"description": "Error response",
"type": "object",
"properties": {
"code": {
"description": "HTTP status code",
"type": "integer"
},
"error": {
"description": "Error message",
"type": "string"
},
"error_code": {
"description": "Machine-readable error code. Common values: `invalid_query_params` (a query parameter failed to parse or validate) and `invalid_path_params` (a path parameter failed to parse). Other endpoint-specific codes exist; treat unknown codes as generic errors of the given HTTP status.",
"type": "string"
},
"request_id": {
"description": "Unique request ID for support",
"type": "string",
"format": "uuid"
}
}
}
OpenAPI example
{
"code": 404,
"error": "Resource not found"
}
Status 429
Rate limit exceededapplication/json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges response 429",
"description": "Error response",
"type": "object",
"properties": {
"code": {
"description": "HTTP status code",
"type": "integer"
},
"error": {
"description": "Error message",
"type": "string"
},
"error_code": {
"description": "Machine-readable error code. Common values: `invalid_query_params` (a query parameter failed to parse or validate) and `invalid_path_params` (a path parameter failed to parse). Other endpoint-specific codes exist; treat unknown codes as generic errors of the given HTTP status.",
"type": "string"
},
"request_id": {
"description": "Unique request ID for support",
"type": "string",
"format": "uuid"
}
}
}
OpenAPI example
{
"code": 429,
"error": "Rate limit exceeded"
}
Status 503
Positions, pagination, or an as-of reconstruction are temporarily unavailable (error_code positions_unavailable, pagination_unavailable, or reconstruction_unavailable). Retry shortly.
application/json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "getHip3WalletPositionChanges response 503",
"description": "Error response",
"type": "object",
"properties": {
"code": {
"description": "HTTP status code",
"type": "integer"
},
"error": {
"description": "Error message",
"type": "string"
},
"error_code": {
"description": "Machine-readable error code. Common values: `invalid_query_params` (a query parameter failed to parse or validate) and `invalid_path_params` (a path parameter failed to parse). Other endpoint-specific codes exist; treat unknown codes as generic errors of the given HTTP status.",
"type": "string"
},
"request_id": {
"description": "Unique request ID for support",
"type": "string",
"format": "uuid"
}
}
}
OpenAPI example
{
"code": 503,
"error": "Account positions are not available right now.",
"error_code": "positions_unavailable"
}