Skip to main content
Grandfathered wallets only. Polymarket rejects orders from wallets with no prior Polymarket trading history - only wallets that have traded on Polymarket before (grandfathered) can place orders. Starting a Polymarket agent on any other wallet is blocked up front with a clear error, and an order from one fails with WALLET_NOT_GRANDFATHERED. There is no way to enroll a new wallet through Circuit.
Use the Polymarket integration to build agents that buy and sell shares in prediction markets. Common use cases include event-driven trading, portfolio hedging, and automated redemption of settled positions.

Market Order

Execute a buy or sell market order.
Request Parameters:
  • tokenId (string): Market token ID for the position
  • side (string): “BUY” or “SELL”
  • spendUsd (number, BUY only): The USD (pUSD) amount to spend - 20 buys $20 of shares
  • shares (number, SELL only): The number of outcome shares to sell
  • idempotencyKey (string, optional): Durable retry key for auto-mode market orders. SDKs generate one automatically; provide a stable key only when retrying the same logical order after a process restart.
  • expiresAt (string | null, optional): ISO 8601 timestamp. In manual mode, the suggestion expires at this time. If omitted, no time-based expiry is set (suggestions are auto-cleared at each run start).
Order amounts are unit-explicit - a BUY is sized in dollars, a SELL in shares (Polymarket’s market orders are specified by what you give: collateral on a BUY, shares on a SELL). Passing the wrong field for the side fails validation before anything executes. Auto-mode market orders are idempotent by idempotencyKey within the current agent run. Duplicate active or already-submitted attempts are rejected; only failures before any external side effect can retry under the same key. Response:
  • success (boolean): Whether the operation succeeded
  • data.orderInfo (object): Order information (on success)
    • orderId (string): Unique order identifier
    • side (string): “BUY” or “SELL”
    • size (string): Order size
    • priceUsd (string): Price per share in USD
    • totalPriceUsd (string): Total order value in USD
    • txHashes (string[]): Mined settlement transaction hashes (the order succeeds only once its settlement lands onchain)
  • error (string | null): Error message (on failure)
In manual mode, the same PolymarketMarketOrderResponse is returned and data is a suggestion envelope ({ suggested: true, suggestionId }) instead of order information. See Manual vs Auto Mode. Example:

Redeem Positions

Redeem settled positions and claim winnings. Pass the token IDs of the positions to redeem - fetch your positions first and filter for isRedeemable. Agents only redeem positions their own session holds; there is no “redeem everything in the wallet” mode.
Request Parameters (required):
  • tokenIds (string[], required, non-empty): Token IDs of the positions to redeem. Requesting a token the session doesn’t hold fails with a 404.
  • idempotencyKey (string, optional): Durable retry key for auto-mode redeem attempts. SDKs generate one per redeemPositions() / redeem_positions() call when omitted.
Use an explicit idempotencyKey only when retrying the same logical redeem after a process restart. Active attempts and attempts that already reached an onchain side effect return a conflict for the same key; only failures before any broadcast can retry under the same key. Response:
  • success (boolean): Whether the operation succeeded
  • data (array): Array of redemption results
    • success (boolean): Whether this redemption succeeded
    • position (object | null): Position details (on success)
      • question (string): Market question text
      • outcome (string): Outcome name (e.g., “Yes”, “No”)
      • marketValueUsd (string): Position value in USD
      • pnlUsd (string): Profit/loss in USD
      • pnlPercent (string): Profit/loss percentage
      • isRedeemable (boolean): Whether position can be redeemed
      • contractAddress (string): Token contract address
      • tokenId (string | null): Token ID
      • decimals (number): Token decimals
      • conditionId (string): Market condition ID
      • formattedShares (string): Human-readable share count
      • shares (string): Raw share count
      • averagePriceUsd (string): Average entry price
      • initialValue (string): Original position value
      • pnlRealizedUsd (string): Realized PnL in USD
      • pnlRealizedPercent (string): Realized PnL percentage
      • isNegativeRisk (boolean): Whether this is a negative risk market
      • imageUrl (string): Market image URL
      • endDate (string): Market end date
    • transactionHash (string | null): Transaction hash. null with success: false means the position was skipped (not settled yet) and no transaction was broadcast.
    • skippedReason (string, optional): Why the position was skipped without broadcasting (e.g. not settled yet). Present only when success is false.
  • error (string | null): Error message (on failure)
Skips are per-position: a request where some positions redeem and others are skipped succeeds with mixed per-token results. A request where no position can be redeemed (all skipped, or none held) fails with POSITIONS_NOT_REDEEMABLE - the error message lists every skip reason. It never reports success for a redeem that executed nothing. In manual mode the redeem is captured as a suggestion for the user to approve; data is then a suggestion envelope ({ suggested: true, suggestionId }) instead of the redemption array. See Manual vs Auto Mode. Example:

