LAZY EDGE NBA
Log In Get Started

API Reference

Institutional-grade edge signals with execution routing keys, top-of-book prices, and Hawkes momentum physics. Built for algorithmic traders.

Base URL

https://api.lazyedge.net/v1

All endpoints are prefixed with /v1. HTTPS is required.

Quickstart: Python Bot in 30 Seconds

This is everything you need to receive live edge signals and route them to Kalshi. No string parsing. No ticker lookups. Just pull the trigger.

import requests, time

API_KEY = "le_your_key_here"
BASE    = "https://api.lazyedge.net/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

while True:
    edges = requests.get(f"{BASE}/edges/live", headers=HEADERS).json()

    for edge in edges:
        # Latency guard: skip if signal is older than 500ms
        age_ms = int(time.time() * 1000) - edge["computed_at_ms"]
        if age_ms > 500:
            continue

        # Only trade expanding edges with momentum
        if (edge["trade_signal"] == "BUY"
            and edge["edge_score"] > 0.04
            and edge["hawkes_flag"] == "SURGE_HOME"
            and edge["edge_velocity"] > 0):

            print(f"EXECUTING: {edge['target_kalshi_ticker']}")
            print(f"  Side: {edge['target_side']}")
            print(f"  Ask:  {edge['kalshi_best_ask']}")
            print(f"  Edge: {edge['edge_score']:.1%}")
            print(f"  Kelly: {edge['kelly']:.1%}")

            # Your execution logic here:
            # kalshi_client.create_order(
            #     ticker=edge["target_kalshi_ticker"],
            #     side="yes",
            #     price=edge["kalshi_best_ask"],
            #     count=int(bankroll * edge["kelly"])
            # )

    time.sleep(2)  # Poll every 2 seconds

That's it. The target_kalshi_ticker is the exact string Kalshi's API requires for order submission. No mapping tables. No string-matching hacks. One variable assignment from signal to execution.

Authentication

Pass your API key as a Bearer token in the Authorization header:

curl -H "Authorization: Bearer le_your_key_here" \
  https://api.lazyedge.net/v1/edges/live

Getting Your API Key

  1. Create an account (free)
  2. Subscribe to Recon ($49/mo), Alpha ($99/mo), or Terminal ($199/mo)
  3. Your API key is generated automatically and shown on your Account page

Keys are prefixed with le_. Keep them secret—treat them like passwords. If compromised, regenerate from your Account page.

Keys are hashed with SHA-256 before storage. We never see your raw key after generation.

Rate Limits

TierDaily LimitBurst RatePrice
FREE No API access $0
RECON 100 calls/day 5 req/sec $49/mo
ALPHA 2,000 calls/day 10 req/sec $99/mo
TERMINAL 10,000 calls/day 50 req/sec $199/mo
ENTERPRISE Unlimited 100 req/sec Custom

WebSocket requires Alpha ($99) or above. Recon Node users get REST-only access. The /v1/ws/edges WebSocket pushes live edge updates to Alpha+ clients in real-time with no call counting. Use REST for bootstrapping (/games/today) and usage checks. Use WebSocket for live trading.

Recon Node ($49): Gets edge signals, trade signals, and Kelly sizing via REST. Does NOT include execution routing keys, top-of-book bid/ask, Hawkes momentum, or WebSocket. Designed for dashboard-first manual traders evaluating the data.

Rate Limit Headers

Every response includes these headers:

HeaderDescription
X-RateLimit-LimitMax requests per day for your tier
X-RateLimit-RemainingRequests remaining today
X-RateLimit-ResetUTC epoch timestamp when limit resets
Retry-AfterSeconds to wait (only on 429 responses)

Edge Signal Payload

Every edge signal includes execution routing keys, top-of-book prices, and momentum physics. This is the complete payload your bot receives:

