Skip to main content
GET
Arbitrage history
Paged feed of every arbitrage opportunity episode recorded by the always-on background scanner, newest first. Repeated detections of the same opportunity extend an existing episode instead of creating a duplicate. This is the endpoint the Dashboard arbitrage table reads from, and the only place min_net_cents is applied server-side across all recorded opportunities (not just the rows currently loaded in the UI). Returns a page envelope: {items, total, offset, limit, has_more}. Preview access (anonymous visitors, free accounts, unauthenticated API keys) returns the first opportunity unmasked and locks the rest — see Preview masking.

Request

Query parameters

integer
default:"50"
Max items per page (1–100).
integer
default:"0"
Zero-based page offset.
string
Filter by interval: 5m, 15m, 1h, 24h, or 1w. Omit for all.
string
Filter by crypto or sports.
number
default:"0"
Minimum net profit after fees, in cents. Applied server-side over the full history in the database, independent of the loaded page.
string
ISO-8601 timestamp. Keep episodes last seen at or after this.
string
ISO-8601 timestamp. Keep episodes first seen at or before this.

Response

Fields opinion_market_id and opinion are null for BTC interval scope and omitted. All monetary fields are null for locked (preview) rows.
array
List of opportunity episodes, newest first.
int
Total episodes matching the filters (before paging).
int
Zero-based offset used for this page.
int
Page size used for this request.
boolean
Whether another page exists after this one.

Episode

string
First timestamp this opportunity was observed.
string
Most recent timestamp this opportunity was observed.
object
The detected opportunity object.

Opportunity

string
Canonical event identifier (e.g. btc-updown-15m-1789273800).
string
Human-readable event title.
string
Outcome bucket key (e.g. btc_15m).
string
Short display label (e.g. BTC 15m).
string
Opportunity snapshot time.
string
Market type, currently binary.
string
Interval for the window when applicable.
string
Window settlement time.
string
Matching Kalshi event ticker, when available.
string
Matching Polymarket event slug, when available.
object
Kalshi leg snapshot: market_ticker, yes_ask, no_ask, volume, volume_24h, open_interest.
object
Polymarket leg snapshot: condition_id, yes_token_id, no_token_id, yes_ask, no_ask, volume, liquidity.
string
Venue to buy YES (kalshi or polymarket).
string
Venue to buy NO.
number
Gross edge in cents before fees.
number
Estimated taker fees in cents.
number
Net edge after fees in cents.
number
Return on capital for the paired legs.
number
Number of contracts executable at the shown edge.
number
Maximum profit in dollars at the executable size.
object
Execution leg: market, identifier, book_side.
object
Execution leg: market, identifier, book_side.
object
Present only when orderbook depth is captured for the episode.
boolean
true for masked preview rows. See below.

Examples

15-minute opportunities with min edge

Paginate through the feed

Use has_more to keep paging; total is the filtered count. Keep limit fixed across pages for stable offset math.

Preview masking

Without a paid entitlement the scanner’s history is masked server-side: the opportunity shown first is locked: false with full prices and net_cents, and every other row is locked: true with net_cents: null and both venue asks removed. A Trader subscription — see Authentication — unlocks the full feed.

Fee model

Arb legs are modeled as taker orders (buying at the ask):