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

# Hyperliquid liquidation map of every market

> GET /v1/liquidations/map/all returns the liquidation map of every Hyperliquid perp in one call, from one node snapshot. Builder plan, or 0.05 USDC a call with x402.

One call returns the [liquidation map](https://docs.ironflow.sh/api-reference/analytics/liquidation-map.md) of every market, all from the same node state snapshot and the same marks. Each market comes in its own auto bucket size (about 0.25% of its price), with running totals from the price and its long and short totals within `range_pct`.

**What is free and what is Builder:**

* **Builder and Enterprise:** every market in one call.
* **One call paid with x402:** 0.05 USDC on Base, at `https://api.ironflow.sh/x402/v1/liquidations/map/all`. No key needed. See [pay per call](https://docs.ironflow.sh/guides/pay-per-call.md).
* **Free keys, Explorer and calls without a key:** one market per call, with `GET /v1/liquidations/map?market=BTC-PERP`. Asking for every market answers `PLAN_REQUIRED` with the Builder plan in `upgrade` (a 402 with the x402 price while pay per call is on).

`GET /v1/liquidations/map` without `market`, or with `market=all`, is the same call.

## Poll it with ETag

The map is re-priced with fresh marks every minute and its positions come from a new snapshot about every 12 minutes. Each answer has an `ETag`; send it back as `If-None-Match` and an unchanged map answers `304 Not Modified` with no body:

```bash theme={null}
curl -si -H "Authorization: Bearer $IRONFLOW_KEY" \
  -H 'If-None-Match: W/"1211490000-1793900910-f-8c1f0e5a7d2b4c61"' \
  https://api.ironflow.sh/v1/liquidations/map/all
```

After a 304, count the snapshot's age from `snapshot.time`.


## OpenAPI

````yaml GET /v1/liquidations/map/all
openapi: 3.1.0
info:
  title: Ironflow API
  version: 1.0.0
  description: >
    Hyperliquid market data from Ironflow's own nodes: tick-level fills and

    trades, candles, funding rates, liquidations, mark prices, open interest,

    markets and wallet analytics over REST, live Server-Sent Events streams and

    read-only SQL. One schema across native HL perps, HIP-3 builder markets,

    HIP-4 outcome contracts and HL spot.


    The same data is a hosted MCP server for AI agents at

    `https://mcp.ironflow.sh/mcp`, and agents with a USDC wallet on Base can pay

    per call with x402, no key: the data GET endpoints are also served at

    `/x402/v1/...` (discovery: `https://api.ironflow.sh/openapi.json` and

    `https://api.ironflow.sh/.well-known/x402`).


    **Base URL:** `https://api.ironflow.sh`


    **Authentication:** Read endpoints work without a key (keyless access) or

    with a Bearer token in the `Authorization` header. Writes always need a key.

    ```

    Authorization: Bearer if_your_api_key

    ```

    Get a free key at https://ironflow.sh/key.


    **Access levels:**


    | Access | Requests per minute | Credits | History | Max range per request |

    |---|---|---|---|---|

    | No key | 30 per IP | 100 a day per IP (300 per app) | 24 hours | 1 hour |

    | Free key | 60 | 1,000 a day, 3,000 a month | 14 days | 6 hours |

    | Explorer | 100 | 25,000 a day | 90 days | 24 hours |

    | Builder | 1,000 | 250,000 a day | 1 year | 7 days |

    | Enterprise | 10,000 | no cap | everything stored | unlimited |


    No key, free keys, Explorer and calls paid with x402 are for personal and

    non-commercial use; Builder and Enterprise include commercial use (Terms
    15.2,

    https://ironflow.sh/terms).


    **Credits:** every call costs credits by what it does. A read (trades,

    fills, liquidations, candles, funding, open interest, prices, markets) costs

    1, analytics (the liquidation map, summary and heatmap, positions at a past

    time, wallet analytics, top traders, open interest changes, the hourly
    market

    panel) 5, SQL (`/v1/query`, also as `/v1/run_query` and `/v1/sql`, and the

    export) 10, and a live stream 1 to open and 1 a minute while it is open.

    Status, getting a key, plans and payment and the SQL schema cost nothing,
    and

    so does a call paid with x402. Any other endpoint costs 1. The full table:

    https://docs.ironflow.sh/concepts/rate-limits#credits


    Without a market filter, high-volume endpoints allow at most 4 hours per
    request.

    `/v1/trades` filtered to one perp or spot market allows 24 hours per request

    without a key and on a free key.

    Each caller can also read a set number of rows per hour: 2 billion without a
    key,

    10 billion on a free key, 100 billion on Explorer, 500 billion on Builder,
    none set

    on Enterprise. REST and SQL count separately. Over it, REST answers 429

    `READ_BUDGET_EXCEEDED` until the next hour.

    A header that is present but malformed returns 401; keyless access applies
    only

    when no `Authorization` header is sent. The keyless 100 credits a day are a

    rolling 24 hours per IP: past them, `KEYLESS_DAILY_LIMIT` (429, or 402 with
    x402

    payment terms) carries a `Retry-After` of the seconds until the next call
    fits.

    An app that names itself in its `User-Agent` (not an HTTP library, a browser

    or curl) also shares 300 keyless credits per rolling 24 hours across all its
    IPs,

    with the same error past them; a free key lifts both.

    A key's credits count per account across all its keys over the UTC day, and
    on

    a free key also over the UTC month (free keys from one address share one
    free

    quota). Keyed responses carry `X-Credits-Cost` (this call),
    `X-Credits-Daily-Limit`,

    `X-Credits-Daily-Remaining` and `X-Credits-Daily-Reset` (the next 00:00 UTC
    in Unix

    seconds), on a free key also `X-Credits-Monthly-Limit` and

    `X-Credits-Monthly-Remaining`; `X-RateLimit-Daily-Limit`,
    `X-RateLimit-Daily-Remaining`

    and `X-RateLimit-Daily-Reset` repeat the daily values. From 80% a notice
    says so.

    A call that does not fit in what is left gets `429 DAILY_QUOTA_EXCEEDED`
    with

    `Retry-After` until 00:00 UTC, or on a free key past the month

    `429 MONTHLY_QUOTA_EXCEEDED` with `Retry-After` until the 1st at 00:00 UTC,
    both

    with an `upgrade` object (Explorer for a free key, Builder for Explorer).

    Calls paid with x402 cost no credits and keep working.


    **Data availability:** fills and trades start on 25 May 2025; other

    datasets start later (funding 2025-09-27, open interest and mark prices

    2026-04-29). Bulk history is free to download from

    https://huggingface.co/ironflow.


    **Timestamps:** All timestamps are Unix milliseconds (int64).


    **Pagination:** Paginated endpoints return a `cursor` in
    `pagination.next_cursor`.

    Pass it as the `cursor` query parameter to fetch the next page.

    When `pagination.has_more` is `false`, you have reached the last page.


    **Notices:** a successful JSON object may start with `notice`, the

    `X-Ironflow-Notice` header in the body: what was served when it differs from

    what was asked (a keyless sample, a shortened history, a guessed path) and

    how to get the rest.


    **Guessed paths:** a few paths callers guess are answered by the endpoint

    they mean, with a `notice` and the `X-Ironflow-Canonical` header naming it:

    `/v1/liquidations/aggregate`, `/v1/summary/liquidations` and similar by

    `/v1/liquidations/summary`, `/v1/liquidations/buckets` and `heatmap` by

    `/v1/analytics/liquidation-levels`, and `/v1/liquidations/map/BTC-PERP` by

    `/v1/liquidations/map?market=BTC-PERP`. A path with trailing `.`, `,`, `;`
    or

    `)` (`/v1/query.`, copied from a sentence) is answered by the endpoint
    without

    them, with the same method, query and body. OpenAI-style paths
    (`/v1/models`,

    `/v1/chat/completions`) answer 404: this is not an LLM API, and agents use
    the

    MCP server above.
  contact:
    name: Ironflow Support
    url: https://ironflow.sh
servers:
  - url: https://api.ironflow.sh
    description: Production
security:
  - bearerAuth: []
  - {}
tags:
  - name: Hyperliquid RPC
    description: Your API key as a Hyperliquid /info URL, on your plan's limits.
  - name: Market Data
    description: Historical tick-level market data stored in ClickHouse.
  - name: Analytics
    description: >-
      Aggregated analytics. Net flows, funding stats and the liquidation map
      markets work without a key; liquidation levels, the liquidation map and
      the vault leaderboard return a sample without one; order flow needs a key
      (a free key works).
  - name: Cohorts
    description: Predefined and custom address groups for filtering market data.
  - name: Alerts
    description: >-
      Liquidation alerts that Ironflow posts to your webhook, Discord channel,
      Slack channel or Telegram chat.
  - name: Ironbox
    description: >-
      Secure, sandboxed environments in Tokyo, next to Hyperliquid, where a
      trading agent runs with Ironflow's data, analytics, alerts and execution.
      Any API key, free included.
  - name: Query
    description: >-
      Read-only ClickHouse SQL over curated Hyperliquid tables (hl.*), limited
      by tier.
  - name: Billing
    description: >-
      Paid plans, paid in USDC on Base or Hyperliquid, or with x402 on Base. No
      card, no account page.
  - name: System
    description: Health checks and metadata endpoints.
  - name: TradingApp
    description: >-
      The trading terminal's own endpoints (terminal.ironflow.sh),
      wallet-session auth. Not part of the public data API; left out of the docs
      copy.
paths:
  /v1/liquidations/map/all:
    get:
      tags:
        - Analytics
      summary: Liquidation map of every market (Builder)
      description: >
        Every Hyperliquid perp's liquidation map in one call, all from the same
        node state

        snapshot and the same marks. For each market: its levels in the auto
        bucket size (about

        0.25% of its mark) within `range_pct`, with running totals from the
        mark, and the long

        and short totals within the range. Markets come largest first (open
        notional within

        50% of mark). It answers what one call per market answered, from one
        snapshot.


        Builder and Enterprise keys. One call paid with x402 costs 0.05 USDC

        (GET https://api.ironflow.sh/x402/v1/liquidations/map/all). Free and
        Explorer keys and

        calls without a key get `PLAN_REQUIRED` with the Builder upgrade block,
        and while x402

        is on a 402 whose `PAYMENT-REQUIRED` header sells this one call; they
        read one market

        per call with GET /v1/liquidations/map?market=.


        Cached, re-priced and answered with an `ETag` like the one-market map:
        send it back as

        `If-None-Match` and an unchanged map answers 304 with no body.
        `bucket_size` is always

        auto here. GET /v1/liquidations/map without `market` is the same call.
      operationId: getLiquidationMapAll
      parameters:
        - name: range_pct
          in: query
          description: How far from each market's mark to cover, in percent each way.
          schema:
            type: number
            exclusiveMinimum: 0
            maximum: 50
            default: 20
        - name: side
          in: query
          description: Longs, shorts or both.
          schema:
            type: string
            enum:
              - both
              - long
              - short
            default: both
        - $ref: '#/components/parameters/IfNoneMatch'
      responses:
        '200':
          description: Every market's liquidation map.
          headers:
            ETag:
              $ref: '#/components/headers/LiquidationMapETag'
            Cache-Control:
              $ref: '#/components/headers/LiquidationMapCacheControl'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiquidationMapAll'
        '304':
          $ref: '#/components/responses/LiquidationMapNotModified'
        '400':
          $ref: '#/components/responses/BadRequest'
        '402':
          $ref: '#/components/responses/LiquidationMapAllPayment'
        '403':
          $ref: '#/components/responses/LiquidationMapPlanRequired'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/LiquidationMapUnavailable'
components:
  parameters:
    IfNoneMatch:
      name: If-None-Match
      in: header
      required: false
      description: >-
        The `ETag` of a map you already have. When the map has not changed the
        answer is 304 with no body.
      schema:
        type: string
        example: W/"1211490000-1793900910-f-8c1f0e5a7d2b4c61"
  headers:
    LiquidationMapETag:
      description: >-
        Names this answer of the map (snapshot height, pricing time, the
        request). Send it back as `If-None-Match`.
      schema:
        type: string
        example: W/"1211490000-1793900910-f-8c1f0e5a7d2b4c61"
    LiquidationMapCacheControl:
      description: >-
        `private, max-age=30`: the map is re-priced every minute and its
        snapshot changes about every 12.
      schema:
        type: string
        example: private, max-age=30
  schemas:
    LiquidationMapAll:
      type: object
      required:
        - as_of
        - snapshot
        - range_pct
        - side
        - count
        - markets
        - stale
        - method
      description: Every market's liquidation map, from one snapshot.
      properties:
        as_of:
          type: string
          format: date-time
          example: '2026-11-06T16:48:30Z'
          description: When the positions were last priced
        snapshot:
          type: object
          required:
            - height
            - time
            - age_s
          description: The node state snapshot every market's positions come from.
          properties:
            height:
              type: integer
              format: int64
              example: 1211490000
            time:
              type: string
              format: date-time
              example: '2026-11-06T16:47:28Z'
            age_s:
              type: integer
              example: 62
              description: Seconds since the snapshot
              counted when this answer was made: null
        range_pct:
          type: number
          example: 20
        side:
          type: string
          enum:
            - both
            - long
            - short
        count:
          type: integer
          example: 174
          description: Markets returned
        markets:
          type: array
          description: Markets, largest open notional first.
          items:
            $ref: '#/components/schemas/LiquidationMapAllMarket'
        stale:
          type: boolean
          description: >-
            True when the map service did not answer and an older map is
            returned
        method:
          type: string
          description: How the map is made
      example:
        as_of: '2026-11-06T16:48:30Z'
        snapshot:
          height: 1211490000
          time: '2026-11-06T16:47:28Z'
          age_s: 62
        range_pct: 20
        side: both
        count: 174
        markets:
          - market: BTC-PERP
            mark_px: 75782
            bucket_size: 200
            long_usd: 208900000
            short_usd: 62400000
            levels:
              - price_lo: 72600
                price_hi: 72800
                long_usd: 21480000
                long_positions: 412
                short_usd: 0
                short_positions: 0
                cum_long_usd: 208900000
                cum_short_usd: 0
            coverage:
              notional_usd: 3286600394
              with_liq_px_pct: 98.1
              portfolio_margin_pct: 6
              unknown_mode_pct: 0.5
        stale: false
        method: >-
          Every open position from our node's state snapshot. Liquidation prices
          follow Hyperliquid's maintenance margin rules; for cross-margin
          positions they assume the account's other positions stay at mark.
          Portfolio-margin accounts use Hyperliquid's own liquidationPx.
          Notional is size times liquidation price. In a real move correlated
          markets fall together, so cross-margin accounts are liquidated earlier
          than these prices.
    LiquidationMapAllMarket:
      type: object
      required:
        - market
        - mark_px
        - bucket_size
        - long_usd
        - short_usd
        - levels
        - coverage
      properties:
        market:
          type: string
          example: BTC-PERP
        mark_px:
          type: number
          example: 75782
        bucket_size:
          type: number
          example: 200
          description: The market's auto bucket size
          about 0.25% of its mark: null
        long_usd:
          type: number
          example: 208900000
          description: Longs liquidated within range_pct
        short_usd:
          type: number
          example: 62400000
          description: Shorts liquidated within range_pct
        levels:
          type: array
          items:
            $ref: '#/components/schemas/LiquidationMapLevel'
        coverage:
          type: object
          properties:
            notional_usd:
              type: number
            with_liq_px_pct:
              type: number
            portfolio_margin_pct:
              type: number
            unknown_mode_pct:
              type: number
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code.
              example: RATE_LIMIT_EXCEEDED
            message:
              type: string
              description: Human-readable error description.
              example: Rate limit exceeded. Retry after 60 seconds.
            upgrade:
              type: object
              description: >-
                On a limit a higher plan lifts, the next plan, its price, what
                it lifts and the call that gets it.
              properties:
                plan:
                  type: string
                  example: explorer
                price_usdc:
                  type: number
                  example: 49
                days:
                  type: integer
                  example: 30
                unlocks:
                  type: string
                  description: >-
                    What the plan adds, starting with SQL export to Parquet or
                    CSV
                limit:
                  type: string
                  description: >-
                    The limit this error hit: rate, history, window, sql_budget,
                    read_budget, streams, alerts, keyless_day or tier
                  example: rate
                lifts:
                  type: string
                  description: What the plan changes about that limit
                  example: 60 requests a minute now, 100 on Explorer
                url:
                  type: string
                  format: uri
                  description: Where to upgrade; the link carries the plan and the limit
                how:
                  type: string
                  description: The API call that opens the upgrade request
                buy_url:
                  type: string
                  format: uri
                  description: Buy this plan in one x402 call (USDC on Base)
                  when x402 is on: null
                pay_per_call:
                  type: object
                  description: On limits one paid call lifts
                  how to pay for this call with x402: null
            get_key:
              type: object
              description: >-
                On every keyless 429 (daily cap, per-minute rate, SQL and read
                budgets, stream cap) and keyless history refusal, the one call
                that gets a free key. `page` is the key page tagged with the
                refusal (utm_campaign).
              properties:
                method:
                  type: string
                  example: POST
                url:
                  type: string
                  format: uri
                  example: https://api.ironflow.sh/v1/keys
                body:
                  type: object
                  additionalProperties:
                    type: string
                  example:
                    email: you@example.com
                page:
                  type: string
                  format: uri
            dataset:
              type: object
              description: >-
                On `HISTORY_OUT_OF_RANGE`, and on a rate limit for a closed past
                range, the free download that holds the requested rows, when one
                does. The message repeats it with its dates.
              properties:
                name:
                  type: string
                  example: Hyperliquid Liquidations
                url:
                  type: string
                  format: uri
                  example: >-
                    https://huggingface.co/datasets/ironflow/hyperliquid-liquidations?utm_source=api
                holds:
                  type: string
                  example: every liquidation
                from:
                  type: string
                  format: date
                  example: '2025-05-25'
                through:
                  type: string
                  format: date
                  example: '2026-10-31'
            ironbox:
              type: object
              description: >-
                On a rate limit, the keyless credits, the daily and monthly
                credits, the stream limit, the SQL budget and the read budget,
                how to run the agent in an Ironbox instead.
              properties:
                why:
                  type: string
                  example: >-
                    No rate limits inside an Ironbox: your agent runs next to
                    Hyperliquid with the data on the box.
                create:
                  type: string
                  example: POST https://api.ironflow.sh/v1/ironbox
                url:
                  type: string
                  format: uri
                  example: https://ironflow.sh/ironbox?utm_source=api
            stream:
              type: string
              description: >-
                On the keyless daily credits, a per-minute rate limit, the read
                budget and a keyless history refusal of `/v1/liquidations` and
                `/v1/trades`, the live stream that replaces polling.
              example: >-
                GET https://api.ironflow.sh/v1/liquidations/stream (1 credit a
                minute)
            allowed_from:
              type: integer
              format: int64
              description: >-
                On `HISTORY_OUT_OF_RANGE`, the earliest `from` (Unix ms; `at` on
                `/v1/positions`) the caller's history reaches; a request from
                there is served.
              example: 1794394800000
            did_you_mean:
              type: array
              items:
                type: string
              description: >-
                On an unknown market (the liquidation map, the order book), the
                markets the name most likely meant. The message repeats them.
              example:
                - xyz:GOLD-PERP
                - PAXG-PERP
    LiquidationMapLevel:
      type: object
      required:
        - price_lo
        - price_hi
        - long_usd
        - long_positions
        - short_usd
        - short_positions
        - cum_long_usd
        - cum_short_usd
      properties:
        price_lo:
          type: number
          example: 72600
        price_hi:
          type: number
          example: 72800
        long_usd:
          type: number
          example: 21480000
          description: >-
            Notional of longs liquidated in this range (size times liquidation
            price)
        long_positions:
          type: integer
          example: 412
        short_usd:
          type: number
          example: 0
        short_positions:
          type: integer
          example: 0
        cum_long_usd:
          type: number
          example: 208900000
          description: Longs liquidated from the mark down to this level
        cum_short_usd:
          type: number
          example: 0
          description: Shorts liquidated from the mark up to this level
  responses:
    LiquidationMapNotModified:
      description: >-
        The map has not changed since the `ETag` sent in `If-None-Match`. No
        body.
      headers:
        ETag:
          $ref: '#/components/headers/LiquidationMapETag'
        Cache-Control:
          $ref: '#/components/headers/LiquidationMapCacheControl'
    BadRequest:
      description: Invalid request parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: BAD_REQUEST
              message: market is required (e.g. BTC-PERP)
    LiquidationMapAllPayment:
      description: >-
        `PLAN_REQUIRED` for a key below Builder or a call without a key, while
        x402 is on: the `PAYMENT-REQUIRED` header sells this one call for 0.05
        USDC on Base. The body is the 403's, with `upgrade.pay_per_call`.
      headers:
        PAYMENT-REQUIRED:
          description: >-
            x402 payment terms (base64 JSON). Pay them and retry with
            `PAYMENT-SIGNATURE`.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    LiquidationMapPlanRequired:
      description: >-
        `PLAN_REQUIRED`: every market in one call is a Builder feature. The
        `upgrade` block names Builder and how to get it; ask one market per call
        with `market=` instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: PLAN_REQUIRED
              message: >-
                One call returns all 174 markets on Builder (149 USDC per 30
                days): https://ironflow.sh/upgrade?utm_source=api&plan=builder.
                Free keys get one market per call: add market=BTC-PERP (GET
                /v1/liquidations/map/markets lists the markets). Or pay 0.05
                USDC for this one call with x402.
              upgrade:
                plan: builder
                price_usdc: 149
                days: 30
                limit: tier
                lifts: included in Builder
                url: >-
                  https://ironflow.sh/upgrade?utm_source=api&plan=builder&limit=tier
    RateLimited:
      description: >-
        Rate limit exceeded: `RATE_LIMIT_EXCEEDED` (per minute),
        `KEYLESS_DAILY_LIMIT` (keyless credits per IP or per app),
        `DAILY_QUOTA_EXCEEDED` (the call does not fit in the account's credits
        left for the UTC day; `Retry-After` runs to 00:00 UTC) or
        `MONTHLY_QUOTA_EXCEEDED` (a free key's credits for the UTC month;
        `Retry-After` runs to the 1st at 00:00 UTC). On the credit refusals
        `upgrade` names the plan: Explorer for a free key, Builder for Explorer.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            example: 60
        X-Credits-Cost:
          description: What the refused call would cost in credits.
          schema:
            type: integer
            example: 10
        X-Credits-Daily-Remaining:
          description: The credits left today (keyless, over the rolling 24 hours).
          schema:
            type: integer
            example: 5
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: RATE_LIMIT_EXCEEDED
              message: Rate limit exceeded. Retry after 60 seconds.
    LiquidationMapUnavailable:
      description: >-
        The map is not ready (its service is starting) or its service did not
        answer and no recent map is cached. Retry after the Retry-After seconds.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            example: 30
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UPSTREAM_UNAVAILABLE
              message: >-
                the liquidation map is not available right now (it is being
                built or its service did not answer); retry in 30 seconds
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Ironflow API key, format `if_xxxx`. Free keys at
        https://ironflow.sh/key. Optional on read endpoints.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.