> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aionmarket.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trade

> Submit a new market order or limit order for execution.

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:

| signatureType | Wallet Type                 | Notes                                                                                                                                     |
| ------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `0`           | EOA                         | Default for `py-clob-client` with a raw private key. Fully supported on V1 and V2 (sign V2 orders with `aion_sdk.build_v2_signed_order`). |
| `1`           | POLY\_PROXY                 | Polymarket proxy wallet                                                                                                                   |
| `2`           | GNOSIS\_SAFE                | Multi-sig wallet                                                                                                                          |
| `3`           | POLY\_1271 / Deposit Wallet | Polymarket deposit wallet (1271 contract)                                                                                                 |

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`](https://pypi.org/project/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

| Field               | Type    | Required | Description                                                             |
| ------------------- | ------- | -------- | ----------------------------------------------------------------------- |
| `venue`             | string  | No       | Defaults to `polymarket`                                                |
| `marketConditionId` | string  | Yes      | Condition identifier                                                    |
| `marketQuestion`    | string  | Yes      | Market question                                                         |
| `outcome`           | string  | Yes      | `YES` or `NO`                                                           |
| `orderSize`         | number  | Yes      | Requested contracts                                                     |
| `price`             | number  | Yes      | Price per contract                                                      |
| `isLimitOrder`      | boolean | No       | Limit or market mode                                                    |
| `orderType`         | string  | No       | `GTC`, `FOK`, `GTD`, `FAK` (default: `GTC` for limit, `FAK` for market) |
| `walletAddress`     | string  | No       | Wallet address                                                          |
| `orderVersion`      | integer | No       | `1`=legacy V1, `2`=Polymarket V2; auto-inferred if omitted              |
| `order`             | object  | Yes      | Signed EIP712 order payload                                             |
| `reasoning`         | string  | No       | Trade explanation                                                       |
| `source`            | string  | No       | Strategy source tag                                                     |
| `skillSlug`         | string  | No       | Skill identifier for attribution                                        |
| `expirationTime`    | number  | No       | Limit order expiration (milliseconds)                                   |
| `tickSize`          | string  | No       | V2 tick size: `0.1`, `0.01`, `0.001`, `0.0001`                          |
| `negRisk`           | boolean | No       | V2 market context flag                                                  |
| `funderAddress`     | string  | No       | V2 funder address                                                       |
| `postOnly`          | boolean | No       | Post-only order flag                                                    |
| `deferExec`         | boolean | No       | Defer execution flag                                                    |
| `owner`             | string  | No       | Polymarket owner (default uses wallet credential apiKey)                |
| `feeAmount`         | number  | No       | Market order fee (`isLimitOrder=false` only)                            |

## Examples

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl -X POST https://www.aionmarket.com/bvapi/markets/trade \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "venue": "polymarket",
        "marketConditionId": "0xabc123...",
        "marketQuestion": "Will Bitcoin reach $100k by end of 2024?",
        "outcome": "YES",
        "orderSize": 10,
        "price": 0.68,
        "isLimitOrder": true,
        "walletAddress": "0x1111111111111111111111111111111111111111",
        "orderVersion": 2,
        "owner": "f4f247b7-4ac7-ff29-a152-04fda0a8755a",
        "orderType": "GTC",
        "deferExec": false,
        "postOnly": false,
        "order": {
          "maker": "0x1111111111111111111111111111111111111111",
          "signer": "0x1111111111111111111111111111111111111111",
          "taker": "0x0000000000000000000000000000000000000000",
          "tokenId": "0x123",
          "makerAmount": "6800000",
          "takerAmount": "10000000",
          "side": "BUY",
          "expiration": "1713604800",
          "nonce": "0",
          "feeRateBps": "0",
          "signature": "0x...",
          "salt": 1,
          "signatureType": 3
        },
        "feeAmount": 0,
        "reasoning": "Technical analysis shows bullish trend; RSI at 65",
        "source": "sdk:weather-alpha",
        "skillSlug": "polymarket-weather-trader",
        "expirationTime": 0
      }'
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    from aion_sdk import AionMarketClient

    client = AionMarketClient(api_key="YOUR_API_KEY", base_url="https://www.aionmarket.com/bvapi")

    signed_order = {
        "maker": "0xDEPOSIT_WALLET_CONTRACT",   # wallet contract on Polygon
        "signer": "0xEOA_ADDRESS",              # EOA owning the deposit wallet (matches private_key)
        "taker": "0x0000000000000000000000000000000000000000",
        "tokenId": "0xTOKEN_ID",
        "makerAmount": "6100000",
        "takerAmount": "10000000",
        "side": "BUY",
        "expiration": "1713604800",
        "nonce": "0",
        "feeRateBps": "0",
        "signature": "0x...",
        "salt": 1,
        "signatureType": 3,                     # Deposit Wallet
    }

    result = client.trade({
        "venue": "polymarket",
        "marketConditionId": "0xabc123...",
        "marketQuestion": "Will Bitcoin reach $100k by end of 2024?",
        "outcome": "YES",
        "orderSize": 10,
        "price": 0.68,
        "isLimitOrder": True,
        "orderType": "GTC",
        "walletAddress": "0xYOUR_WALLET",
        "order": signed_order,
        "reasoning": "Positive edge after context check",
        "source": "sdk:strategy-alpha",
    })
    print(result)
    ```
  </Tab>
