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
- Create an account (free)
- Subscribe to Recon ($49/mo), Alpha ($99/mo), or Terminal ($199/mo)
- 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
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:
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
game_idstringESPN game ID (primary key for cross-referencing)home_teamstringHome team 3-letter abbreviation (PHX, LAL, BOS...)away_teamstringAway team 3-letter abbreviationperiodintCurrent quarter (1-4, 5+ for OT). 0 = pregameclockstringGame clock ("4:22", "0:00"). Empty if pregamehome_scoreintHome team scoreaway_scoreintAway team scoreThe Alpha — Execution Routing
trade_signalstringBUY (edge ≥ +3%), SELL (edge ≤ -3%), or HOLDtarget_sidestring"YES" or "NO" — which side of the contract to buy. Empty on HOLDtarget_kalshi_tickerstringExact Kalshi contract ticker to execute on. Pass directly to Kalshi order APItarget_polymarket_idstringExact Polymarket condition ID to execute onThe Math — Signal Strength
our_probfloatLazy Edge computed win probability (0-1). Derived from Dynamic Skellam engine + 4 enrichment layersedge_scorefloatRaw alpha: our_prob minus market mid-price. Positive = underpriced, negative = overpricedkellyfloatFractional Kelly bet size (0-1). Pre-computed with quarter-Kelly bankroll fractionThe Market — Top of Book
kalshi_best_bidfloatBest bid price on Kalshi (0-1). What you'd receive if sellingkalshi_best_askfloatBest ask price on Kalshi (0-1). What you'd pay to buy. This is your execution costkalshi_impliedfloatMid-price: (bid + ask) / 2. The market's implied probabilityWhy 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
edge_velocityfloatTrailing edge change between consecutive signals. Positive = edge expanding, negative = edge shrinkinghawkes_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 runmomentum_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
computed_at_msintUNIX millisecond timestamp when the Skellam engine finalized this signal. Use for staleness detectiontimestampstringISO 8601 timestamp of the signalLatency 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 lineRouting Keys — Market Cross-Reference
kalshi_home_tickerstringKalshi home team contract ticker (e.g., KXNBAGAME-01APR26LALPHX-PHX)kalshi_away_tickerstringKalshi away team contract tickerkalshi_event_prefixstringKalshi event prefix (shared between home/away contracts)polymarket_condition_idstringPolymarket condition ID for this gamepolymarket_slugstringPolymarket URL slug for this gameREST Endpoints
All endpoints require Authorization: Bearer <key> header.
/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
min_edgefloatMinimum absolute edge score (default: 0). Set to 0.03 to only get actionable signalsTier
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"
}
]/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
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"
/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"
}
]/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
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"
}
]/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
exchangestring"polymarket" (default) or "kalshi"Tier
TERMINAL and above
/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
teamstringFilter by team (optional)limitint50 (max 500)offsetint0Tier
TERMINAL and above
/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
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:
- Layer 1 — Dynamic Intensities: Per-team scoring rates (λ) derived from Vegas O/U totals, adjusted for pace, lineup, and fatigue
- Layer 2 — Hawkes Volatility: Self-exciting point process inflates/dampens λ based on unanswered scoring runs (momentum)
- Layer 3 — Skellam CDF: Given remaining time and adjusted λs, computes the exact probability of home team winning
- 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.
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()
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.
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.
returnIf 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).
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.
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.
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.
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_msto 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
400Bad RequestInvalid parameter or missing required field401UnauthorizedMissing or invalid API key. Check your Bearer token403ForbiddenEndpoint requires a higher tier (e.g., Terminal for /market/depth)404Not FoundGame ID not found or no games today429Too Many RequestsDaily rate limit or burst rate exceeded. Check X-RateLimit-Remaining header503Service UnavailableDatabase or upstream service temporarily down. Retry in 5 secondsError 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.