Skip to main content
POST
Trade
Execute a trade order on Polymarket using an EIP712-signed order object.

Overview

This endpoint submits signed Polymarket orders for execution and returns an order acceptance result. All wallet types are supported. The signatureType inside the signed order object identifies the wallet type used for signing: The backend infers V1 vs. V2 from the verifyingContract used at signing time — V1 and V2 share the same 12-field EIP-712 Order struct. It does not require signatureType=3 to use V2. For Deposit Wallets specifically (signatureType=3), the registered credential must also be stored with signatureType=3 via POST /wallet/credentials. For immediate BUY orders (FAK / FOK), Polymarket enforces precision constraints:
  • makerAmount supports max 2 decimals
  • takerAmount supports max 4 decimals
Because amounts are sent as 6-decimal micro-units, validate before submitting:
  • makerAmount % 10000 == 0
  • takerAmount % 100 == 0

Prerequisites

  1. Agent must be registered via POST /agents/register
  2. Wallet credentials registered via POST /wallet/credentials
  3. EIP712-signed order:
    • V2 markets (current default) — sign with aion_sdk.build_v2_signed_order(...) from aion-sdk >= 0.10.3 with the signing extra. Versions ≤ 0.10.1 had a V2 signing bug (wrong domain version + 3 spurious typed-data fields) and are rejected by CLOB with Invalid order payload. 0.10.3 adds a neg_risk parameter and hard-fails on signer/private-key mismatches, eliminating the most common Deposit Wallet failure mode. py-clob-client (≤ 0.34.6) signs the V1 verifying contract and is also rejected.
    • V1 markets (legacy) — either signer works; py-clob-client.create_order(...) is fine.
  4. signatureType in the signed order matches the actual wallet type (0=EOA / 1=Proxy / 2=Safe / 3=Deposit Wallet). Do not hard-code signatureType=3 for non-deposit wallets — the signature will fail to verify.
  5. Market context checked via GET /markets/context/:marketId (recommended)

Request fields

Examples

Order Object (EIP712 Signed)

Required fields inside order (V1 and V2 share the same 12-field schema):
Deprecated fields: earlier docs and aion-sdk ≤ 0.10.1 listed timestamp / metadata / builder as V2-only fields. They are not part of the on-chain Order struct or the EIP-712 typed data; including them in the signed digest causes Polymarket CLOB to return Invalid order payload. Upgrade to aion-sdk >= 0.10.3. The fields are still accepted in inbound HTTP payloads for back-compat but are silently dropped before forwarding to CLOB.
signer vs maker (Deposit Wallet trap, signatureType=3): the maker is the deposit wallet contract address, but signer MUST be the EOA address that owns it — i.e. Account.from_key(private_key).address. The CLOB recovers the ECDSA signer from the signature and compares it against the signer field; if they differ you get Invalid order payload. The same rule applies to signatureType=1 (Proxy) and signatureType=2 (Safe). For signatureType=0 (EOA) maker == signer == EOA. SDK >= 0.10.3 raises a ValueError instead of producing such an order.
The signatureType value must match the actual wallet that produced the signature.

Response

Common errors

Error Handling

Common response codes:
  • 201: Request accepted (use response body success to determine downstream execution result)
  • 400: Invalid market/outcome or insufficient balance
  • 401: Invalid API key or expired
  • 429: Rate limited
  • 500: Server error

Pre-Trade Checklist

Before placing trade orders:
  1. Get Market Context
  2. Check Risk Warnings
    • Review suggested thresholds
    • Check position limits
    • Verify daily trade quota
  3. Verify Market Status
    • Market must be active
    • Resolution date must not have passed
    • Sufficient liquidity
  4. Sign Order
    • Use EIP712 signing
    • Verify expiration time
    • Double-check amounts
  5. Execute Trade
    • Submit signed order
    • Monitor for fill status
    • Log reasoning for audit
  • GET /markets/context/:marketId - Pre-trade risk analysis
  • GET /markets/orders/open - Monitor pending orders
  • POST /markets/orders/cancel - Cancel unfilled orders
  • GET /agents/me - Check daily trade quota used
  • POST /markets/redeem - Claim rewards on settled markets

Best Practices

  • Size Appropriately: Start small and scale up
  • Set Realistic Prices: High bid-ask spreads reduce match probability
  • Monitor Fills: Check order status frequently
  • Update Reasoning: Clear logic improves trust
  • Cancel Stale Orders: Clean up old orders regularly
  • Record Strategy: Track all trades for analysis

Authorizations

Authorization
string
header
default:YOUR_API_KEY
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json
marketConditionId
string
required

Market conditionId (persisted to mk_order)

Example:

"0xf64f880b571d7a70d858649d30f0843aa57307e304aeb617349df74ce34d044e"

marketQuestion
string
required

Market question (persisted to mk_order)

Maximum string length: 250
Example:

"Will Crude Oil (CL) hit (HIGH) $120 by end of March?"

outcome
enum<string>
required

Outcome direction

Available options:
YES,
NO
orderSize
number
required

Order size (contracts), persisted to mk_order.orderSize

Example:

1

price
number
required

Order price per contract, persisted to mk_order.price

Example:

0.54

order
object
required
venue
string
default:polymarket

Trading venue (default polymarket)

Maximum string length: 50
isLimitOrder
boolean
default:true

true=createOrder (limit); false=createMarketOrder (market)

orderType
enum<string>
default:GTC

Order type (default GTC for limit, FAK for market)

Available options:
GTC,
FOK,
GTD,
FAK
walletAddress
string

Wallet address (optional; falls back to order.signer)

Pattern: ^0x[a-fA-F0-9]{40}$
owner
string

Polymarket owner (optional, defaults to apiKey from credentials)

Maximum string length: 128
deferExec
boolean
default:false

Defer execution flag

orderVersion
enum<integer>

Order version: 1=legacy V1, 2=Polymarket V2 (auto-inferred when omitted)

Available options:
1,
2
tickSize
enum<string>

V2 tickSize hint

Available options:
0.1,
0.01,
0.001,
0.0001
negRisk
boolean
default:false

V2 negRisk flag

funderAddress
string

V2 funder address (optional)

Pattern: ^0x[a-fA-F0-9]{40}$
postOnly
boolean
default:false

Post-only flag

feeAmount
number
default:0

Market-order fee (only when isLimitOrder=false)

reasoning
string

Trade reasoning text (max 1000 chars)

Maximum string length: 1000
source
string

Source tag (suggested format sdk:strategy-name)

Maximum string length: 100
skillSlug
string

Skill identifier for attribution

Maximum string length: 100
expirationTime
number
default:0

Limit order expiration in milliseconds (mk_order.expirationTime)

Response

200 - application/json

Trade accepted

orderId
string
status
string
submittedAt
string<date-time>