vike

Leverage changes

Hyperliquid wallets that changed the leverage or margin mode of an open perp position between two position snapshots, newest first, with the position before and after.

GET https://data.vike.io/v1/hyperliquid/leverage-changes

The wallets that changed the leverage setting, or the margin mode (cross or isolated), of an open perp position between two consecutive position snapshots. One row per wallet and market, with the position on both sides of the change. Newest first by default, and order=asc follows the feed forward. The rows are derived from snapshots, so they show what two snapshots show and nothing in between: read the two warnings at the end of this page before building on them.

cURL
# the newest leverage changes (last 24 hours)
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?limit=3" \
  -H "X-API-KEY: $VIKE_API_KEY"

# next page of the call just above: NEXT is its nextCursor, passed back verbatim
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?limit=3&cursor=$NEXT" \
  -H "X-API-KEY: $VIKE_API_KEY"

# leverage raised to 20x or more
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?change=up&min_leverage=20&limit=100" \
  -H "X-API-KEY: $VIKE_API_KEY"

# leverage lowered
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?change=down&limit=100" \
  -H "X-API-KEY: $VIKE_API_KEY"

# margin mode switched with the leverage number unchanged
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?change=mode&limit=100" \
  -H "X-API-KEY: $VIKE_API_KEY"

# one wallet's changes on one market
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?wallet=0x25773676902085225ae5751075e4161369334897&symbol=BTC&limit=100" \
  -H "X-API-KEY: $VIKE_API_KEY"

# follow the feed: everything since a moment, oldest first
curl -s "https://data.vike.io/v1/hyperliquid/leverage-changes?order=asc&start=2026-10-27T12:00:00Z&limit=500" \
  -H "X-API-KEY: $VIKE_API_KEY"
walletqueryoptional
One wallet, 0x plus 40 hex, any case
symbolqueryoptional
HL ticker, e.g. BTC or xyz:TSLA
changequeryoptional
up (leverage rose) | down (leverage fell) | mode (only the margin mode, cross or isolated, changed). Validated against this fixed set
min_leveragequeryoptional
Minimum new leverage, 0 or more. Default 0: no floor
startqueryoptional
ISO-8601 UTC. Default: the 24 hours before end (before now when end is empty), unless wallet is given. Resuming an order=asc cursor starts from the cursor instead; a desc cursor keeps the 24-hour floor
endqueryoptional
ISO-8601 UTC. Default: now. A window wider than 31 days is a 400 unless wallet is given
orderqueryoptional
asc | desc. Default desc, newest first. order=asc returns the oldest events first and is the mode for following a feed: pass each nextCursor back verbatim. It orders by key, so a row the writer inserts late with an older key is not seen by a poller already past it: re-read a small overlap. An asc page with rows always carries a cursor; an empty one returns the cursor you sent, or on a first call with no start or wallet, a cursor at the lower bound of the default window (null when one of them already pins the place). So stop on an empty page, not on a null cursor. A desc page that comes back short carries no cursor. Anything else is a 400
limitqueryoptional
Default 100, max 5000
cursorqueryoptional
nextCursor from the previous page, verbatim. It pins the call that returned it: the feed, order, every filter and the start and end you sent. Changing or dropping any of them, start included, is a 400. Without wallet, an asc cursor more than 31 days before end (before now when end is empty) is a 400 too: restart with start
Example response
{
  "items": [
    {
      "ts": "2026-10-27T12:19:00+00:00",
      "prev_ts": "2026-10-27T12:14:00+00:00",
      "captured_at": "2026-10-27T12:16:24+00:00",
      "prev_captured_at": "2026-10-27T12:04:25+00:00",
      "wallet": "0xfeee942a06d2f8012823ccde7bf7bcbcaa29a09f",
      "symbol": "BTC",
      "dex_name": "HL",
      "change": "down",
      "leverage_prev": 16.0,
      "leverage": 13.0,
      "mode_prev": "cross",
      "mode": "cross",
      "position_side_prev": "long",
      "position_side": "long",
      "size_usd_prev": 372105.54335999995,
      "size_usd": 304172.482124,
      "entry_price_prev": 79954.26056653017,
      "entry_price": 79954.21213080973
    },
    {
      "ts": "2026-10-27T12:19:00+00:00",
      "prev_ts": "2026-10-27T12:14:00+00:00",
      "captured_at": "2026-10-27T12:16:24+00:00",
      "prev_captured_at": "2026-10-27T12:04:25+00:00",
      "wallet": "0xfd7c556e671054891be52b5c50f9449bb05fc5b6",
      "symbol": "BTC",
      "dex_name": "HL",
      "change": "up",
      "leverage_prev": 35.0,
      "leverage": 39.0,
      "mode_prev": "cross",
      "mode": "cross",
      "position_side_prev": "short",
      "position_side": "short",
      "size_usd_prev": 644.5024800000001,
      "size_usd": 645.183588,
      "entry_price_prev": 80568.0,
      "entry_price": 80568.0
    },
    {
      "ts": "2026-10-27T12:19:00+00:00",
      "prev_ts": "2026-10-27T12:14:00+00:00",
      "captured_at": "2026-10-27T12:16:24+00:00",
      "prev_captured_at": "2026-10-27T12:04:25+00:00",
      "wallet": "0xfcf104006bfff47695c1dc21dad3e9de1e72098e",
      "symbol": "BTC",
      "dex_name": "HL",
      "change": "up",
      "leverage_prev": 1.0,
      "leverage": 2.0,
      "mode_prev": "cross",
      "mode": "cross",
      "position_side_prev": "short",
      "position_side": "short",
      "size_usd_prev": 948.78432,
      "size_usd": 6411.062195999999,
      "entry_price_prev": 79838.0,
      "entry_price": 79953.0
    }
  ],
  "nextCursor": "<opaque cursor>"
}

