SDKsClients
Python SDK
The predictefy package is the official synchronous Python 3.10+ REST client. It uses one
runtime dependency (httpx) and covers normalized venue data, history, most of the
client.router REST surface, discrepancy qualification, and Trader Intelligence. The router
currently omits fetch_event_matches; use REST or the TypeScript SDK for that operation. Catalog
and order-book reads cover all 16 served venues, including PredictStreet; Trader Intelligence is served
on a narrower native-venue set. pascal, xo, and pred are not data-only venues — each has
an execution lane, in its own state — and each one does carry Trader Intelligence: all three
serve wallet-attributed trades and appear in the scored-trade/smart-money feed, while holders,
leaderboards, and wallet profiles stay unsupported. Actual verbs remain capability-qualified by
venue.
Quickstart
Section titled “Quickstart”pip install predictefyfrom predictefy import Predictefy
client = Predictefy(api_key="pk_...")
markets = client.polymarket.fetch_markets({"limit": 5, "query": "fed"})clusters = client.fetch_clusters({"limit": 20})smart_money = client.fetch_smart_money({"venue": "hyperliquid", "limit": 20})Change the venue client without changing the normalized method shape:
# Books, the tape, and candles are outcome-keyed: resolve an outcomeId from that# venue's own catalog first. A venue-native ticker or symbol is not resolved for you.markets = client.kalshi.fetch_markets({"limit": 1, "status": "active"})outcome_id = markets[0]["outcomes"][0]["outcomeId"]
client.kalshi.fetch_order_book(outcome_id)client.kalshi.fetch_ohlcv({"outcomeId": outcome_id, "resolution": "1h", "limit": 500})client.router.fetch_markets({"query": "election", "status": "active"})
# exchange(id) is the dynamic form of the same verbs on any venue.hyperliquid = client.exchange("hyperliquid")hl_markets = hyperliquid.fetch_markets({"limit": 1, "status": "active"})hyperliquid.fetch_trades(hl_markets[0]["outcomes"][0]["outcomeId"])List methods return a PageList: an ordinary list with .page, .meta, and
.next_cursor. iterate_markets follows snapshot-safe cursors for you.
Trader Intelligence
Section titled “Trader Intelligence”Trader support is capability-qualified by venue:
trades = client.polymarket.fetch_trader_trades("market-id", {"limit": 50})holders = client.polymarket.fetch_holders("market-id", {"limit": 50})leaders = client.hyperliquid.fetch_leaderboard({"by": "score", "limit": 50})profile = client.hyperliquid.fetch_wallet_profile("0x...")An unsupported upstream capability returns NOT_SUPPORTED; the client does not
fabricate trader identity or venue data.
Sports odds screen
Section titled “Sports odds screen”Sports catalogue, screen, and comparison reads have been live and metered since 2026-09-29.
If a deployment switches the routes off,
calls raise NotFoundError with code ROUTE_NOT_FOUND and a dark call is not charged. The screen
has a second switch, so catalogue reads can work while the screen remains dark. Check the code:
SPORTS_FIXTURE_NOT_FOUND and SPORTS_BLOCK_NOT_FOUND describe missing data instead.
The SDK never retries a 404, fabricates an empty result, or caches availability.
from predictefy import NotFoundError
try: grid = client.fetch_sports_screen( competition="epl", market_type="match_result", limit=20, ) print(grid.meta["degraded"], grid.next_cursor) for row in grid: if row["market"] is not None: print(row["fixtureId"], row["market"]["selections"])except NotFoundError as exc: if exc.code != "ROUTE_NOT_FOUND": raise print("Sports is not enabled on this deployment yet; this call was not charged.")The other reads are fetch_sports_facets, fetch_sports_competitions, fetch_sports_teams,
fetch_sports_fixtures, fetch_sports_fixture, compare_fixture_prices, and
fetch_fixture_price_history. Filters are keyword-only; the three fixture-id methods take the
id as their first positional argument. Lists retain .meta; screen and fixtures also
retain .page and .next_cursor (None on the last page). Pass that cursor with the same
filters to read the next page. Facets and fixture detail return the full success, data,
meta envelope. For screen and fixture-list reads, window filters from_ and to accept an
aware datetime, a date, or an ISO string with seconds and an offset; the default window is
12 hours ago through 7 days ahead, capped at 31 days. Compare has no line filter, and facets
have no window filters.
This is a price comparison, not an arbitrage claim. avg, fair, edge, and hold are
Predictefy’s own calculations: fair is the no-vig average, and edge is fair / best minus one,
which may be negative. Catalog and stale cells never win best; unknown fees have net=None
and use gross with edgeOnGross. final means our keyed markets closed, not a settlement
claim. The Python CLI has no sports command.
Fixture price history
Section titled “Fixture price history”fetch_fixture_price_history is dark by default inside the sports family. Public access
requires both READS_ENABLE_SPORTS and READS_ENABLE_SPORTS_HISTORY. Disabled calls raise
NotFoundError with code ROUTE_NOT_FOUND and are not charged.
from datetime import date, datetime, timezone
history = client.fetch_fixture_price_history( "fixture-id", # an id from fetch_sports_screen rows or fetch_sports_fixtures market_type="match_result", interval="1h", from_=date(2026, 9, 22), to=datetime(2026, 9, 24, tzinfo=timezone.utc),)print(history["data"]["series"])print(history["meta"])The method returns the full SportsPriceHistoryResponse envelope: success, data
(FixturePriceHistory), and meta (FixturePriceHistoryMeta). meta retains the resolved
window, interval, and recorder health; meta.degradedReason is omitted when healthy.
from_ and to accept an aware datetime, a date, or an ISO string. The history window
defaults to the seven days before the resolved to, capped at 31 days. There is no pagination.
Stake sizing
Section titled “Stake sizing”Optional stake sizing on client.router.fetch_arbitrage is dark by default behind
READS_ENABLE_ARBITRAGE_STAKE. Pass stake in the parameter dictionary:
assessments = client.router.fetch_arbitrage({"stake": 100.5, "limit": 100})stake is a USD budget: finite, greater than zero, at most 1,000,000, and with at most two
decimal places. When stake is supplied, limit must be at most 100. Violating either rule
raises ValidationError before any request. The client sends stake as a two-decimal string
("100.50" above). Sizing adds no credits to the existing request weight.
The PyPI package installs a predictefy console script:
export PREDICTEFY_API_KEY=pk_...
predictefy markets polymarket --limit 10 --q fedpredictefy discrepancies --limit 10 --livepredictefy clusters --limit 20Add --json for raw JSON. The full verb list is markets <venue>, market <venue> <id>,
discrepancies, clusters, and account <resource> <venue> [account-id].
Public execution and client-side signing support is capability-qualified separately; do not infer execution support from data coverage.
Rotate a secret with client.webhooks.rotate(endpoint_id) to issue a new signing secret for an
existing webhook endpoint; see Rotating a secret.