Skip to content

Quick Start Guide

Everything you need to integrate the Hyperlight API — from your first API key to production.

Getting Your API Key

Create an account and get your API key in under a minute. Every key is prefixed with hlt_ and shown exactly once — save it somewhere safe.

Register via API

Send a single POST request to create your account. The response includes a JWT token for dashboard access and your first API key.

Tip: Your API key is shown exactly once in the response. Copy it immediately — the server only stores a SHA-256 hash.
Tip: The free tier includes 75K credits/month and 30 requests/minute.
curl -X POST https://api.hyperlightapi.xyz/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@example.com",
    "password": "your-secure-password",
    "tos_accepted": true
  }'

Register via Website

Prefer a UI? Visit hyperlightapi.xyz/auth/signup to create your account with email or GitHub OAuth. Your API key appears on the dashboard after signup.

Understanding Your API Key

All Hyperlight API keys start with the prefix hlt_ followed by 48 hex characters. Example: hlt_7kT9BxQ4mN2pR8vL1wX5yZ3aD6fG9hJ0kS.

The server never stores your full key — only its SHA-256 hash. If you lose your key, you cannot recover it. Create a new one from your dashboard or via the API.

Authentication

Pass your API key via header, bearer token, or query parameter. WebSocket connections authenticate with the first message.

X-Api-Key Header (Recommended)

The simplest and most secure method for REST calls.

curl https://api.hyperlightapi.xyz/api/v1/orderbook/0 \
  -H "X-Api-Key: hlt_your_key_here"

Authorization Bearer

Works with both API keys and JWT tokens. Useful when your HTTP client already sets an Authorization header.

curl
# With API key
curl https://api.hyperlightapi.xyz/api/v1/orderbook/0 \
  -H "Authorization: Bearer hlt_your_key_here"

# With JWT (from login/register)
curl https://api.hyperlightapi.xyz/api/v1/keys \
  -H "Authorization: Bearer eyJhbG..."

Query Parameter

Pass your key as a query parameter. Convenient for quick testing but avoid in production — URLs can appear in logs and browser history.

curl
curl "https://api.hyperlightapi.xyz/api/v1/orderbook/0?api_key=hlt_your_key_here"

WebSocket Authentication

The first message on any WebSocket connection must be an auth message. You have 10 seconds to authenticate before the server closes the connection.

Message
// Client sends:
{"type": "auth", "api_key": "hlt_your_key_here"}

// Server responds:
{"type": "authenticated", "tier": "free", "max_subscriptions": 5}

Your First API Call

Start with a health check, then fetch live data. Every response follows the same envelope format.

Health Check (No Auth Required)

Verify the API is reachable. No authentication needed.

curl https://api.hyperlightapi.xyz/health

Get an Orderbook

Fetch the current orderbook for market 0 (ETH-PERP). Data is served from Redis cache with sub-second freshness.

curl https://api.hyperlightapi.xyz/api/v1/orderbook/0 \
  -H "X-Api-Key: hlt_your_key_here"

Batch Query Accounts

Query multiple accounts in a single request — the signature Hyperlight feature. Lighter's native API only supports one account per request.

curl -X POST https://api.hyperlightapi.xyz/api/v1/accounts/batch \
  -H "X-Api-Key: hlt_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"accounts": [0, 1, 2, 3, 4], "by": "index"}'

Understanding the Response Envelope

Every response follows the same structure. Check success first, then read data. The meta object includes a unique request_id for tracing.

{
  "success": true,
  "data": { ... },
  "meta": {
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": 1706745600000,
    "total": 100,
    "limit": 50,
    "offset": 0
  }
}

REST Endpoints by Category

43 REST endpoints organized by function. All authenticated endpoints require an API key unless noted.

Accounts & Batch Queries

Batch endpoints accept up to your tier's batch size limit (5 for Free, up to 5,000 for Enterprise).

MethodPathDescription
POST/api/v1/accounts/batchBatch query accounts (positions, orders, fills)
POST/api/v1/accounts/batch/fillsBatch fills across accounts
POST/api/v1/accounts/batch/positionsBatch positions across accounts
POST/api/v1/accounts/batch/liquidationsBatch liquidation events
GET/api/v1/accounts/:id/positionsSingle account positions
GET/api/v1/accounts/:id/fillsSingle account fill history
GET/api/v1/accounts/:id/pnlPnL snapshot history
GET/api/v1/accounts/:id/liquidation-riskLiquidation risk estimate

Orderbook

MethodPathDescription
GET/api/v1/orderbook/:market_idCurrent orderbook (Redis-cached, sub-second)
GET/api/v1/orderbook/:market_id/depthAggregated depth at custom price levels
GET/api/v1/orderbook/:market_id/snapshotsHistorical orderbook at any point in time