What a row is. A wallet's position in one market whose leverage setting or margin mode differs between two consecutive position snapshots. leverage_prev and leverage are the leverage the wallet had configured for that market at the two snapshots, not position size over account value; mode_prev and mode are cross or isolated. change is up or down when the leverage number moved and mode when only the margin mode did, so an up or down row whose mode_prev and mode differ moved both. The side (position_side_prev, position_side), the USD size and the entry price are given for both snapshots, which is how to tell an edit of the setting on a standing position from a position that was closed and reopened. symbol is the market's name, with the dex prefix for a builder-dex market (xyz:GOLD), and dex_name says which dex it belongs to.

When a row exists. The position must be open in both snapshots and its leverage known in both. A position that is flat at either snapshot, or whose leverage the snapshot does not report, never produces a row.

Choose the window. Without a wallet, a call with no start covers the 24 hours before end (before now by default). That floor slides with the clock, and a newest-first cursor without start stops at it, so pass start to read further back. A window of more than 31 days is a 400: from start to end (or now), from an order=asc cursor to end (or now), or from start to a newest-first cursor. An order=asc cursor replaces start as the window's lower edge (keep sending the same start and end: they are pinned in the cursor), so one more than 31 days old is a 400 too: restart with start (ISO 8601, UTC) and read a longer span in slices. Naming a wallet removes all of these rules. The feed holds the changes derived so far, so its earliest row is the earliest change we derived: an empty answer for an older window means nothing was derived there, not that nothing changed. symbol keeps one market, change takes up, down or mode, and min_leverage keeps rows whose new leverage is at least that value. limit takes 1 to 5000 and defaults to 100; a value above 5000 is a 422. An unknown order is a 400. A call costs 1 credit (Rate limits).

Page and follow. Newest first is the default, and nextCursor is null once a page holds fewer rows than limit. With order=asc the feed runs oldest first from start (or from your cursor), which is how to follow it: keep the last nextCursor and send it back with the same filters. In this mode nextCursor is never null once you hold a cursor, so stop a walk at the first empty page, not at a null; an empty page returns the cursor you sent, so a poller keeps its place. An empty first page with no start and no wallet returns a cursor at the lower edge of the 24-hour window, and with a start or a wallet it returns null: poll again with the same parameters. Changes arrive in batches, one per new capture of the positions (see the second warning), so most polls in between come back empty. Following a feed has the rules, and Freshness says how far behind the venue the feed runs.

What the feed cannot see