</Tabs>

## Order Object (EIP712 Signed)

Required fields inside `order` (V1 and V2 share the same 12-field schema):

| Field         | Type    | Required | Description                                                  |
| ------------- | ------- | -------- | ------------------------------------------------------------ |
| maker         | string  | Yes      | Maker wallet address                                         |
| signer        | string  | Yes      | Signing wallet address                                       |
| taker         | string  | Yes      | Taker address, usually zero address for open orders          |
| tokenId       | string  | Yes      | Polymarket CLOB token ID                                     |
| makerAmount   | string  | Yes      | Maker amount in 6-decimal integer precision                  |
| takerAmount   | string  | Yes      | Taker amount in 6-decimal integer precision                  |
| side          | string  | Yes      | `BUY` or `SELL`                                              |
| expiration    | string  | Yes      | Expiration timestamp in seconds                              |
| nonce         | string  | Yes      | Unique nonce (use `"0"` if unused)                           |
| feeRateBps    | string  | Yes      | Fee rate in basis points (use `"0"` for default)             |
| signature     | string  | Yes      | EIP712 signature                                             |
| salt          | number  | Yes      | Random salt                                                  |
| signatureType | integer | Yes      | `0`=EOA, `1`=PolymarketProxy, `2`=GnosisSafe, `3`=POLY\_1271 |

> **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

```json theme={null}
{
  "success": true,
  "orderId": "0x456def...",
  "status": "live",
  "orderVersion": 2,
  "collateralSymbol": "pUSD",
  "walletAddress": "0x1111111111111111111111111111111111111111",
  "signatureType": 3,
  "aiAgentId": "1",
  "userId": "42",
  "syncedToMkOrder": true,
  "syncedToStrategyLog": true
}
```

## Common errors

| Code  | Meaning                                                      |
| ----- | ------------------------------------------------------------ |
| `400` | Invalid payload, bad market/outcome, or invalid order object |
| `401` | Invalid API key                                              |
| `429` | Rate limited                                                 |
| `500` | Server-side failure                                          |

## 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**

   ```bash theme={null}
   GET /markets/context/:marketId?user=YOUR_WALLET
   ```

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

## Related Endpoints

