Overview
Polymarket runs a rolling series of short-dated crypto markets. Every five minutes a new Bitcoin Up or Down market opens a window, and every fifteen minutes a longer one does the same. Each asks one question: at the end of this window, is BTC higher than it was at the start? On 7 August 2026 the way these markets settle changed. They no longer read a single price at the instant the window closes. They read a Chainlink time-weighted average price over the final seconds of the window. That change is the whole reason this guide exists, because it moves the decision point of the market from one instant to a measurable interval, and a bot written against the old behaviour is now systematically wrong at exactly the moment it matters. This guide covers what settles these markets, how to find and price them, what the fees do to your edge, and how to execute through the Bravado Trade API.Spin up a Trade API key
trade.read, trade.execute, and trade.cancel in the Bravado Portal. Every example below runs in dry mode without one, and needs one the moment you go live.TL;DR
- It is Chainlink, not Pyth. Crypto up/down markets resolve against Chainlink Data Streams TWAP feeds. Pyth is Polymarket’s resolution source for equities, ETFs, and commodities, not for BTC.
- 5-minute markets use a 30-second TWAP lookback. 15-minute markets use 60 seconds. Read the window from the market’s
cryptoMarketConfigrather than hardcoding it. - Market slugs are deterministic.
btc-updown-5m-<unix window start>. You never need to search for the next market, you can compute it. - Taker fees dominate the edge. At 50 cents a taker pays 1.75 cents per share. You need roughly 1.75 points of probability edge just to break even. Rest as a maker whenever you can.
- Bravado is the execution layer, Polymarket is the data layer. There is no order book endpoint on Bravado, and you do not want one in the hot loop.
- Advanced order types mostly do not apply here.
PEGGEDis the one worth testing.TWAP,ICEBERG, and the stop variants are built for hours, not for a 300-second window. - Location is a first-class design decision. Polymarket’s primary servers are in
eu-west-2.
What you will do
- Resolve the current and next BTC window without searching
- Read the TWAP configuration off the market instead of assuming it
- Stream Chainlink TWAP prices from Polymarket RTDS
- Compute a fair probability and compare it to a live book
- Size an order against the fee, not against your conviction
- Execute through Bravado with retry-safe keys
- Decide where to run the process
What you will need
Knowledge- Python 3.11 or later, comfort with REST and WebSockets
- A directional view on BTC over a 5 to 15 minute horizon. This guide gives you the harness, not the signal.
- A Bravado API key with
trade.read,trade.execute, andtrade.cancel, created in the Bravado Portal pip install requests websockets- pUSD collateral for live trading. Dry-run mode needs none.
- A machine with a clock disciplined by NTP. Window boundaries are absolute times and drift will cost you.
What settles these markets
Each crypto up/down market carries its rules in its own description. This is the current text on a BTC 5-minute market, verbatim:This market will resolve to “Up” if the time-weighted average price (TWAP) of Bitcoin, generated by Chainlink, of the time range specified in the title is greater than or equal to the price at the beginning of that range. Otherwise, it will resolve to “Down”.The resolution source is a Chainlink Data Streams feed, published on the market as a URL:
It is Chainlink, not Pyth
Worth stating plainly because the assumption is common. Polymarket uses two price oracles for different asset classes:Read the window, do not hardcode it
Every crypto up/down market exposes its settlement configuration as a structured field. Read it:twapLookbackSeconds is the number your bot cares about. It is 30 on 5-minute markets and 60 on 15-minute markets today, and it is the kind of parameter that moved once already this year. A bot that reads it survives the next change. A bot that hardcodes 30 silently mis-prices every market the day it moves.
The reference price is the part to verify yourself
The rule compares the TWAP at the end of the window against “the price at the beginning of that range”. Polymarket does not publish a separate reference-price endpoint, and the TWAP stream has no history or replay after a disconnect. The practical consequence: your bot has to snapshot the reference itself, at the window open, and keep it. Before you risk capital, run the harness in dry mode for a few hundred windows, log your snapshot and the settled outcome side by side, and confirm your reference reconstruction agrees with how the market actually resolved. This is not optional diligence. It is the one part of the model you cannot verify from documentation alone.Find the market without searching
The single most useful property of these series: the slug is a pure function of the window start time.What a real window looks like
Three consecutive BTC 5-minute books, sampled two seconds before the top of a window:bestBid and bestAsk fields on the Gamma market object are cached and were stale in every sample above. For anything you trade on, read https://clob.polymarket.com/book?token_id=....Venue parameters
The fee decides the strategy
Polymarket charges a taker fee on crypto markets, and it is not small:p is the share price. Makers pay nothing and receive a share of collected fees as a rebate. Bravado charges 10 bips of notional per side on top.
The fee peaks exactly where these markets live:
Architecture: Polymarket for data, Bravado for execution
Bravado has no order book, midpoint, or market discovery endpoint, and that is the correct split for this workload. Price data belongs on a WebSocket you own; execution belongs behind an API that handles signing, idempotency, and strategy supervision.Stream the TWAP
Resolve the window
twapLookbackSeconds.Price it
Execute through Bravado
POST /v2/trade/order with an idempotency key. Rest as a maker by default.Flatten or let it settle
Streaming the TWAP
RTDS is live and is the recommended path. No API key, no Chainlink credentials, no report decoding.full_accuracy_valueis the price. It is a signed E18 fixed-point integer. Thevaluefield beside it is a float provided for display, and it is not what settles the market. Divide the integer withDecimal.payload.timestampis the Chainlink observation time. The outertimestampis when Polymarket relayed it. In sampling, the gap between them ran about 1 to 2 seconds. Use the inner one for freshness checks, and budget for the relay lag in your model.PINGevery 5 seconds, as a text frame. RTDS uses an application-level heartbeat and will drop you without it.
When to use Chainlink Data Streams directly instead
When to use Chainlink Data Streams directly instead
wss://ws.dataengine.chain.link when you need the original signed report, want to verify DON signatures before acting, or want to remove Polymarket’s relay from your latency path. It costs you: Data Streams credentials, request signing, a server clock within five seconds of Chainlink’s, and report decoding via @chainlink/data-streams-sdk. Feed IDs come from the Data Streams catalog under the TWAP: 30s and TWAP: 60s tickers. For most bots the 1 to 2 seconds of relay lag is not the binding constraint, and RTDS is the better trade.Resolving the window
twapEnabled guard. It is the cheapest possible protection against pointing a TWAP-aware bot at a series that does not settle on TWAP.
Pricing the window
The fair probability ofUp is the probability that the closing TWAP finishes at or above your reference. Everything you know reduces to three quantities: how far the TWAP has already moved, how much time is left, and how volatile BTC is over that horizon.
- The lookback window flattens the endgame. With 30 seconds of lookback on a 5-minute market, roughly the final 10% of the window is already being averaged in. A move in the last 5 seconds moves the settlement value by about a sixth of its magnitude. Under the old snapshot rule that same move counted in full. Any model carried over from before 7 August 2026 systematically overestimates how much late price action matters.
- Your view is delayed. The relay adds 1 to 2 seconds and the feed prints about once a second. With 8 seconds left on the clock, you are pricing off information that is a meaningful fraction of the remaining window old.
Executing through Bravado
One endpoint, one idempotency key per intended order. If you have not created an API key yet, do it now in the Bravado Portal and granttrade.read, trade.execute, and trade.cancel, since the flatten step below needs all three.
Closing out the window
Two calls, and they are not interchangeable:PEGGED order left running past the close belongs to a market that no longer exists in any useful sense.
After settlement, winning shares are redeemable but not redeemed automatically. Call POST /v2/trade/positions/redeem once position.redeemable is true. Running 288 windows a day, unredeemed winners are the most common form of capital sitting idle in this strategy.
Confirming what you do not need
You were right to be suspicious of both.Advanced order types
The Data API
Not in the hot loop. It reads on-chain Polygon settlement records, so it is the wrong latency class for a decision you make every second. It is the right tool the moment the window closes. Run 288 windows a day and the only question that matters is whether the strategy is profitable after fees, which is precisely what a cashflow-model PnL over your own wallet tells you. PullGET /traders/{address}/pnl and GET /traders/{address}/trades on a daily cadence and check the answer against your own logs. See Build a PnL leaderboard.
Latency and location
Where the venue is
Polymarket publishes this, and it changes how you should think about hosting:What that actually costs you
Be honest about the mechanism, because latency matters here for a narrower reason than people assume. The TWAP feed prints about once a second and the relay adds 1 to 2 seconds. So 50 milliseconds of network time does not change what you know. What it changes is what you can do about it:- Queue position. A one cent tick means many participants want the same price level. On a book with a few hundred shares at the touch, arriving first at a level is most of the game.
- Cancel races. When the TWAP prints and the fair value moves, your resting order is now mispriced and someone else’s taker is on the way to hit it. The gap between your cancel and their take is measured in exactly the milliseconds this table describes.
- The final window. In the last 30 or 60 seconds the outcome is being averaged into existence. The book repriced from
0.54 / 0.55to0.99bid, no ask inside a single window in the sample above. Being 150 milliseconds late into that transition is the difference between a fill and a chase.
Why execute through Bravado
Two concrete reasons, plus one thing to check for yourself. You skip order construction entirely. A native CLOB order requires building and EIP-712 signing the order locally before it can be sent. Through Bravado it is one authenticated JSON POST. That removes local signing work from the path between your decision and the venue, on every order, in a loop that runs 288 times a day. Managed strategies run server-side. If you usePEGGED, its chase logic lives on Bravado’s infrastructure, adjacent to the venue, rather than in a loop on your box that has to observe a move, decide, and send. Your process restarting does not abandon it mid-window.
Then measure the hop. Routing through Bravado inserts a network hop between you and Polymarket. That is a clear win when Bravado sits closer to eu-west-2 than your process does, which is the common case for anyone not already co-located, and it is worth confirming against your own numbers before you scale size. Time a round trip through POST /v2/trade/order in dry conditions and compare it against your own path to the CLOB. Optimise the leg that is actually costing you.
Eligibility, before you write any of this
Polymarket restricts order placement by jurisdiction, and the restrictions apply to the API, not just the website.- Blocked entirely: Iran, Syria, Cuba, North Korea, and the Crimea, Donetsk, and Luhansk regions of Ukraine. No new orders, no closing existing positions.
- Close-only on frontend and API: a longer list that includes the United States, the United Kingdom, Canada, Australia, France, Germany, Belgium, Brazil, and Russia. Existing positions can be closed. New positions cannot be opened.
- Close-only on frontend, API unrestricted: Ireland, Japan, Malta, the Netherlands.
Going live
Run dry for 200 windows
DRY_RUN = True. Log your reference snapshot, your fair value, the book, and the settled outcome for every window. This is how you validate the reference-price reconstruction, which is the one thing documentation cannot confirm for you.Check the calibration, not the hit rate
Trade one series, maker only
Reconcile against the Data API
GET /traders/{address}/pnl. If they disagree, your fee accounting is wrong, and fee accounting is the whole margin here.Then add 5-minute windows, then add taking
Wrapping up
The TWAP change made these markets harder to manipulate and easier to model. Settlement is now an average over a defined interval published on a public feed you can subscribe to for free, rather than a single number read at an instant you had to race. What is left is an execution problem with an unusually explicit cost. You know the fee formula, you know the tick, you know the feed cadence, and you know where the venue is. The 1.75 cents per share at the money is the number the strategy lives or dies on, and almost everything in this guide is downstream of the decision to rest rather than cross.Frequently asked questions
Is Pyth involved anywhere in BTC up/down markets?
Is Pyth involved anywhere in BTC up/down markets?
equity_prices RTDS topic. If your market is a BTC window, Pyth is not in the path.Why is my market showing a book for a window that is a day away?
Why is my market showing a book for a window that is a day away?
startDate descending, you found tomorrow’s window rather than the current one. Compute the slug from the window start timestamp instead.Can I reproduce the settlement TWAP myself and front-run it?
Can I reproduce the settlement TWAP myself and front-run it?
My bot restarted mid-window. Can it recover the reference price?
My bot restarted mid-window. Can it recover the reference price?
Why is my 52%-accurate signal losing money?
Why is my 52%-accurate signal losing money?
Should I use a TWAP order to enter a TWAP-settled market?
Should I use a TWAP order to enter a TWAP-settled market?
TWAP order type spreads your execution over time to reduce market impact. The market’s TWAP settlement is how the outcome is computed. In a 300-second window with a minimum interval_sec of 10, a TWAP order gives you a slowly-accumulated position in a market that will have resolved before it finishes.Do I need to redeem winners manually?
Do I need to redeem winners manually?
position.redeemable and call POST /v2/trade/positions/redeem. At 288 windows a day this adds up quickly if you skip it.Does the 15-minute series behave the same as the 5-minute one?
Does the 15-minute series behave the same as the 5-minute one?
Resources
- Place an order, every order type in detail
- Build a trading bot, reconciliation and restart safety
- Safe retries, idempotency keys in depth
- Trade API reference, fields, fees, and position mechanics
- Polymarket coverage, venue constraints and supported products
- Bravado Portal, create and manage API keys and scopes
- Chainlink TWAP prices, the settlement feed
- Geographic restrictions, eligibility and server regions