In this feed a leverage change is only what two consecutive position snapshots show. It does not see:

  • A change that reverts inside one interval: A to B to A reads as no change, and A to B to C reads as one change, A to C.
  • A position opened and closed between two snapshots.
  • A change made while the wallet was flat. The first sighting of a position carries whatever leverage is set, and that is not a change.
  • A position whose leverage is unknown. The snapshots report 0 for about 6% of position rows (2026-10-27), and a row with an unknown leverage on either side is never a change.
  • A close and reopen inside one interval with a different leverage reads as a change. Size and entry price differ, which is how to spot it.
  • A venue-driven change, such as a lowered maximum leverage that clamps the setting. It is indistinguishable from the wallet's own action.
  • Sub-accounts, which are separate wallets.
  • A stretch with no usable snapshots. A gap of more than 20 minutes between usable snapshots produces no row for the changes inside it. An incomplete snapshot is skipped and the next complete one is compared with the last one used, so that row spans a longer interval; prev_ts and prev_captured_at say how long.
  • A snapshot that does not show a newer capture. One with no capture time while other snapshots have one, or whose capture is older than the previous one's, can be a stale copy of an earlier capture. It is skipped like an incomplete snapshot, so a change that only it shows is not seen and the row that reports the change spans a longer interval. While a run of such snapshots lasts no row is produced, and a gap of more than 20 minutes between the snapshots used ends it with no row for the changes inside.

ts is a write stamp, not the time of the change

ts is when the later snapshot was written and prev_ts when the earlier one was. The positions in a snapshot were captured before it was written, by minutes: captured_at and prev_captured_at are those capture times, and the change happened between them. Positions are captured about every 12 minutes, not every 5, so consecutive snapshots often show the same capture and no change can appear between two of those. A row's interval (captured_at minus prev_captured_at) is usually about 12 minutes. Read a row as "between prev_captured_at and captured_at", never as "at ts". Both capture times are null when the capture time is unknown.

Example response
{  "items": [    {      "ts": "2026-10-27T12:19:00+00:00",      "prev_ts": "2026-10-27T12:14:00+00:00",      "captured_at": "2026-10-27T12:16:24+00:00",      "prev_captured_at": "2026-10-27T12:04:25+00:00",      "wallet": "0xfeee942a06d2f8012823ccde7bf7bcbcaa29a09f",      "symbol": "BTC",      "dex_name": "HL",      "change": "down",      "leverage_prev": 16.0,      "leverage": 13.0,      "mode_prev": "cross",      "mode": "cross",      "position_side_prev": "long",      "position_side": "long",      "size_usd_prev": 372105.54335999995,      "size_usd": 304172.482124,      "entry_price_prev": 79954.26056653017,      "entry_price": 79954.21213080973    },    {      "ts": "2026-10-27T12:19:00+00:00",      "prev_ts": "2026-10-27T12:14:00+00:00",      "captured_at": "2026-10-27T12:16:24+00:00",      "prev_captured_at": "2026-10-27T12:04:25+00:00",      "wallet": "0xfd7c556e671054891be52b5c50f9449bb05fc5b6",      "symbol": "BTC",      "dex_name": "HL",      "change": "up",      "leverage_prev": 35.0,      "leverage": 39.0,      "mode_prev": "cross",      "mode": "cross",      "position_side_prev": "short",      "position_side": "short",      "size_usd_prev": 644.5024800000001,      "size_usd": 645.183588,      "entry_price_prev": 80568.0,      "entry_price": 80568.0    },    {      "ts": "2026-10-27T12:19:00+00:00",      "prev_ts": "2026-10-27T12:14:00+00:00",      "captured_at": "2026-10-27T12:16:24+00:00",      "prev_captured_at": "2026-10-27T12:04:25+00:00",      "wallet": "0xfcf104006bfff47695c1dc21dad3e9de1e72098e",      "symbol": "BTC",      "dex_name": "HL",      "change": "up",      "leverage_prev": 1.0,      "leverage": 2.0,      "mode_prev": "cross",      "mode": "cross",      "position_side_prev": "short",      "position_side": "short",      "size_usd_prev": 948.78432,      "size_usd": 6411.062195999999,      "entry_price_prev": 79838.0,      "entry_price": 79953.0    }  ],  "nextCursor": "<opaque cursor>"}