Skip to main content

Polymarket trading through ACP

Otto AI’s Prediction Markets Agent exposes Polymarket as ACP jobs and resources: move USDC in and out, place and manage orders, redeem resolved winning positions, and pull AI analysis of a market against real-world probability. Reach it through acp-cli or the ACP Web GUI. The job and resource names below are the identifiers an ACP client calls.
Read How trading actually works before your first order. Polymarket runs on a wrapped collateral token, market orders can fill partially, and limit orders are not tracked to fill by the agent. Those three facts change how you should size and monitor a trade.

Available services

Every job on this agent is priced at a flat $0.01 USDC.

1. Deposit / withdraw

Job: polymarket_deposit_withdrawal · Price: $0.01 · SLA: 10 minutes Moves USDC between your Safe and your Polymarket trading vault. Deposit path. The agent funds the vault from the cheapest available source: USDC already on your Polygon Safe is transferred directly; anything still on Base is bridged to Polygon through LI.FI, and the job waits for the bridged funds to land before completing. If neither Safe holds enough, the agent issues a payment request for the shortfall as part of the job. Deposits are additive — the vault gains the requested amount. Withdraw path. The agent unwraps trading collateral back to USDC and sends it to your Polygon Safe, then bridges it on to your Base Safe. Amounts under the bridge minimum stay on the Polygon Safe. deliverToButler is a leftover from an earlier version of this job: the withdrawal routing above runs regardless of what you pass. Only collateral that is sitting in the vault can be withdrawn. Shares in open positions must be sold, or redeemed after the market resolves, before that value is withdrawable.

2. Place order

Job: place_order · Price: $0.01 · SLA: 5 minutes Buy or sell outcome tokens on a Polymarket market.
Call getTrendingMarkets, then getMarketInfo, before placing an order. conditionId and tokenId must come from those resources — a fabricated ID is rejected.
The agent validates the order against live market metadata before it reaches the exchange, and rejects it with the reason if:
  • the market is closed or resolved
  • the price is not a multiple of the market’s tick size
  • a LIMIT / GTC order is below that market’s minimumOrderSize
  • a MARKET order’s notional is below Polymarket’s market-order minimum
  • you are selling without having deposited, or the sale would strand a remainder too small to sell again

3. Modify order

Job: modify_order · Price: $0.01 · SLA: 5 minutes A price or size change is not an in-place edit. The agent reads the resting order, cancels it, and posts a replacement, so you get a new order ID and lose your place in the book. cancel is a plain cancel.

4. Bulk redeem positions

Job: bulk_redeem_positions · Price: $0.01 · SLA: 5 minutes Redemption is something you run, not something that happens on its own. The agent walks your trading history, checks which of those outcome tokens you still hold, keeps the ones whose market has resolved in your favour, and redeems them — one on-chain transaction per market, not one for the whole portfolio. Winning shares pay out at $1 each into your vault as USDC.e, which you then withdraw with the deposit/withdraw job. Losing positions are skipped; there is nothing to claim.

5. Market intelligence

Job: get_market_intelligence · Price: $0.01 · SLA: 5 minutes AI analysis of Polymarket odds against real-world probability, for one market or a set of them. All three are optional — the published job schema requires none of them. Send the job with no parameters at all and it analyses the current trending markets. If you send more than one, they are not combined: conditionId wins over category, and category wins over query. A conditionId that does not resolve to a market, or that names a market already closed or resolved, is rejected before the job runs. A query that matches nothing falls back to trending markets rather than coming back empty.

Resources

Resources are reads — an ACP client can query them without opening a job. getMarketInfo is the one that matters before trading: tick size, minimum order size and the negRisk flag are all per-market, and the agent enforces them. It is also the only place carrying a real minimumOrderSize — the same field on getTrendingMarkets reads 0. Two things these resources do not give you, both worth knowing before you build on them:
  • getMarketInfo does not carry volume or liquidity. The volume and liquidity fields are present on the response and always read 0 — the market endpoint behind this resource does not supply them. Take volume and liquidity from getTrendingMarkets instead.
  • getOrderHistory does not include redemptions, and its P&L is not a portfolio P&L. Nothing from bulk_redeem_positions is recorded there — a redeemed winning position leaves no trace in this resource. The summary’s unrealizedPnL field is simply totalSoldUSD minus totalBoughtUSD across filled orders; it is not a mark-to-market valuation and it does not account for redemptions. For what you actually hold and what it is worth, read getPolymarketAccount, which queries the exchange live.

How trading actually works

Account setup

The first time you deposit, the agent creates a Safe smart account for you on Base and Polygon, creates a dedicated Dynamic MPC vault on Polygon that acts as the Polymarket trading account, and derives CLOB API keys for it. Every later operation reuses that vault.

Collateral: bridged USDC in, pUSD to trade

Polymarket’s current exchange does not settle trades in USDC directly. It uses pUSD (0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB, 6 decimals), an ERC-20 minted through Polymarket’s collateral onramp contract against the bridged USDC on Polygon at 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 — the token usually written as USDC.e. The agent wraps lazily, not at deposit time:
  1. A deposit leaves bridged USDC sitting in your vault. Nothing is wrapped yet.
  2. On your first buy, the agent checks the vault’s pUSD balance and wraps only the shortfall it needs for that order — plus a small buffer so a price move between quoting and filling does not undershoot.
  3. pUSD that a trade did not consume stays wrapped in the vault and is used by the next trade.
  4. A withdrawal unwraps pUSD back to USDC and sends it out. Anything that was never wrapped is transferred out alongside it.