{
  "game_id": "401585901",
  "home_team": "PHX",
  "away_team": "LAL",
  "period": 3,
  "clock": "4:22",
  "home_score": 87,
  "away_score": 82,

  "trade_signal": "BUY",
  "target_side": "YES",
  "target_kalshi_ticker": "KXNBAGAME-01APR26LALPHX-PHX",
  "target_polymarket_id": "0x1234abcd...",

  "our_prob": 0.72,
  "edge_score": 0.05,
  "kelly": 0.08,

  "kalshi_best_bid": 0.63,
  "kalshi_best_ask": 0.67,
  "kalshi_implied": 0.65,

  "edge_velocity": 1.5,
  "hawkes_flag": "SURGE_HOME",
  "momentum_state": "BLEED_OUT",

  "computed_at_ms": 1711984210555,
  "timestamp": "2026-04-01T23:45:10.555Z",

  "kalshi_home_ticker": "KXNBAGAME-01APR26LALPHX-PHX",
  "kalshi_away_ticker": "KXNBAGAME-01APR26LALPHX-LAL",
  "kalshi_event_prefix": "KXNBAGAME-01APR26LALPHX",
  "polymarket_condition_id": "0x1234abcd...",
  "polymarket_slug": "lakers-vs-suns-april-1"
}

Field Reference

Game State

FieldTypeDescription
game_idstringESPN game ID (primary key for cross-referencing)
home_teamstringHome team 3-letter abbreviation (PHX, LAL, BOS...)
away_teamstringAway team 3-letter abbreviation
periodintCurrent quarter (1-4, 5+ for OT). 0 = pregame
clockstringGame clock ("4:22", "0:00"). Empty if pregame
home_scoreintHome team score
away_scoreintAway team score

The Alpha — Execution Routing

FieldTypeDescription
trade_signalstringBUY (edge ≥ +3%), SELL (edge ≤ -3%), or HOLD
target_sidestring"YES" or "NO" — which side of the contract to buy. Empty on HOLD
target_kalshi_tickerstringExact Kalshi contract ticker to execute on. Pass directly to Kalshi order API
target_polymarket_idstringExact Polymarket condition ID to execute on

The Math — Signal Strength

FieldTypeDescription
our_probfloatLazy Edge computed win probability (0-1). Derived from Dynamic Skellam engine + 4 enrichment layers
edge_scorefloatRaw alpha: our_prob minus market mid-price. Positive = underpriced, negative = overpriced
kellyfloatFractional Kelly bet size (0-1). Pre-computed with quarter-Kelly bankroll fraction

The Market — Top of Book

FieldTypeDescription
kalshi_best_bidfloatBest bid price on Kalshi (0-1). What you'd receive if selling
kalshi_best_askfloatBest ask price on Kalshi (0-1). What you'd pay to buy. This is your execution cost
kalshi_impliedfloatMid-price: (bid + ask) / 2. The market's implied probability

Why this matters: If our_prob is 0.72 and kalshi_implied is 0.65, your raw edge is +7%. But to enter, you cross the spread at kalshi_best_ask = 0.67. Your realizable edge is only +5%. Bots that calculate risk on mid-prices bleed money to the spread.

The Physics — Momentum & Velocity

FieldTypeDescription
edge_velocityfloatTrailing edge change between consecutive signals. Positive = edge expanding, negative = edge shrinking
hawkes_flagstringDirectional momentum state. SURGE_HOME = home team on a scoring run with expanding edge. SURGE_AWAY = away team surging. FADING = momentum decaying. NEUTRAL = no significant run
momentum_statestringRaw Hawkes intensity bucket: NEUTRAL (γ < 0.5), HIGH_VOLATILITY (0.5-1.5), BLEED_OUT (1.5-3.0), FLASH_CRASH (γ ≥ 3.0)

Trading with momentum: A +4.2% edge with hawkes_flag: "SURGE_HOME" and edge_velocity: +1.5 means the home team is on an unanswered run AND the edge is expanding. The optimal entry. A +4.2% edge with hawkes_flag: "FADING" means the run is cooling off—the market will correct and your edge may vanish before fill.

Timing — Latency Guard

FieldTypeDescription
computed_at_msintUNIX millisecond timestamp when the Skellam engine finalized this signal. Use for staleness detection
timestampstringISO 8601 timestamp of the signal

Latency guard pattern:

age_ms = int(time.time() * 1000) - edge["computed_at_ms"]
if age_ms > 500:
    skip()  # Signal is stale — market makers already moved the line

Routing Keys — Market Cross-Reference

FieldTypeDescription
kalshi_home_tickerstringKalshi home team contract ticker (e.g., KXNBAGAME-01APR26LALPHX-PHX)
kalshi_away_tickerstringKalshi away team contract ticker
kalshi_event_prefixstringKalshi event prefix (shared between home/away contracts)
polymarket_condition_idstringPolymarket condition ID for this game
polymarket_slugstringPolymarket URL slug for this game

REST Endpoints

All endpoints require Authorization: Bearer <key> header.