Reading positions

Polymarket positions at invocation start are in agent.allocation.positions, with each position enriched under polymarketMetadata (question, outcome, price, value, redeemability, PnL). Filter the allocation to Polymarket positions by the presence of polymarketMetadata.

Common Errors

Errors are returned from Polymarket’s API in the error field. Common errors include: Note: Additional error messages may be returned by Polymarket’s API. Check the error field in the response for specific details.

Search Events

Discover Polymarket events by name - market resolution step 1 of 2.
Request Parameters:
  • query (string): Specific names to search for - teams, people, tickers ("egypt", "australia egypt"). Never category words: “world cup” ranks generic futures above today’s match.
Response (data):
  • events (array): Top-ranked matching events, each with slug, title, and the markets search exposes (liquidity-sorted; same market shape as Event Markets)
  • moreEvents (array): Lower-ranked matches as { slug, title, startDate } refs - check here when the wanted event isn’t in events; a match is often outranked by unrelated popular markets. Enumerate a ref’s full catalog with eventMarkets(slug).
Search is fuzzy and never returns empty - verify a returned title actually names what you’re looking for before trading, and report “no matching market” rather than trading the closest miss.
Search results NEVER show an event’s full market catalog: totals/over-under, spreads, and props are missing even when they exist (and are often the event’s most liquid markets). Only eventMarkets is authoritative for which markets exist.

Event Markets

Enumerate one event’s COMPLETE market catalog by slug - market resolution step 2 of 2, and the only authority on which markets an event has. (Polymarket splits sports matches across a main event and a companion “more markets” event that search never returns; this merges them.)
Request Parameters:
  • slug (string): Event slug exactly as returned by searchEvents
Response (data):
  • slug, title (string): The event
  • markets (array): Every tradeable market, in descending-liquidity order:
    • question (string): e.g. “Australia vs. Egypt: O/U 0.5”
    • sportsMarketType (string | null): "moneyline" | "totals" | "spreads" | … (null for non-sports)
    • groupItemTitle (string | null): the side/option this market represents within the event, e.g. "Egypt"
    • line (number | null): spread/total line, e.g. 0.5
    • gameStartTime (string | null): "2026-07-03 18:00:00+00" (space-separated, not ISO T) - use it to pick “today’s” match
    • liquidityUsd, volume24hUsd (number)
    • outcomes (array): each outcome’s name (e.g. "Yes"/"Over"), priceUsd, and the tokenId orders take

Getting Token IDs

The tokenId identifies a specific outcome (e.g., “Yes” or “No”) in a Polymarket market - a ~77-digit decimal string you must resolve, never invent. Two sources:
  • From your holdings: agent.allocation.positions includes invocation-start Polymarket positions with token IDs in position.polymarketMetadata.tokenId.
  • From market resolution: searchEvents (discover) → eventMarkets (enumerate) → pick the market matching the intent → the outcome’s tokenId.
Interpretation rules:
  1. Trade only the most liquid market matching the intent - markets come back liquidity-sorted; skip thin books. For a generic sports bet that’s the match’s moneyline.
  2. Sports model: one match = one event; a soccer moneyline is one Yes/No market per side (groupItemTitle names the side - “bet on Egypt” = groupItemTitle: "Egypt", outcome "Yes"). Totals are one market per line with Over/Under outcomes - “over 0.5 goals” = the totals market with line: 0.5, outcome "Over".
  3. Never conclude a market doesn’t exist from search results - enumerate the event’s full catalog first.
If several events plausibly match, pick only when one candidate clearly wins on participant + date + liquidity; otherwise report the candidates instead of guessing.

Notes

  • Polymarket’s API accepts different decimal precision for buys and sells. This can result in dust positions if selling a position before expiry. Clean up dust with redeemPositions({ tokenIds }) after market expiry.
  • Negative risk markets: Some markets use an inverted pricing model. The SDK handles this transparently, but be aware that position values may display differently.
  • Invocation-start open positions are available in agent.allocation.positions (pUSD cash stays in balances).
  • Polymarket positions always include enriched metadata (question, outcome, PNL) on position.polymarketMetadata.
  • SDKs generate idempotencyKey automatically for marketOrder and redeemPositions; pass a stable key only when you need to resume the same logical action after a process restart.

See Also

  • Positions - Polymarket positions include enriched metadata on polymarketMetadata
  • Error Handling - Polymarket-specific error codes