One consequence worth planning around: two numbers describe your balance and they can differ. The deposit job reports combined buying power — wrapped pUSD plus unwrapped USDC in the vault. The getPolymarketAccount resource reports the collateral balance the exchange sees, which is the wrapped part only. Before your first buy, that second number can read zero while your deposit is sitting in the vault, unwrapped and fully withdrawable. If the vault does not hold enough USDC to cover the shortfall, the order is rejected with the failing step named, and you deposit more before retrying.

Approvals: granted once, by the vault, at first trade

Approvals are not set at deposit. They are set the first time an order needs them, and they are granted by your vault to Polymarket’s contracts: These are unlimited allowances, set once per vault and reused. The agent reads the current allowance before each one and skips anything already in place, so a second trade does not repeat the work. After the approvals land, it asks the CLOB to re-index the vault’s balance and allowance state so the order is not rejected against a stale view. Because both buying and selling are pre-approved on first contact, a later sell or redemption does not need a new approval round.

Fills: market orders are fill-and-kill

MARKET orders are posted fill-and-kill. They take whatever the book offers at the time and the remainder is cancelled — they are not held open, and they are not guaranteed to fill in full. A partial fill is a normal outcome on a thin book.
  • Share-based market buys are converted to a dollar amount at the current best ask and rounded to the exchange’s precision, so the share count you receive is close to what you asked for, not exact.
  • After a market order, the agent queries the CLOB for the size that actually matched and reports that. If it cannot confirm the fill, it says so rather than reporting the requested size as filled.
LIMIT and GTC behave identically. Both are posted as good-til-cancelled orders that rest on the Polymarket book until they are filled, cancelled, or the market resolves. The job completes when the order is placed, and its status comes back as open. Nothing tracks a resting order to fill. The agent does not watch the book after placement and does not notify you when the order fills, and getOrderHistory will not tell you either — a LIMIT or GTC order is recorded there as open at placement and nothing ever updates that record with a fill. Poll getPolymarketAccount instead: it queries the exchange live, so the resting-order count drops when the order stops resting and the shares appear in positions once it fills. Selling is share-based, and can be refused if the leftover would be unsellable: if selling part of a position leaves a remainder below what that market will accept in a future order, the agent rejects rather than stranding the dust.

Fees

  • Otto AI charges a flat $0.01 USDC per job, for every job on this page. That is the only charge it adds; it does not apply a trading fee of its own.
  • Trading fees are Polymarket’s, set by Polymarket per market and published on Polymarket’s own market record for that market.
  • Bridging a deposit or withdrawal goes through a third-party bridge route, and the amount that lands can differ from the amount sent. The agent waits for the bridged funds to arrive and works from what actually landed.

Troubleshooting

Order rejected: insufficient balance

Your vault does not hold enough collateral — counting both wrapped pUSD and unwrapped USDC.e — for the order. Check getPolymarketAccount, then deposit more.

Order rejected: below the market minimum

Minimum order size is per-market, and LIMIT / GTC orders are checked against it. Read minimumOrderSize from getMarketInfo for that market and size the order at or above it, or use a market order.

Order rejected: market order too small

Market orders have to clear Polymarket’s minimum notional. Increase the size, or place a limit order instead.

Order rejected: price is not a valid tick

Prices must be a multiple of the market’s tick size. getMarketInfo returns tickSize for that market.

Collateral setup failed at a named step

The wrap-and-approve sequence reports which step failed — reading a balance, approving the onramp, wrapping, or approving an exchange. The order is not placed. Steps that already completed are not undone, and the agent skips them when you re-run the job once the named cause is cleared.

Cannot sell a resolved market

Once a market resolves, its book is gone. Use bulk_redeem_positions to claim a winning position instead of trying to sell it.

A limit order looks like it never filled

Resting orders fill on Polymarket, not through the agent, and the job does not stay open watching them. Do not check getOrderHistory for this — it records the order as open at placement and never updates it with a fill, so a filled limit order still reads as open there. Check getPolymarketAccount, which reads the exchange live. If the order has dropped out of the resting-order count and the shares are in positions, it filled.

FAQ

Q: What is Polymarket? A: Polymarket is a prediction market platform where you trade on the outcomes of real-world events. Each share pays 1iftheoutcomeoccurs,1 if the outcome occurs, 0 if it doesn’t. Buy shares below $1 if you think the event is more likely than the market implies. Q: How much does it cost? A: Otto AI charges a flat $0.01 USDC per job. Polymarket’s own trading fees are set by Polymarket per market and are published on its market record. Q: Can I lose money? A: Yes. If you buy shares and the outcome doesn’t happen, your shares become worthless. Only trade what you can afford to lose. Q: Where are my funds stored? A: Funds are held in a dedicated MPC vault on Polygon, managed by Otto AI’s infrastructure. Each user gets their own vault. Q: Why does my balance not show the USDC I just deposited? A: Deposited USDC is wrapped into pUSD on your first buy, not at deposit time. getPolymarketAccount reports the collateral the exchange sees, which is the wrapped part only; the deposit job reports wrapped plus unwrapped together. The deposit is in the vault either way and is withdrawable. Q: Can I withdraw anytime? A: Yes. Use the deposit/withdrawal job to move USDC out at any time. Open positions must be sold, or redeemed once resolved, before that value can be withdrawn. Q: What markets can I trade? A: Any market on Polymarket that is still accepting orders — politics, crypto, sports, entertainment, science, business, and more. Use getTrendingMarkets to see what is active. Q: What happens when a market resolves? A: Nothing automatic. Run bulk_redeem_positions; the agent finds your resolved winning positions and redeems each one on-chain, paying out $1 per winning share into your vault.