API Endpoints ยท Under Development
PREC EDGE API
The planned API returns a joined cross-venue view: Polymarket event data, Kalshi event data, mapped markets, normalized orderbooks, venue raw fields, and opportunity calculations in one response. The goal is to let dashboards and research tools consume one stable interface instead of calling both venues directly on every page load.
Overview
The first endpoint is scoped to one mapped event pair. It is intentionally event-centered: callers ask for an event pair and receive both venue containers, the mapped markets inside that pair, and optional orderbook snapshots. This matches the internal pipeline where event reconciliation happens before market reconciliation.
The response keeps three layers separate. The venue layer contains Polymarket and Kalshi source fields. The mapping layer explains which event and market records are connected. The pricing layer contains orderbook snapshots and opportunity math. Keeping those layers separate makes the endpoint easier to debug when a title, settlement rule, or price changes.
Endpoint
GET /api/v1/cross-venue/events/{event_pair_id}/markets?include_orderbooks=true
Path
event_pair_id identifies the mapped Polymarket/Kalshi event pair in the
PREC EDGE database.
Query
include_orderbooks=true includes normalized orderbook snapshots for each
returned market pair.
Status
Under development. The static portal currently uses local exports; this endpoint is the planned runtime interface.
Response Example
{
"event_pair_id": "evt_pair_2026_world_cup_winner",
"status": "mapped",
"captured_at": "2026-07-08T09:45:00Z",
"polymarket": {
"event": {
"id": "pm_event_123",
"slug": "2026-fifa-world-cup-winner",
"title": "2026 FIFA World Cup Winner",
"category": "Sports",
"source": "gamma-api.polymarket.com"
}
},
"kalshi": {
"event": {
"ticker": "KXMENWORLDCUP-26",
"title": "2026 FIFA World Cup Winner",
"sub_title": "2026",
"category": "Sports",
"source": "external-api.kalshi.com/trade-api/v2"
}
},
"markets": [
{
"market_pair_id": "mkt_pair_france_winner",
"normalized": {
"event_title": "2026 FIFA World Cup Winner",
"outcome": "France",
"market_type": "winner",
"settlement_basis": "tournament winner"
},
"polymarket": {
"market_id": "pm_market_456",
"token_id": "1234567890",
"question": "Will France win the 2026 FIFA World Cup?",
"orderbook": {
"best_bid": 0.115,
"best_ask": 0.125,
"levels": [
{ "side": "bid", "price": 0.115, "size": 250 },
{ "side": "ask", "price": 0.125, "size": 180 }
]
}
},
"kalshi": {
"market_ticker": "KXMENWORLDCUP-26-FR",
"title": "Will France win the 2026 Men's World Cup?",
"orderbook": {
"yes_bid": 0.11,
"yes_ask": 0.13,
"no_bid": 0.87,
"no_ask": 0.89,
"levels": [
{ "side": "yes_bid", "price": 0.11, "size": 120 },
{ "side": "no_bid", "price": 0.87, "size": 80 }
]
}
},
"opportunity": {
"gross_roi": 0.0187,
"net_roi_estimate": 0.0142,
"max_size_estimate": 80,
"freshness_seconds": 4
}
}
]
}
JavaScript Example
async function fetchPrecEdgeEventMarkets(eventPairId) {
const url = new URL(`/api/v1/cross-venue/events/${eventPairId}/markets`, "https://api.jsprec.com");
url.searchParams.set("include_orderbooks", "true");
const response = await fetch(url, {
headers: { "Accept": "application/json" }
});
if (!response.ok) {
throw new Error(`PREC EDGE API request failed: ${response.status}`);
}
const payload = await response.json();
return payload.markets.map((market) => ({
marketPairId: market.market_pair_id,
outcome: market.normalized.outcome,
pmBestAsk: market.polymarket.orderbook.best_ask,
kalshiYesAsk: market.kalshi.orderbook.yes_ask,
grossRoi: market.opportunity.gross_roi
}));
}
Python Example
import requests
def fetch_prec_edge_event_markets(event_pair_id: str) -> list[dict]:
url = f"https://api.jsprec.com/api/v1/cross-venue/events/{event_pair_id}/markets"
params = {"include_orderbooks": "true"}
response = requests.get(url, params=params, timeout=20)
response.raise_for_status()
payload = response.json()
rows = []
for market in payload["markets"]:
rows.append({
"market_pair_id": market["market_pair_id"],
"outcome": market["normalized"]["outcome"],
"polymarket_best_ask": market["polymarket"]["orderbook"]["best_ask"],
"kalshi_yes_ask": market["kalshi"]["orderbook"]["yes_ask"],
"gross_roi": market["opportunity"]["gross_roi"],
})
return rows
Implementation Notes
The endpoint should be backed by cached normalized venue tables and short-lived orderbook snapshots. It should not call both venue APIs synchronously for every browser request. A background refresh job can update Polymarket CLOB books, Kalshi market books, and opportunity calculations, while the API returns the latest consistent snapshot.
The API should expose raw venue identifiers because developers need traceability: Polymarket event IDs, market IDs, token IDs, Kalshi event tickers, Kalshi market tickers, capture times, and source URLs. It should also expose normalized fields because the public UI should not need to know every venue-specific naming difference.