Synpath
Resources

Migrate from Dome / pmxt

A method-by-method mapping for teams moving to Synpath.

Why teams move

  • Dome has been acquired by Polymarket. Every Dome API reaches end of life on 28 April 2026, and the SDKs with it.
  • pmxt is no longer maintained. Its last release and last commit were on 18 July 2026, and over a thousand issues and pull requests sit open on its tracker.
  • Synpath is actively maintained by an open-source community, under the MIT licence, with the same unified shape both projects promised: one client, one schema, one id, across Kalshi, Polymarket and Polymarket US.

Synpath runs in your process and talks to the venues directly. Market data needs no key at all; order entry uses the venue keys you already hold. There is no hosted proxy between you and the exchange to be sunset.

pip uninstall pmxt dome-api-sdk
pip install synpath

The three things that change

  1. One class, keyed by venue. pmxt.Polymarket() and dome.polymarket.markets become synpath.exchange("polymarket"), or synpath.Client(), which routes on the id.
  2. One id per market. Dome's token_id and condition_id, and pmxt's marketId plus outcomeId, become a single venue:native id. YES and NO are sides of the order, not separate ids. See Synpath IDs.
  3. One price. Every price is the YES price. There is no per-outcome price array to index into; market.yes.quote and market.no.quote are both on the market.

From pmxt

Client

pmxtSynpath
pmxt.Polymarket(pmxt_api_key="...")synpath.exchange("polymarket")
pmxt.Kalshi(...)synpath.exchange("kalshi")
pmxt.Router(...)synpath.Client(); every venue behind one object
PMXT_API_KEYNot needed for market data. Venue keys for trading.

Market data

pmxtSynpathNote
fetch_markets(query, limit, offset)fetch_markets(query, limit, cursor)Cursor paging; read page.next_cursor.
fetch_events(...)fetch_events(...)Markets nested on each event, as before.
fetch_market(market_id)fetch_market(market_id)The id carries the venue.
fetch_order_book(outcome_id)fetch_order_book(market_id, side="yes")One book per market; side selects the view.
fetch_trades(outcome_id)fetch_trades(market_id)Prices in YES terms.
fetch_ohlcv(outcome_id, timeframe)fetch_ohlcv(market_id, timeframe)Read price_source on each candle.
status="active"status="open"open, unopened, closed, settled.

Fields

pmxtSynpath
market.outcomes[0].pricemarket.yes.quote.last
market.outcomes[1].pricemarket.no.quote.last
outcome.outcomeIdGone. Pass side instead.
market.volume24hmarket.volume_24h
market.marketIdmarket.id

Trading

pmxtSynpath
create_order(outcome_id, side="buy", price, amount)create_order(OrderRequest(market_id, side="buy", price, amount))
Buying the NO outcomeside="sell"
cancel_order(order_id)cancel_order(order_id, market_id=...)
fetch_positions()fetch_positions()
fetch_balance()fetch_balance("polymarket")

Trading calls are async in Synpath. Market data stays synchronous.

Before (pmxt)
import pmxt

poly = pmxt.Polymarket(pmxt_api_key="pmxt_live_...")
markets = poly.fetch_markets(query="election", limit=3)
for m in markets:
    print(m.title, m.outcomes[0].price)
After (Synpath)
import synpath

poly = synpath.exchange("polymarket")
markets = poly.fetch_markets(query="election", limit=3)
for m in markets:
    print(m.title, m.yes.quote.last)

From Dome

Client

DomeSynpath
DomeClient(api_key="...")synpath.Client()
dome.polymarket.marketssynpath.exchange("polymarket")
dome.kalshi.marketssynpath.exchange("kalshi")

Market data

DomeSynpathNote
get_markets(status, limit, pagination_key)fetch_markets(status, limit, cursor)A page, not {markets: [...]}.
get_market_price(token_id)fetch_market(market_id).yes.quotebid, ask and last on one object.
get_orderbook(token_id)fetch_order_book(market_id, side)YES or NO view of one book.
get_candlesticks(condition_id, start_ts, end_ts)fetch_ohlcv(market_id, timeframe, since, until)Unix milliseconds.
get_trades(...)fetch_trades(market_id)
get_orders(user)fetch_open_orders()Your own orders, with your own key.
get_wallet_pnl(...)engine.pnl(...)Your own P&L through the engine; wallet analytics for arbitrary addresses have no equivalent.
matched marketsComing, as a hosted serviceCross-venue matching is not in the library.

Identifiers

DomeSynpath
token_id (a Polymarket outcome token)polymarket:<gamma id> plus side
condition_idpolymarket:<gamma id>
market_slug, event_slugSearch with query, or resolve once with fetch_markets
ticker (Kalshi)kalshi:<ticker>
Before (Dome)
from dome_api_sdk import DomeClient

dome = DomeClient(api_key="your-key")
price = dome.polymarket.markets.get_market_price(token_id="9825044544769936...")
print(price.price)
After (Synpath)
import synpath

market = synpath.Client().fetch_market("polymarket:2252244")
print(market.yes.quote.last)
Dome ids are Polymarket's own ids, so nothing is lost: a condition_id still resolves through fetch_markets_by_ids once you prefix the Gamma id with polymarket:, and a token_id maps to that market plus the side it represented.

What has no equivalent

  • Wallet analytics for other people's addresses (Dome). Synpath reports your own positions, fills and P&L.
  • A hosted API key. Neither project's key carries over; there is nothing to replace it with for market data.
  • pmxt's long-tail venues (Limitless, Myriad, Smarkets and others). Synpath covers Kalshi, Polymarket and Polymarket US today, with more on the roadmap.
  • Cross-venue matching. Coming as a hosted service; the library raises NotSupported for it today.

What you gain

  • Order entry on every venue, with stops, icebergs, brackets, TWAP, pegs and smart takers the venues do not hold.
  • Live streams for books, trades, orders and fills, with reconnect and resync built in.
  • A journaled execution engine that survives a crash without sending an order twice.
  • A REST and WebSocket server you can run yourself, with a typed OpenAPI schema for any other language.

Start with the Quickstart, then the REST API reference for every call.