GET /v1/edges/live Live edge signals for all active games +

Description

Returns the latest edge signal for each active game. This is the primary endpoint for algorithmic trading bots. Includes execution routing keys, top-of-book prices, and Hawkes momentum flags.

Query Parameters

ParameterTypeDescription
min_edgefloatMinimum absolute edge score (default: 0). Set to 0.03 to only get actionable signals

Tier

RECON and above (Recon gets basic fields; Alpha+ gets full God Tier payload with routing keys, bid/ask, momentum)

Example Request

curl -H "Authorization: Bearer le_your_key_here" \
  "https://api.lazyedge.net/v1/edges/live?min_edge=0.03"

Example Response

[
  {
    "game_id": "401585901",
    "home_team": "PHX", "away_team": "LAL",
    "period": 3, "clock": "4:22",
    "home_score": 87, "away_score": 82,
    "trade_signal": "BUY",
    "target_side": "YES",
    "target_kalshi_ticker": "KXNBAGAME-01APR26LALPHX-PHX",
    "target_polymarket_id": "0x1234abcd...",
    "our_prob": 0.72, "edge_score": 0.05, "kelly": 0.08,
    "kalshi_best_bid": 0.63, "kalshi_best_ask": 0.67,
    "kalshi_implied": 0.65,
    "edge_velocity": 1.5,
    "hawkes_flag": "SURGE_HOME",
    "momentum_state": "BLEED_OUT",
    "computed_at_ms": 1711984210555,
    "timestamp": "2026-04-01T23:45:10.555Z",
    "kalshi_home_ticker": "KXNBAGAME-01APR26LALPHX-PHX",
    "kalshi_away_ticker": "KXNBAGAME-01APR26LALPHX-LAL",
    "kalshi_event_prefix": "KXNBAGAME-01APR26LALPHX",
    "polymarket_condition_id": "0x1234abcd...",
    "polymarket_slug": "lakers-vs-suns-april-1"
  }
]
GET /v1/edges/game/{game_id} Edge time series for a specific game +

Description

Returns the chronological edge signal history for a specific game. Each entry includes edge_velocity computed between consecutive signals. Use for backtesting execution timing against historical momentum shifts.

Path & Query Parameters

ParameterTypeDescription
game_idstringESPN game ID (from /v1/games/today)
limitintNumber of entries (1-100, default: 20)

Tier

ALPHA and above

Example Request

curl -H "Authorization: Bearer le_your_key_here" \
  "https://api.lazyedge.net/v1/edges/game/401585901?limit=50"
GET /v1/games/today Today's game slate with Kalshi/Polymarket tickers +

Description

Returns today's full NBA game slate with all market identifiers: Kalshi tickers (home/away), Polymarket condition IDs, and tip times. Hit this once per day to build your execution routing table.

Tier

ALPHA and above

Example Request

curl -H "Authorization: Bearer le_your_key_here" \
  https://api.lazyedge.net/v1/games/today

Example Response

[
  {
    "game_id": "401585901",
    "game_date": "2026-04-01",
    "home_team": "PHX", "away_team": "LAL",
    "tip_time": "2026-04-01T02:00:00Z",
    "kalshi_home_ticker": "KXNBAGAME-01APR26LALPHX-PHX",
    "kalshi_away_ticker": "KXNBAGAME-01APR26LALPHX-LAL",
    "kalshi_event_prefix": "KXNBAGAME-01APR26LALPHX",
    "polymarket_condition_id": "0x1234abcd...",
    "polymarket_slug": "lakers-vs-suns-april-1"
  }
]
GET /v1/injuries/live Injury impacts with ML-weighted player data +

Description

Returns current injury impacts ranked by usage share. Includes the ML-derived PMM (Player Missing Model) impact score that feeds the Skellam engine's probability adjustments.

Query Parameters

ParameterTypeDescription
teamstringFilter by 3-letter team abbreviation (optional)

Tier

ALPHA and above

Example Response

[
  {
    "player_name": "Kevin Durant",
    "team_abbr": "PHX",
    "status": "OUT",
    "usage_share": 0.294,
    "pmm_impact": -0.035,
    "signal": "BEARISH",
    "source": "sportradar"
  }
]
GET /v1/market/depth L2 order book depth snapshots +

Description

Returns L2 order book depth for Kalshi or Polymarket markets. Includes bid/ask depth at 5 levels and 24h volume. Feeds the Almgren-Chriss market impact model.