Trades & Candles

MethodPathDescription
GET/api/v1/trades/by-timeTrades within arbitrary time ranges
GET/api/v1/trades/aggregateVWAP + volume aggregation at custom intervals
GET/api/v1/candlesOHLCV candles (1m to 1w resolution)

Liquidations

MethodPathDescription
GET/api/v1/liquidations/by-timeLiquidation events in a time range
GET/api/v1/liquidations/recentRecent liquidations across all markets
GET/api/v1/liquidation-heatmap/:market_idLiquidation level heatmap
GET/api/v1/liquidation-heatmap/:market_id/cascadeCascade effect analysis

Funding Rates

MethodPathDescription
GET/api/v1/funding-ratesCurrent funding rates for all markets
GET/api/v1/funding-rates/historyHistorical funding rate data

Exchange Analytics

MethodPathDescription
GET/api/v1/exchange/stats24h volume, open interest, price changes
GET/api/v1/exchange/metricsHistorical exchange-level metrics
GET/api/v1/markets/:market_id/top-accountsTop accounts by position size (tier-limited)
GET/api/v1/exchange/top-accountsTop accounts exchange-wide by total notional (tier-limited)

Data Lake

Parquet exports for backtesting and analytics. Available on paid tiers.

MethodPathDescription
GET/api/v1/data-lake/exportsList available Parquet exports
GET/api/v1/data-lake/download/:export_idPre-signed S3 download URL

Signal Engine (Custom Alerts)

Create rules that trigger webhooks based on market conditions. See the Signal Engine section below for full details.

MethodPathDescription
POST/api/v1/signalsCreate alert rule (JSON DSL)
GET/api/v1/signalsList your alerts
GET/api/v1/signals/:signal_idGet alert details
PATCH/api/v1/signals/:signal_idUpdate alert rule
DELETE/api/v1/signals/:signal_idDelete alert
GET/api/v1/signals/:signal_id/backtestBacktest against historical data

API Key Management

MethodPathDescription
POST/api/v1/keysCreate new API key
GET/api/v1/keysList your keys (prefix only)
PATCH/api/v1/keys/:key_idUpdate key (name, IP allowlist)
DELETE/api/v1/keys/:key_idRevoke key
GET/api/v1/keys/:key_id/usageHourly usage breakdown

Auth, Billing & Health

MethodPathAuthDescription
GET/healthNoService health check
GET/statusNoLighter network status
POST/api/v1/auth/registerNoRegister and get API key + JWT
POST/api/v1/auth/loginNoLogin and get JWT token
POST/api/v1/billing/checkoutJWTCreate Stripe checkout session
POST/api/v1/billing/portalJWTCreate Stripe customer portal

WebSocket Streaming

Connect to the WebSocket endpoint for real-time orderbook updates, enriched trades, whale alerts, and liquidation heatmaps.

Connecting & Authenticating

Connect to the WebSocket endpoint and send an auth message as your first message. The server responds with your tier and subscription limit.

# Install: npm install -g wscat
wscat -c wss://api.hyperlightapi.xyz/ws

# Once connected, send:
{"type": "auth", "api_key": "hlt_your_key_here"}

Available Channels

Subscribe and unsubscribe to channels by sending JSON messages. Replace {market_id} with the numeric market ID (0 = ETH-PERP).

ChannelDescription
order_book/{market_id}Live orderbook updates (direct upstream proxy)
enriched_order_book/{market_id}Orderbook with account attribution and whale flags
enriched_trade/{market_id}Trades with account attribution
trade/{market_id}Raw trade updates
alert/{market_id}Large order and whale activity alerts
liquidation_heatmap/{market_id}Liquidation level heatmap updates
Subscribe/Unsubscribe
// Subscribe
{"type": "subscribe", "channel": "trade/0"}
// → {"type": "subscribed", "channel": "trade/0"}

// Unsubscribe
{"type": "unsubscribe", "channel": "trade/0"}
// → {"type": "unsubscribed", "channel": "trade/0"}

Data Message Format

Channel data arrives in a standard envelope with the channel name and a server timestamp.

{
  "type": "trade_update",
  "channel": "trade/0",
  "trade": {
    "trade_id": 12345,
    "price": "3200.50",
    "size": "2.5",
    "is_maker_ask": true,
    "ask_account_id": 42,
    "bid_account_id": 99,
    "market_id": 0,
    "timestamp": 1706700000123
  }
}

Connection Limits

WebSocket connections are rate-limited to 30 messages/second (burst of 60). After 3 consecutive violations, the connection is closed. The server sends a ping every 30 seconds — your client must respond with a pong within 10 seconds.

Backtesting Replay

Replay historical orderbook snapshots and trades via WebSocket at 0.1x–100x speed. Point your trading bot at the replay endpoint and test strategies against real market data.