* `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


## OpenAPI

````yaml POST /markets/trade
openapi: 3.1.0
info:
  title: Aion AI Agent API
  description: >-
    API for agent registration, wallet onboarding, market discovery, order
    management, and execution on Aion.
  version: 1.0.0
  contact:
    name: Aion Support
    email: info@aionmarket.com
    url: https://docs.aionmarket.com
servers:
  - url: https://www.aionmarket.com/bvapi
    description: Aion API
security:
  - bearerAuth: []
tags:
  - name: Agent Management
  - name: Market Operations
  - name: Order Management
  - name: Trading
  - name: Kalshi
  - name: Skills
  - name: Wallet Management
  - name: Trades & Leaderboard
  - name: Utilities
  - name: Settings
  - name: Positions & Portfolio
  - name: Fee Charging
paths:
  /markets/trade:
    post:
      tags:
        - Trading
      summary: Trade
      description: Submit a new market order or limit order for execution.
      operationId: placeTrade
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TradeRequest'
      responses:
        '200':
          description: Trade accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TradeResult'
components:
  schemas:
    TradeRequest:
      type: object
      required:
        - marketConditionId
        - marketQuestion
        - outcome
        - orderSize
        - price
        - order
      properties:
        venue:
          type: string
          description: Trading venue (default polymarket)
          default: polymarket
          maxLength: 50
        marketConditionId:
          type: string
          description: Market conditionId (persisted to mk_order)
          example: '0xf64f880b571d7a70d858649d30f0843aa57307e304aeb617349df74ce34d044e'
        marketQuestion:
          type: string
          description: Market question (persisted to mk_order)
          example: Will Crude Oil (CL) hit (HIGH) $120 by end of March?
          maxLength: 250
        outcome:
          type: string
          description: Outcome direction
          enum:
            - 'YES'
            - 'NO'
        orderSize:
          type: number
          description: Order size (contracts), persisted to mk_order.orderSize
          example: 1
        price:
          type: number
          description: Order price per contract, persisted to mk_order.price
          example: 0.54
        isLimitOrder:
          type: boolean
          description: true=createOrder (limit); false=createMarketOrder (market)
          default: true
        orderType:
          type: string
          description: Order type (default GTC for limit, FAK for market)
          enum:
            - GTC
            - FOK
            - GTD
            - FAK
          default: GTC
        walletAddress:
          type: string
          description: Wallet address (optional; falls back to order.signer)
          pattern: ^0x[a-fA-F0-9]{40}$
        owner:
          type: string
          description: Polymarket owner (optional, defaults to apiKey from credentials)
          maxLength: 128
        deferExec:
          type: boolean
          description: Defer execution flag
          default: false
        orderVersion:
          type: integer
          description: >-
            Order version: 1=legacy V1, 2=Polymarket V2 (auto-inferred when
            omitted)
          enum:
            - 1
            - 2
        tickSize:
          type: string
          description: V2 tickSize hint
          enum:
            - '0.1'
            - '0.01'
            - '0.001'
            - '0.0001'
        negRisk:
          type: boolean
          description: V2 negRisk flag
          default: false
        funderAddress:
          type: string
          description: V2 funder address (optional)
          pattern: ^0x[a-fA-F0-9]{40}$
        postOnly:
          type: boolean
          description: Post-only flag
          default: false
        feeAmount:
          type: number
          description: Market-order fee (only when isLimitOrder=false)
          default: 0
        reasoning:
          type: string
          description: Trade reasoning text (max 1000 chars)
          maxLength: 1000
        source:
          type: string
          description: Source tag (suggested format sdk:strategy-name)
          maxLength: 100
        skillSlug:
          type: string
          description: Skill identifier for attribution
          maxLength: 100
        expirationTime:
          type: number
          description: Limit order expiration in milliseconds (mk_order.expirationTime)
          default: 0
        order:
          $ref: '#/components/schemas/TradeOrderPayload'
    TradeResult:
      type: object
      properties:
        orderId:
          type: string
        status:
          type: string
        submittedAt:
          type: string
          format: date-time
    TradeOrderPayload:
      type: object
      required:
        - maker
        - signer
        - tokenId
        - makerAmount
        - takerAmount
        - side
        - signature
        - salt
        - signatureType
      properties:
        maker:
          type: string
          description: Maker wallet address
          example: '0x1111111111111111111111111111111111111111'
        signer:
          type: string
          description: Signing wallet address
          example: '0x1111111111111111111111111111111111111111'
        taker:
          type: string
          description: Taker wallet address (zero address for open orders)
          example: '0x0000000000000000000000000000000000000000'
        tokenId:
          type: string
          description: CLOB token ID
          example: >-
            69136365945621600854789649488423522395843457249417452310260493085275775221076
        makerAmount:
          type: string
          description: Maker amount (6-decimal integer)
          example: '120000'
        takerAmount:
          type: string
          description: Taker amount (6-decimal integer)
          example: '1000000'
        side:
          type: string
          enum:
            - BUY
            - SELL
          description: Trade direction
        expiration:
          type: string
          description: Expiration timestamp in seconds
          example: '0'
        nonce:
          type: string
          description: Nonce (V1 only)
          example: '0'
        feeRateBps:
          type: string
          description: Fee rate in basis points (V1 only)
          example: '0'
        signature:
          type: string
          description: EIP712 signature
          example: '0x1234abcd'
        salt:
          type: number
          description: Random salt
          example: 599228746038
        signatureType:
          type: integer
          description: 0=EOA, 1=PolymarketProxy, 2=GnosisSafe, 3=DepositWallet (POLY_1271)
          enum:
            - 0
            - 1
            - 2
            - 3
        timestamp:
          type: string
          description: 'V2 only: order timestamp in milliseconds'
          example: '1713000000000'
        metadata:
          type: string
          description: 'V2 only: metadata (bytes32 hex)'
          example: '0x0000000000000000000000000000000000000000000000000000000000000000'
        builder:
          type: string
          description: 'V2 only: builder (bytes32 hex)'
          example: '0x0000000000000000000000000000000000000000000000000000000000000000'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      x-default: YOUR_API_KEY

````