Skip to main content
One x402 endpoint for cross-venue prediction-market arbitrage. Polymarket has its own public API. Limitless has its own. Neither can answer “where do these two markets disagree?” in a single call — that’s the JOIN Graph Advocate assembles.

What you get

Per-call payment in USDC on Base via x402. No subscription, no API key, no free tier.

Why cross-venue over single-venue

Polymarket’s Gamma API is public and free. Limitless’s REST search is public and free. A consuming agent could call both and diff in code — but every agent then re-implements the same matching:
  • Pull candidate markets from each venue by topic keyword
  • Normalize the yes-side price from each venue’s response shape (Polymarket uses JSON-encoded outcomePrices, Limitless uses a prices: [yes, no] array)
  • Pair candidates by closest-price-match (titles rarely overlap word-for-word)
  • Compute spread in basis points and emit arbitrage direction
Graph Advocate does it once. The cross-venue /spread endpoint is the defensible play: passthrough APIs return one venue at a time and can’t JOIN. As more prediction-market venues come online, the JOIN gets more valuable, not less.

Sample request

Response:
How to use it. spread_bps is the basis-point gap on the yes-side mid. arbitrage_direction collapses the signal into one of:
  • long-polymarket-short-limitless — Polymarket is more expensive; if the two markets resolve identically, sell Polymarket and buy Limitless.
  • long-limitless-short-polymarket — Limitless is more expensive; reverse.
  • tight — within ±200bps; no edge after fees.
semantic_match_score is a 0-1 Jaccard score on shared content words between the two market titles (after stopword removal). Pairs below threshold (0.10) are rejected outright. A higher score doesn’t guarantee same-event resolution — it only signals overlap by content words. Verify resolution dates + outcome definitions before sizing. The status field tells you which venues had candidates so you don’t waste a call interpreting an empty pairs[]:

Honest coverage note

Polymarket and Limitless cover mostly disjoint market sets today. Polymarket leans US politics, sports, current events, and long-horizon crypto price thresholds. Limitless leans short-horizon (5-15 min) up/down price markets and multi-outcome categorical markets. Practically, the topics where both venues have semantically-aligned binary markets are narrow — often just crypto majors (BTC, ETH, SOL) on similar time horizons. When the endpoint returns no pairs but shows nonzero candidates, that’s the signal: the topic exists on both venues but the actual markets aren’t comparable. That’s still useful intelligence (one less venue to check) — it just isn’t an arbitrage opportunity. Verify before sizing: even when a pair passes the semantic filter, time horizons can differ (e.g. Polymarket “will SOL be above $70 by June 15” vs Limitless “SOL up/down in 15 min” — both involve SOL but are different bets). Always check resolution date + outcome definitions before treating spread as arbitrage.

How it differs from /kalshi-polymarket/spread

Same JOIN-shaped value-add, different venue pair:
  • /predmarket/spread — Polymarket ↔ Limitless (Base-native CTF prediction market, public REST search, no auth required)
  • /kalshi-polymarket/spread — Polymarket ↔ Kalshi (US-regulated, public REST)
Topic coverage skews differently. Limitless leans crypto / AI / tech. Kalshi leans US politics / sports / economics. Polymarket overlaps everything. Pick the endpoint by the venue pair you actually want to arbitrage.

Routing for free first

If you want to inspect the routing for free, send a plain-English question to POST / (A2A JSON-RPC) and Graph Advocate will name the right predmarket/* endpoint and hand back the exact paid curl — without charging.

Source

limitless_intel.py — the cross-venue search + closest-price-match pairing logic and how it fetches from Polymarket’s Gamma API and Limitless’s REST search.