Starting a Replay

Connect to the /ws/replay endpoint, authenticate, then send a replay command with your desired market, time range, and playback speed.

Python
import asyncio, websockets, json

async def replay():
    async with websockets.connect("wss://api.hyperlightapi.xyz/ws/replay") as ws:
        # Authenticate
        await ws.send(json.dumps({
            "type": "auth",
            "api_key": "hlt_your_key_here"
        }))
        print(json.loads(await ws.recv()))  # authenticated

        # Start replay: ETH-PERP, 1 hour, 10x speed
        await ws.send(json.dumps({
            "type": "replay",
            "market_id": 0,
            "start": "2026-01-01T00:00:00Z",
            "end": "2026-01-01T01:00:00Z",
            "speed": 10.0
        }))

        async for msg in ws:
            event = json.loads(msg)
            if event["type"] == "replay_event":
                print(f"[{event['event_type']}] {event['data']}")
            elif event["type"] == "replay_complete":
                print(f"Done! {event['events_sent']} events")
                break

asyncio.run(replay())

Playback Controls

Pause, resume, or stop a replay at any time. Only one replay can be active per connection — send stop before starting another.

Commands
{"type": "pause"}    // → {"type": "replay_paused"}
{"type": "resume"}   // → {"type": "replay_resumed"}
{"type": "stop"}     // → {"type": "replay_stopped"}

Replay Event Types

Events arrive in chronological order, interleaving trades and orderbook snapshots. Each event has the original timestamp (ts) and the wall-clock replay timestamp (replay_ts).

{
  "type": "replay_event",
  "event_type": "trade",
  "data": {
    "market_id": 0,
    "trade_id": 12345,
    "price": "3200.50",
    "size": "2.5",
    "side": "buy"
  },
  "ts": 1717200330000,
  "replay_ts": 1706700050000
}

Replay Tier Limits

The maximum replay window and number of concurrent replays depend on your tier.

TierMax Replay WindowConcurrent Replays
FreeDisabled0
Starter7 days2
Growth30 days5
Scale90 days10
EnterpriseUnlimitedUnlimited

Signal Engine (Custom Alerts)

Define alert rules using a JSON DSL. When market conditions match, Hyperlight sends a webhook to your endpoint with HMAC-SHA256 signing.

Creating a Signal

Define a rule, a delivery channel (webhook URL + secret), and optional cooldown. The rule evaluates in real-time against live market data.

curl
curl -X POST https://api.hyperlightapi.xyz/api/v1/signals \
  -H "Authorization: Bearer <your_jwt_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ETH price alert",
    "market_id": 0,
    "rule_definition": {
      "conditions": [
        {"field": "trade_price", "op": "gt", "value": 4000}
      ],
      "logic": "AND"
    },
    "delivery_channels": [
      {
        "type": "webhook",
        "url": "https://your-app.com/webhook",
        "secret": "your-hmac-secret-min-16-chars"
      }
    ],
    "cooldown_secs": 300
  }'

Rule DSL Reference

Rules are JSON objects with conditions (each having a field, op, and value), combined with AND/OR logic. Available fields: trade_price, trade_size, trade_notional, orderbook_spread, bid_depth, ask_depth, funding_rate, heatmap_long_at_risk, heatmap_short_at_risk.

OperatorDescriptionExample
gtField > value{"field": "trade_price", "op": "gt", "value": 4000}
ltField < value{"field": "trade_price", "op": "lt", "value": 3000}
gteField >= value{"field": "trade_size", "op": "gte", "value": 100}
lteField <= value{"field": "orderbook_spread", "op": "lte", "value": 0.01}
eqField == value{"field": "funding_rate", "op": "eq", "value": 0}
neField != value{"field": "funding_rate", "op": "ne", "value": 0}
crosses_aboveField crosses above value{"field": "trade_price", "op": "crosses_above", "value": 4000}
crosses_belowField crosses below value{"field": "trade_price", "op": "crosses_below", "value": 3000}
Compound rule
{
  "conditions": [
    {"field": "trade_price", "op": "gt", "value": 4000},
    {"field": "trade_size", "op": "gt", "value": 50}
  ],
  "logic": "AND"
}

Backtesting a Signal

Test your rule against historical data before activating it. The backtest endpoint returns how many times the rule would have triggered.

curl
curl "https://api.hyperlightapi.xyz/api/v1/signals/{signal_id}/backtest?start=1767225600000&end=1767312000000" \
  -H "Authorization: Bearer <your_jwt_token>"

Rate Limiting & Tiers

Rate limits are enforced per API key. Every response includes rate limit headers so you can track your usage.

Rate Limit Headers

Every response includes these headers:

HeaderDescription
X-RateLimit-LimitYour tier's max requests per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUNIX timestamp when the window resets
Retry-AfterSeconds to wait (only on 429 responses)

