Overview
Most order APIs give you a different endpoint per order type, so adding a stop-loss to a working integration means writing a new client method, new error handling, and new state tracking. Bravado does not work that way. Every order goes through one endpoint,POST /v2/trade/order, and a type field selects the execution strategy. A market order and a multi-hour TWAP are the same call with different fields.
That design has a consequence worth understanding early: because the types behave very differently, the response you get back and the endpoint you later poll to find your order both change depending on the type you sent. Getting that wrong is the most common reason people think an order vanished.
This guide places a real order, then walks all eight types, then covers where each one ends up.
TL;DR
- One endpoint,
POST /v2/trade/order. Thetypefield picks the strategy. symbolis an outcome token, not a market. A binary market has two of them.- Prices are decimal probabilities:
"0.62"means 62 cents. Sending"62"is rejected. - Size in shares with
size, or spend a budget in dollars withquote_amount. - Three types return an
order_idand live onGET /v2/trade/orders/open. Five return arecord_idand live onGET /v2/trade/strategies. Poll the wrong one and your order looks missing. - Always send an
Idempotency-Key, and always readwarnings[]even on a200.
What you will do
- Verify your key has the right scope and your wallet has collateral
- Place a market buy and read the fill back
- Shape the same request into each of the eight order types
- Attach take-profit and stop-loss legs to an entry
- Find your order afterwards, whichever type you used
- Cancel correctly, including the case where cancel-all does not do what you expect
What you will need
Knowledge- Comfort making HTTP requests from curl, Python, or TypeScript
- No Polymarket background required, though how Polymarket works is useful context
- A Bravado API key from the Bravado Portal
- The
trade.executescope for placing orders, plustrade.cancelto cancel them - USDC collateral in your Bravado wallet
- An outcome token id to trade, covered below
Check your account first
Two calls save a lot of confused debugging later. Does this key have permission?trade.execute is in scopes. If onboarding_status is pending, your wallet is not fully provisioned and orders will fail regardless of collateral.
The rate_limit_per_min value is worth keeping: it is your polling budget later, and reading it beats hard-coding a guess.
Do you have money to spend?
pusd is what you can trade with immediately. usdc_e is bridged USDC.e sitting on Polygon that has not been deposited yet, so it does not count toward buying power.
Understand what you are trading
This trips up nearly everyone once. A Polymarket market is a question: “Will X happen?” Each possible outcome is a separate ERC-1155 token with its own id and its own price.symbol refers to the outcome token, not the market.
So a binary market gives you two symbols: one for YES, one for NO. Buying YES and selling NO are different orders on different symbols, not two sides of one instrument.
Prices are decimal probabilities between 0.001 and 0.999. A YES token at 0.62 costs 62 cents per share and implies the market thinks there is roughly a 62% chance. If it resolves true, each share pays $1.
Place your first order
Spend $10 at whatever the book offers:Sizing: shares or dollars
Two ways to express quantity, and mixing them up is a common early bug:size, because you are disposing of a specific number of shares you hold.
The eight order types
Same endpoint throughout. Only the distinguishing fields are shown.LIMIT: rest on the book at your price
LIMIT: rest on the book at your price
order_id.Constraint: most markets require at least 5 shares on a resting order. size: "1" is rejected by the venue, not by Bravado.MARKET: take liquidity now
MARKET: take liquidity now
order_id.Constraint: minimum spend of $1.Watch for: on a thin book, a large market order walks through several price levels and your average is worse than the price you saw. For anything substantial, see Execute a large position.TWAP: spread execution over a window
TWAP: spread execution over a window
record_id, not an order_id.duration_sec and interval_sec are seconds, and interval_sec has a minimum of 10. price_tolerance_pct is a percent from 0 to 100 that skips clips when price has moved too far, which is your protection against filling into a spike.ICEBERG: show a slice, hide the rest
ICEBERG: show a slice, hide the rest
clip_size at a time. Returns a record_id.Constraint: slices are post-only. For a buy, the price must be at or below the current best bid, or the slice is rejected with order crosses book. Iceberg cannot be used to fill aggressively; it waits to be hit.PEGGED: follow the touch price
PEGGED: follow the touch price
record_id.offset_ticks is in CLOB ticks where one tick is 0.1 cents, so 2 quotes two ticks off the touch. price_ceiling stops it chasing the market up past a level you are unwilling to pay.STOP_LOSS: sell if price falls
STOP_LOSS: sell if price falls
record_id. Before it triggers, this exists only on GET /v2/trade/strategies, because a sell below the market would fill instantly if it were resting on the book. Bravado holds it and places the order when the trigger hits, at which point it also appears on open orders with is_stop_loss: true.TAKE_PROFIT: sell if price rises
TAKE_PROFIT: sell if price rises
order_id, unlike the other exit types. A sell above the current price can rest on the book straight away, so it does, and it earns you the spread while it waits.TRAILING_STOP: follow the high-water mark
TRAILING_STOP: follow the high-water mark
record_id.Units matter here. trailing_offset is a decimal probability, so "0.05" trails by 5 cents. If you want a percentage, use trailing_offset_pct, which takes 0 to 100. Sending "5" to trailing_offset is rejected for falling outside the valid range.Attach exits at entry
Rather than placing an exit after your entry fills, attach both legs to the entry itself:Find your order afterwards
This is the part that generates the most confusion, so it is worth a table:PENDING has not been rejected. It has been accepted and is waiting for its entry conditions. Cancelling and re-placing on PENDING churns fees and stops the strategy ever working. See Track order and strategy state.Cancel correctly
Confirm the position
Wrapping up
One endpoint, eight strategies, and the field set changes with the type. The two things worth carrying forward are thatsymbol is an outcome and not a market, and that where your order lives afterwards depends on the type you sent.
Everything else is detail you can look up. Those two cause the bugs.
Frequently asked questions
Why was my price rejected?
Why was my price rejected?
0.001 and 0.999. Sending "62" instead of "0.62" puts you outside the range. The error message names the value it received and suggests the decimal you probably meant.My TWAP disappeared from open orders. Where did it go?
My TWAP disappeared from open orders. Where did it go?
GET /v2/trade/strategies, not open orders. Only LIMIT, MARKET, and TAKE_PROFIT appear in open orders.Why did my iceberg slice get rejected for crossing the book?
Why did my iceberg slice get rejected for crossing the book?
Do I need an Idempotency-Key on every order?
Do I need an Idempotency-Key on every order?
Can I place several orders in one request?
Can I place several orders in one request?
POST /v2/trade/order/batch submits several at once, and POST /v2/trade/orders/cancel-batch cancels a targeted set. Both still take an idempotency key.What happens to my order when the market resolves?
What happens to my order when the market resolves?
Resources
- Trade API reference, full field and response documentation
- Order endpoints, request shapes for every type
- Execute a large position, TWAP and Iceberg in depth
- Stop-loss and take-profit, exits and brackets in depth
- Track order and strategy state, where each order type lives
- Safe retries, idempotency keys
- Error reference, status codes and common messages