Query Parameters

ParameterTypeDescription
exchangestring"polymarket" (default) or "kalshi"

Tier

TERMINAL and above

GET /v1/signals/history Historical edge signals with pagination +

Description

Returns historical edge signals for backtesting and performance analysis. Paginated, filterable by team. Includes game outcome data when available.

Query Parameters

ParameterTypeDefault
teamstringFilter by team (optional)
limitint50 (max 500)
offsetint0

Tier

TERMINAL and above

GET /v1/account/usage API usage stats for your key +

Description

Returns usage statistics for the authenticated API key: calls today, tier, rate limits.

Tier

ALPHA and above

Example Response

{
  "key_prefix": "le_abc1",
  "tier": "pro",
  "calls_today": 423,
  "rate_limit_per_min": 60,
  "created_at": "2026-03-15T12:00:00Z"
}

WebSocket — Real-Time Edge Stream

For sub-second edge delivery, connect via WebSocket. The Megaphone pattern broadcasts new edges to all connected clients every 2 seconds. Requires Alpha ($99) tier or above. Recon Node users should use REST polling instead.

Connection

wss://api.lazyedge.net/v1/ws/edges

Authentication

After connecting, send an auth message within 10 seconds:

{"type": "AUTH", "key": "le_your_key_here"}

Messages

After authentication, you'll receive EDGE_UPDATE messages containing arrays of edge signals in the same format as /v1/edges/live:

{
  "type": "EDGE_UPDATE",
  "edges": [ ... ],
  "count": 3,
  "timestamp": "2026-04-01T23:45:10Z"
}

Keep-Alive

Send "ping" text messages to keep the connection alive. The server responds with "pong".

Python Example

import asyncio, websockets, json

async def stream_edges():
    async with websockets.connect("wss://api.lazyedge.net/v1/ws/edges") as ws:
        await ws.send(json.dumps({"type": "AUTH", "key": "le_your_key_here"}))

        async for message in ws:
            if message == "pong":
                continue
            data = json.loads(message)
            if data["type"] == "EDGE_UPDATE":
                for edge in data["edges"]:
                    if edge.get("trade_signal") == "BUY":
                        print(f"BUY {edge['target_kalshi_ticker']} @ {edge['kalshi_best_ask']}")

asyncio.run(stream_edges())

Frequently Asked Questions

What is the Skellam engine and how does our_prob get computed? +