Tier Comparison

TierPriceRate LimitBatch SizeCredits/MonthWS Connections
FreeFree30/min575K1
Starter$199300/min200750K50
Growth$8493,000/min1,0005M500
Scale$1,79930,000/min2,50025M1,000
EnterpriseCustomUnlimited5,000UnlimitedUnlimited

Handling 429 Responses

When you exceed your rate limit, the API returns HTTP 429. Use the Retry-After header to know how long to wait.

Python
import time, requests

def api_call(url, headers):
    resp = requests.get(url, headers=headers)
    if resp.status_code == 429:
        wait = int(resp.headers.get("Retry-After", 60))
        print(f"Rate limited. Waiting {wait}s...")
        time.sleep(wait)
        return api_call(url, headers)  # retry
    return resp.json()

Verification Checklist

Run through these steps to confirm your integration is working correctly.

Step-by-Step Verification

Run each command and verify you get the expected response. Replace hlt_your_key_here with your actual API key.

Full checklist
# 1. Health check (no auth)
curl -s https://api.hyperlightapi.xyz/health | jq .status
# Expected: "ok"

# 2. Orderbook (auth required)
curl -s https://api.hyperlightapi.xyz/api/v1/orderbook/0 \
  -H "X-Api-Key: hlt_your_key_here" | jq .success
# Expected: true

# 3. Trades in time range
curl -s "https://api.hyperlightapi.xyz/api/v1/trades/by-time?market_id=0&start=2026-01-01T00:00:00Z&end=2026-01-02T00:00:00Z&limit=5" \
  -H "X-Api-Key: hlt_your_key_here" | jq '.data.trades | length'
# Expected: > 0

# 4. Batch query 5 accounts
curl -s -X POST https://api.hyperlightapi.xyz/api/v1/accounts/batch \
  -H "X-Api-Key: hlt_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"accounts": [0,1,2,3,4], "by": "index"}' | jq '.data.accounts | length'
# Expected: up to 5

# 5. Current funding rates
curl -s https://api.hyperlightapi.xyz/api/v1/funding-rates \
  -H "X-Api-Key: hlt_your_key_here" | jq '.data.rates | length'
# Expected: > 0

# 6. Exchange stats
curl -s https://api.hyperlightapi.xyz/api/v1/exchange/stats \
  -H "X-Api-Key: hlt_your_key_here" | jq .success
# Expected: true

# 7. Check rate limit headers
curl -sI https://api.hyperlightapi.xyz/api/v1/orderbook/0 \
  -H "X-Api-Key: hlt_your_key_here" | grep -i x-ratelimit
# Expected: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset

# 8. WebSocket (requires wscat: npm i -g wscat)
# wscat -c wss://api.hyperlightapi.xyz/ws
# > {"type":"auth","api_key":"hlt_your_key_here"}
# < {"type":"authenticated",...}
# > {"type":"subscribe","channel":"order_book/0"}
# < {"type":"subscribed","channel":"order_book/0"}

Error Handling

All errors follow the standard response envelope with a code and human-readable message.

Error Codes

CodeHTTP StatusDescription
unauthorized401Missing or invalid API key
forbidden403Key expired, disabled, or IP not allowed
bad_request400Invalid query parameters
not_found404Resource not found
rate_limit_exceeded429Tier rate limit exceeded
batch_too_large400Batch size exceeds tier limit
internal_error500Server error
upstream_error502Lighter API unavailable

Error Response Example

429 Response
{
  "success": false,
  "data": {
    "code": "rate_limit_exceeded",
    "message": "rate limit exceeded"
  },
  "meta": {
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": 1706745600000
  }
}

Production Best Practices

Tips for building reliable integrations.

Recommendations

Use batch endpoints instead of looping: A single POST /api/v1/accounts/batch replaces hundreds of individual requests and costs only 25 credits regardless of batch size.

Monitor rate limit headers: Track X-RateLimit-Remaining and back off before you hit 429. This is more efficient than retrying after the fact.

Implement WebSocket reconnection: Connections can drop due to network issues or server restarts. Use exponential backoff (1s, 2s, 4s, 8s, max 30s) when reconnecting.

Rotate API keys periodically: Create a new key, update your services, then delete the old one. Hyperlight supports multiple active keys per account.

Use IP allowlists: Lock your production keys to specific IP addresses via PATCH /api/v1/keys/:key_id with an allowed_ips array.

Cache responses where appropriate: Orderbook and funding rate data is cached server-side with sub-second freshness. For lower-frequency use cases, cache locally to avoid unnecessary requests.

Use the health endpoint for monitoring: Add GET /health to your uptime monitoring. It checks all dependencies (PostgreSQL, Redis, Lighter API).