API ReferenceCross-Venue Intelligence
Live executable-arbitrage assessment of discrepancy clusters. Router only.
const url = 'https://data.predictefy.com/api/router/fetchArbitrage?contracts=100&executableOnly=false&limit=5&offset=0&snapshotTTL=60000';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://data.predictefy.com/api/router/fetchArbitrage?contracts=100&executableOnly=false&limit=5&offset=0&snapshotTTL=60000' \ --header 'Authorization: Bearer <token>'Prices a page of discrepancy clusters against LIVE order books at the requested
contracts size: buy YES on the cheap venue's real asks + buy NO on the dear venue's
real asks, for a locked $1/contract payout at resolution.
A row is labeled "arbitrage" ONLY when EVERY gate passes:
- Books — live non-synthetic asks on both legs.
- Market — open market status.
- Depth — full depth at the requested size.
- Fees — a VERIFIED per-venue fee model, walked per level, with settlement commissions charged at the worst-case winning leg.
- Resolution — the resolution-equivalence gate: an affirmative persisted verdict for the current rule-content hashes, plus threshold, stage and settlement-source vetoes.
- Edge — a positive net edge after all costs.
Every other row is served as "indicative price discrepancy" with machine-readable
reasons:
- Per leg — see
ArbitrageLeg.reasons;market_not_opencovers stale status, an inactive flag, or a passed close time. - Per pair — threshold, stage and source conflicts,
close_time_mismatch,resolution_equivalence_unverified,same_venue,*_leg_not_executable,no_positive_edge.
The fingerprint conflict vetoes AND the close-time bar are re-applied live at claim time.
The fresh published surface pages filtered assessment rows. If that surface is unavailable,
the computed fallback scans at most 10 candidate clusters and may emit multiple ordered
venue pairs per cluster. Fallback pagination advances before executable, venue, edge and sports
filters, so an empty data page can still carry page.hasMore and page.nextCursor.
Rows are ordered executable first, then by netEdge descending; at one contracts size that is the same order as roi descending.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Must be router for this cross-venue operation. Market anchors must use the canonical venue:marketId form; event anchors must use the canonical venue:eventId form.
Query Parameters
Section titled “Query Parameters”Position size to assess; depth and fees are judged AT this size.
USD budget for an optional whole-contract allocation from the recorded executable fills. One decimal number with at most 2 decimal places; repeated values, signs and exponents are rejected. Requires READS_ENABLE_ARBITRAGE_STAKE; while off, answers 400 VALIDATION_ERROR with "stake is not enabled". With stake, limit must be <= 100. Adds no credits to the existing request weight. Does not change the assessed contracts size or fetch deeper books.
True = serve ONLY rows that earned the "arbitrage" label.
Keep a row when either leg touches this case-insensitive venue id. Repeated and comma-separated values are accepted, trimmed, and de-duplicated. For cursor walks, put all ids in one comma-separated value because the cursor fingerprints only the first repeated occurrence.
Alias of venue; keeps a row when either leg touches any listed id. Repeated values work on the first page, but cursor walks must use one comma-separated value because only the first repeated occurrence is fingerprinted.
Minimum finite netEdge in dollars, inclusive. Rows with null or non-finite net edge do not match.
Keep at most this many best-ranked ordered venue pairs per base cluster after executable, venue, minEdge and sports filters.
Keep a row only when the markets of BOTH legs are keyed by the sports catalog to this canonical sport slug (as fetchSportsFacets serves it). A row whose legs are not both keyed, or whose keys disagree, never matches a sports filter. One exact value; a repeated key answers 400. Unknown valid values return an empty page. Requires the sports family (READS_ENABLE_SPORTS); while it is off, this parameter answers 400 VALIDATION_ERROR sports filters are not enabled.
Keep a row only when the markets of BOTH legs are keyed by the sports catalog to this competition id (as fetchSportsCompetitions serves it). A row whose legs are not both keyed, or whose keys disagree, never matches a sports filter. One exact value; a repeated key answers 400. Unknown valid values return an empty page. Requires the sports family (READS_ENABLE_SPORTS); while it is off, this parameter answers 400 VALIDATION_ERROR sports filters are not enabled.
Keep a row only when the markets of BOTH legs are keyed by the sports catalog to this market type (moneyline, match_result, spread, total, team_total, btts, halftime_result, first_to_score, exact_score, outright, advance, player_prop, other; the vocabulary can grow). A row whose legs are not both keyed, or whose keys disagree, never matches a sports filter. One exact value; a repeated key answers 400. Unknown valid values return an empty page. Requires the sports family (READS_ENABLE_SPORTS); while it is off, this parameter answers 400 VALIDATION_ERROR sports filters are not enabled.
Keep a row only when the markets of BOTH legs are keyed by the sports catalog to this period (full, regulation, 1h, 2h, q1 to q4, p1 to p3, map1 to map5). A row whose legs are not both keyed, or whose keys disagree, never matches a sports filter. One exact value; a repeated key answers 400. Unknown valid values return an empty page. Requires the sports family (READS_ENABLE_SPORTS); while it is off, this parameter answers 400 VALIDATION_ERROR sports filters are not enabled.
Published assessment rows requested per page. The computed fallback accepts the same value but scans at most 10 candidate clusters; one cluster can emit multiple pair rows.
Zero-based offset. An explicit offset wins over page; a valid cursor overrides both after they are validated. Offsets above the maximum are rejected; use cursor pagination for deep walks.
One-based page used to derive offset as (page - 1) * limit; the derived offset must be a safe integer. Explicit offset wins; a valid cursor overrides both.
Opaque page.nextCursor from a prior response. It overrides offset/page and records this route plus the first serialized value of each non-pagination filter (category, contracts, executableOnly, venue/venues, minEdge, pairsPerCluster, sport, competition, marketType, period, stake); changing a recorded value answers 400. Repeated values after the first are not fingerprinted, so encode multi-venue filters as one comma-separated value. Published cursors also record the exact surface sequence. A published cursor keeps paging that exact sequence (same rows, same order) for 60 seconds after a newer sequence replaces it; a caller-chosen longer snapshotTTL, or 0, cannot extend retention. After that it answers 400 Cursor has expired and the walk restarts from page 1. Snapshot/offset cursors are signed by the server; a tampered or foreign cursor is rejected as VALIDATION_ERROR.
Lifetime in milliseconds recorded when a cursor chain starts. 0 disables time expiry. A supplied cursor carries its original TTL, so a later snapshotTTL value is ignored.
Responses
Section titled “Responses”Live executable-arbitrage assessments (honestly labeled per row).
object
A discrepancy cluster's best cross-venue pair priced against LIVE books. label is "arbitrage" IFF executable — every gate passed at the requested size; otherwise "indicative price discrepancy" with the failing gates in reasons (hard rule 2: the claim is earned, never assumed).
object
Candidate similarity from matching, distinct from matchScore.
The assessed size; depth/fees judged AT this size.
object
One taker-BUY leg of the assessed pair. Pricing fields are null whenever the leg cannot honestly be priced AS THE CLAIMED TRADE (missing/synthetic/thin book, or no verified fee model) — reasons carries the machine-readable WHY.
object
Composite "{venue}:{marketId}".
Research note for unverified-fee venues (why no model exists).
VWAP of the full requested fill, $/contract.
Walked cost of the full requested fill, $.
VERIFIED taker fee for the fill, $ (0 for settlement-commission venues).
Which fee rate applied (general, sports, conservative-max, …).
Contracts available on the walked asks (≤ requested).
The outcome whose live book priced this leg; the outcome an order for this leg names. Served only when the sports family is enabled on the deployment.
The canonical sports selection this outcome pays on (home, away, draw, over, under, yes, no, team:<team_id>). Served on leg-paired rows, and on every leg the sports catalog maps when the sports family is enabled; omitted otherwise.
Contracts resting at the best usable ask of the same live book, summed across levels at that price; null when the book is unavailable, synthetic or has no usable ask. Read in the same pricing pass as the row asOf. Served only when the sports family is enabled on the deployment.
One taker-BUY leg of the assessed pair. Pricing fields are null whenever the leg cannot honestly be priced AS THE CLAIMED TRADE (missing/synthetic/thin book, or no verified fee model) — reasons carries the machine-readable WHY.
object
Composite "{venue}:{marketId}".
Research note for unverified-fee venues (why no model exists).
VWAP of the full requested fill, $/contract.
Walked cost of the full requested fill, $.
VERIFIED taker fee for the fill, $ (0 for settlement-commission venues).
Which fee rate applied (general, sports, conservative-max, …).
Contracts available on the walked asks (≤ requested).
The outcome whose live book priced this leg; the outcome an order for this leg names. Served only when the sports family is enabled on the deployment.
The canonical sports selection this outcome pays on (home, away, draw, over, under, yes, no, team:<team_id>). Served on leg-paired rows, and on every leg the sports catalog maps when the sports family is enabled; omitted otherwise.
Contracts resting at the best usable ask of the same live book, summed across levels at that price; null when the book is unavailable, synthetic or has no usable ask. Read in the same pricing pass as the row asOf. Served only when the sports family is enabled on the deployment.
Whether a high-confidence affirmative persisted verdict matches both legs' current resolution-rule content hashes.
Deterministic rules comparison score. Null when no current verdict exists. Verification still requires an equivalent high-confidence verdict; the score alone never permits execution. Hidden rows are excluded from the feed.
Each difference kind is deducted once; explanations of that kind are joined.
A listed score deduction. Confidence costs 5 points for medium and 10 for low. A date veto accounts for all 100 points as deadline_handling; that row is hidden.
object
The sports catalog key that the markets of BOTH legs share. fixtureId is null for a competition-level market such as an outright. Omitted when either leg is not keyed or the two keys disagree; such a row never matches a sports filter. Served only when the sports family is enabled on the deployment. Catalog identity is Predictefy data, not a venue statement and not a settlement claim.
object
Optional USD allocation projection, emitted only when stake is supplied. A null allocation carries the reason it cannot be priced; no deeper book is fetched.
object
Requested budget in USD.
Largest affordable whole-contract allocation within the recorded assessed fills. Small allocations can lose money because of per-order minimum fees; profitable states the result.
object
The allocation equals the assessed contracts size.
The budget exceeds the assessed total cost; recorded depth caps the allocation.
object
object
Composite "{venue}:{marketId}".
Canonical sports selection when present on the source leg.
Re-walked ask cost in USD before fees.
Verified taker fee in USD, including any per-order minimum.
object
Composite "{venue}:{marketId}".
Canonical sports selection when present on the source leg.
Re-walked ask cost in USD before fees.
Verified taker fee in USD, including any per-order minimum.
Worst-case winning-leg settlement commission in USD.
Both legs plus fees and worst-case settlement commission in USD.
Contracts times the locked USD 1 payout.
Payout minus totalCost in USD.
True only when payout exceeds totalCost.
(payout − totalCost) / totalCost, rounded down to 4 decimal places; null when totalCost is zero.
Requested budget minus totalCost in USD.
Cheap fingerprint conflict veto (compatible ≠ verified equivalent).
object
Worst-case settlement commission across legs (only one leg wins), $.
Legs + fees + settlement worst case, $; null when unknowable.
The locked payout: contracts × $1.
Payout − totalCost, $; null when unknowable.
Pair-level failing gates (empty when executable).
EARLIEST leg-book freshness; null when either live book is missing.
Live-book provenance and the source of this response. asOf/seq exist only on the published path; totalUnavailable explains a null page.total on fallback.
object
The requested position size used for every assessment.
object
Predictefy-live — served from the live WebSocket hub or live order book.
Published surface timestamp; omitted on computed fallback.
Published surface sequence; omitted on computed fallback.
Whether rows came from the fresh published surface or bounded on-demand computation.
Why page.total is null; present only when the fallback count is unavailable.
Requested USD budget; omitted without stake.
Present and true when the fills sidecar is unavailable.
Omitted when the fills sidecar read has not failed.
object
Total matching rows, or null when the total was NOT computed — never a fabricated 0. The data page is the product and the count is metadata, so routes may warm an exact total off-request or abandon a count that exceeds its short budget while the page is still served. null is always accompanied by meta.totalUnavailable, which says why; use hasMore / nextCursor to walk the result set.
Whether another page exists. Determined by fetching one row beyond the requested limit, so it stays correct even when total is null.
Opaque cursor for the next page. Omitted on the final page.
Compatibility alias of page.nextCursor; omitted on the final page.
Example
{ "data": [ { "legs": { "buyYes": { "side": "yes", "reasons": [ "unverified_fees" ] }, "buyNo": { "side": "yes", "reasons": [ "unverified_fees" ] } }, "resolutionEquivalence": "verified", "matchBand": "verified", "matchDifferences": [ { "kind": "event_identity" } ], "stake": { "reason": null, "allocation": { "legs": { "buyYes": { "side": "yes" }, "buyNo": { "side": "yes" } } } }, "resolution": { "reason": "" }, "label": "arbitrage" } ], "meta": { "live": true, "provenance": { "source": "predictefy-live" }, "source": "published", "degradedReason": "fills_sidecar_unavailable" }}VALIDATION_ERROR (incl. non-router exchange, contracts/limit out of range, a sports filter while the sports family is off)
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}UNAUTHORIZED — platform lane (READS_ENABLE_AUTH)
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}INSUFFICIENT_CREDITS — endpoint-weighted credits
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}SCOPE_MISSING — API key lacks the route's required scope (RBAC v1); PLAN_REQUIRED — see credits.md
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}RATE_LIMITED — per-key rps limit
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}Unexpected internal error. Retryable; error.requestId identifies the failure.
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}ARBITRAGE_UNAVAILABLE (dark lane) / CATALOG_UNAVAILABLE (store outage)
object
object
Always present on errors; quote this id when reporting a failed request.
Present only when a venue error is attributed to a specific exchange.
Example
{ "success": false, "error": { "code": "VALIDATION_ERROR" }}