The Dynamic Skellam Engine models NBA games as two competing Poisson processes (one per team's scoring rate). Instead of additive heuristics, it calculates P(Home Wins) from the physics of the game:

  1. Layer 1 — Dynamic Intensities: Per-team scoring rates (λ) derived from Vegas O/U totals, adjusted for pace, lineup, and fatigue
  2. Layer 2 — Hawkes Volatility: Self-exciting point process inflates/dampens λ based on unanswered scoring runs (momentum)
  3. Layer 3 — Skellam CDF: Given remaining time and adjusted λs, computes the exact probability of home team winning
  4. Layer 4 — Swarm Blending: Behavioral edge from LLM agent reaction surfaces (panic pricing during Flash Crashes)

The result is a first-principles probability recalculated on every play-by-play event, typically within 100ms.

What does hawkes_flag tell me that edge_score doesn't? +

edge_score tells you the size of your alpha. hawkes_flag tells you whether that alpha is expanding or contracting.

A +4.2% edge with SURGE_HOME means the home team is on an unanswered run AND the edge is still growing. The market hasn't caught up yet. This is the optimal entry window.

The same +4.2% edge with FADING means the run just ended and the market is about to correct. If you buy now, the line moves against you before your order fills.

Advanced bot logic: if hawkes_flag == "SURGE_HOME" and edge_velocity > 0: execute()

Why do I need kalshi_best_ask instead of just kalshi_implied? +

kalshi_implied is the mid-price: (bid + ask) / 2. It represents the market's consensus probability. But you can't trade at the mid.

To buy, you cross the spread and pay the ask. To sell, you hit the bid. The difference is your spread cost.

Example: Bid 0.63, Ask 0.67, Mid 0.65. Your our_prob is 0.72.

  • Calculated on mid: edge = 0.72 - 0.65 = +7%
  • Realized on ask: edge = 0.72 - 0.67 = +5%

Bots that size positions on mid-price edges will over-leverage by 40% in this example. Use kalshi_best_ask for buy-side sizing and kalshi_best_bid for sell-side sizing.

How do I use computed_at_ms for latency detection? +

In sub-200ms sports trading, data rots instantly. computed_at_ms tells you exactly when the engine finalized the Skellam math.

age_ms = int(time.time() * 1000) - edge["computed_at_ms"]
if age_ms > 300:
    # Signal is 300ms+ old. Market makers have already moved.
    # ABORT the trade.
    return

if age_ms > 500:
    # Signal is half a second old. Definitely stale.
    # If you execute here, you are the liquidity, not the alpha.
    return

If your bot is consistently seeing age_ms > 500, your network path to our API is too slow. Consider colocating closer to our server (IONOS, US-East).

What's the difference between Recon ($49), Alpha ($99), and Terminal ($199)? +

Recon Node ($49/mo) is for manual traders who want to watch our data:

  • 100 API calls/day (check /v1/edges/live a few times per game)
  • Edge signals + trade signals + Kelly sizing
  • Live screener terminal access
  • No WebSocket, no execution routing keys, no top-of-book

Alpha ($99/mo) gives you everything you need for profitable automated trading:

  • 2,000 API calls/day (poll /v1/edges/live every 2 seconds for 8 hours of games)
  • Full God Tier payload with execution routing, top-of-book, momentum physics
  • WebSocket real-time stream (uncounted — no rate limit)
  • Latency guard (computed_at_ms) for staleness detection

Terminal ($199/mo) adds institutional-grade data feeds:

  • 10,000 API calls/day (multi-game parallel polling)
  • L2 order book depth (Almgren-Chriss market impact data)
  • Historical signal archive for backtesting
  • Higher burst rate (50 req/sec vs 10 req/sec)

Manual trader? Recon. Single-game bot? Alpha. Multi-game portfolio with impact sizing? Terminal.

What is your accuracy / hit rate? +

Our nightly accuracy report runs automatically after each game night. Season-to-date metrics as of the latest report:

  • Directional hit rate: ~94.5% (when we say BUY, the home team wins)
  • Brier score: Tracked per game-progress bucket (Pregame, Early, Mid, Late, Clutch) — our model is best-calibrated in Late/Clutch game states where momentum data is richest
  • Edge capture: Varies by market liquidity. Higher on Polymarket (thinner books = more mispricing) than Kalshi

Full accuracy reports are available on the terminal dashboard under Analytics.

Can I use this with OpenClaw / custom execution bots? +

Yes — that's the primary use case. The target_kalshi_ticker field is the exact string Kalshi's order API requires. A minimal OpenClaw integration:

edge = get_latest_edge(game_id)
if edge["trade_signal"] == "BUY" and edge["hawkes_flag"] == "SURGE_HOME":
    kalshi_client.create_order(
        ticker=edge["target_kalshi_ticker"],
        side="yes",
        type="limit",
        yes_price=int(edge["kalshi_best_ask"] * 100),  # Kalshi wants cents
        count=calculate_position_size(edge["kelly"], bankroll)
    )

No ticker mapping. No team-to-contract lookup tables. One variable assignment from signal to order.

How fresh is the data? What's your update latency? +

The system operates on multiple timing loops:

  • Play-by-play events: ESPN polls every 60 seconds. Each new event triggers the Skellam engine within ~100ms
  • Kalshi prices: WebSocket real-time + REST API polls every 60s (authoritative). Written to Redis with 120s TTL
  • WebSocket delivery: Edge updates broadcast to connected clients within 2 seconds of computation
  • REST API: Always returns the latest computed edge. Use computed_at_ms to verify freshness

End-to-end latency from a scoring play to your bot receiving the updated edge: ~60-120 seconds (dominated by ESPN's poll interval, not our compute).

Error Codes

StatusMeaningCommon Cause
400Bad RequestInvalid parameter or missing required field
401UnauthorizedMissing or invalid API key. Check your Bearer token
403ForbiddenEndpoint requires a higher tier (e.g., Terminal for /market/depth)
404Not FoundGame ID not found or no games today
429Too Many RequestsDaily rate limit or burst rate exceeded. Check X-RateLimit-Remaining header
503Service UnavailableDatabase or upstream service temporarily down. Retry in 5 seconds

Error Response Format

{
  "detail": "This endpoint requires pro tier or above (you have basic)"
}

Ready to Deploy?

Get your API key and start receiving institutional-grade edge signals with execution routing in minutes.

Get API Key View Pricing