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

# Trade API: Order Types, Execution, and Positions

> The Bravado Trade API covers the full order lifecycle on supported prediction markets: eight order types, bracket orders, and position management including redeem, split, and merge.

Every order on Bravado flows through a single endpoint, `POST /v2/trade/order`, and a `type` field selects the execution strategy. Eight order types are available, ranging from simple resting limit orders to fully managed strategies like TWAP and trailing stops. Understanding which fields belong to which type, and how each type interacts with each venue, will save you time debugging unexpected rejections and miscalculated sizes.

<Warning>
  **Price is a decimal probability, not cents.** A price of `"0.62"` means 62 cents per share. If you send `price: "62"`, the API will return an error because 62 is outside the valid range of 0.001–0.999. Always express prices as decimals.
</Warning>

## Why Bravado over the native endpoints

Polymarket's CLOB accepts limit and market orders. Anything more sophisticated is left to you: you build the execution engine, keep a process alive to run it, and handle every failure in between.

Bravado runs that layer for you.

|                      | Native CLOB                | Bravado Trade API                                                          |
| -------------------- | -------------------------- | -------------------------------------------------------------------------- |
| Order types          | LIMIT, MARKET              | Those plus TWAP, ICEBERG, PEGGED, STOP\_LOSS, TAKE\_PROFIT, TRAILING\_STOP |
| Advanced execution   | Build and host it yourself | Executed server-side, survives your process restarting                     |
| Bracket orders       | Not available              | Take-profit and stop-loss attached at entry                                |
| Duplicate protection | Not enforced               | `Idempotency-Key` required on every mutation                               |
| Batching             | One order per call         | Batch submit, batch cancel, cancel-all                                     |
| Sub-accounts         | Not available              | Provisioned under a partner master key                                     |

What that means in practice:

* **A TWAP keeps running when your bot does not.** Managed strategies live on Bravado's side and expose a lifecycle you can inspect on `GET /v2/trade/strategies` and cancel on demand. A self-hosted scheduler dies with your process, mid-execution.
* **Retries are safe.** Every mutating request takes an `Idempotency-Key`. Retry a timed-out order with the same key and you get the original response back rather than a second position. See [Idempotency](/reference/idempotency).
* **Position mechanics are one call.** Redeem, split, and merge are endpoints rather than raw Conditional Token Framework interactions.
* **Limits are discoverable.** Your quota is returned as `rate_limit_per_min` on [`GET /v2/trade/account`](/api/trade/account), so a client can read its own budget instead of hard-coding an assumption.

## Fees

The Trade API charges **10 bips (0.10%) per side**, applied to both the maker and the taker.

|       | Trade API       |
| ----- | --------------- |
| Maker | 10 bips (0.10%) |
| Taker | 10 bips (0.10%) |

Basis points are hundredths of a percent, so 10 bips is 0.10% of notional. Fees are collected through **Bravado builder codes**, which are applied automatically. No configuration is required to start trading.

The builder code applied to an order is returned as `builder_code_used` on the order response, and the effective code for your key is visible as `builder_code_resolved` on [`GET /v2/trade/account`](/api/trade/account).

<Card title="Need your own builder codes?" icon="mail" href="mailto:support@bravadotrade.com">
  If you need a custom setup running your own builder codes rather than Bravado's, reach out to **[support@bravadotrade.com](mailto:support@bravadotrade.com)** and the team will get you configured.
</Card>

## Field units reference

Mismatched units are the single most common source of bugs when integrating the Trade API. Use this table as a reference whenever you build a request payload.

| Field                                                                                       | Unit                              | Valid example    | Common mistake         |
| ------------------------------------------------------------------------------------------- | --------------------------------- | ---------------- | ---------------------- |
| `price`, `take_profit.price`, `stop_loss.price`, `price_floor`, `price_ceiling`             | Decimal probability (0.001–0.999) | `"0.60"` (= 60¢) | Sending `"60"` (cents) |
| `execution.trailing_offset`, `execution.high_water_mark`                                    | Decimal probability (0.001–0.999) | `"0.05"`         | Sending `"5"`          |
| `size`, `execution.clip_size`, bracket `size`                                               | Shares                            | `"100"`          |                        |
| `budget_usdc`, `quote_amount`                                                               | US dollars                        | `"50"`           | Micro-units            |
| `offset_ticks`                                                                              | CLOB ticks (1 tick = 0.1¢)        | `0`              |                        |
| `execution.trailing_offset_pct`, `execution.randomize_pct`, `execution.price_tolerance_pct` | Percent (0–100)                   | `5`              | Sending `0.05`         |
| `execution.duration_sec`                                                                    | Seconds                           | `3600`           | Minutes                |
| `execution.interval_sec`                                                                    | Seconds (minimum 10)              | `60`             | Values below 10        |

## Order type overview

| Type            | Returns     | Description                                          | Venues                  |
| --------------- | ----------- | ---------------------------------------------------- | ----------------------- |
| `LIMIT`         | `order_id`  | Resting limit order posted to the CLOB               | Polymarket, Predict.fun |
| `MARKET`        | `order_id`  | Immediate execution at the best available price      | Polymarket, Predict.fun |
| `TWAP`          | `record_id` | Time-weighted average price spread over a duration   | Polymarket, Predict.fun |
| `PEGGED`        | `record_id` | Automatically chases the touch price within a budget | Polymarket              |
| `ICEBERG`       | `record_id` | Large order executed as hidden, repeated slices      | Polymarket              |
| `STOP_LOSS`     | `record_id` | Sell trigger when price falls to a threshold         | Polymarket              |
| `TAKE_PROFIT`   | `order_id`  | Immediate CLOB sell when price rises to a target     | Polymarket              |
| `TRAILING_STOP` | `record_id` | Dynamic stop that trails the high-water mark         | Polymarket              |

<Info>
  **Choosing a venue.** Add `"venue": "predictfun"` to route an order to Predict.fun; omit it (or send `"polymarket"`) for Polymarket. The venue must be enabled for your key. Order types not yet on a venue return `VENUE_CAPABILITY_UNSUPPORTED`. You can also pin the venue in the path — `POST /v2/trade/predictfun/order` — see [venue selection](/markets/predict-fun/trade-api#two-ways-to-select-the-venue).
</Info>

## Venue support

The Trade API is multi-venue. Everything below is the Polymarket reference; the [venue pages](/markets/overview) document what each venue supports and where it differs.

<CardGroup cols={2}>
  <Card title="Polymarket" icon="https://mintcdn.com/bravado/nm6Bs4I1Kmd-W087/logo/polymarket.png?fit=max&auto=format&n=nm6Bs4I1Kmd-W087&q=85&s=4ce81507f8cf81b627f57e3ed782dbfd" href="/markets/polymarket/trade-api" width="148" height="148" data-path="logo/polymarket.png">
    Full support — all eight order types, brackets, and positions (redeem/split/merge). Polygon, pUSD.
  </Card>

  <Card title="Predict.fun" icon="https://mintcdn.com/bravado/cHy7EauylyRcAcVI/logo/predict-fun.png?fit=max&auto=format&n=cHy7EauylyRcAcVI&q=85&s=76b47997dd7baeaa9e263f802a25b0f0" href="/markets/predict-fun/trade-api" width="400" height="400" data-path="logo/predict-fun.png">
    LIMIT, MARKET, TWAP + positions (redeem/split/merge/withdraw). BNB Chain, USDT.
  </Card>
</CardGroup>

|                    | Polymarket                        | Predict.fun                                              |
| ------------------ | --------------------------------- | -------------------------------------------------------- |
| Chain / collateral | Polygon / pUSD                    | BNB Chain / USDT                                         |
| Order types        | All 8                             | LIMIT, MARKET, TWAP                                      |
| Price tick         | `0.001`                           | `0.01`                                                   |
| Minimum order      | 5 shares (resting) / \$1 (market) | \$0.90                                                   |
| Trading fee        | 0                                 | Market-set (`feeRateBps`, \~2%), taken in shares on buys |
| Time in force      | GTC / IOC / FOK                   | GTC only                                                 |
| Order ids          | `0x` hashes                       | Numeric strings                                          |

## CLOB orders vs. managed strategies

Order types fall into two categories that differ in how you track and cancel them.

**CLOB orders** (`LIMIT`, `MARKET`, `TAKE_PROFIT`) post directly to the Polymarket central limit order book. They return an `order_id` and appear on `GET /v2/trade/orders/open`. Cancel them with `DELETE /v2/trade/orders/{order_id}`.

**Managed strategies** (`PEGGED`, `TWAP`, `ICEBERG`, `STOP_LOSS`, `TRAILING_STOP`) are supervised by the Bravado execution engine, which manages their lifecycle on your behalf. They return a `record_id` and appear on `GET /v2/trade/strategies`. Cancel them with `DELETE /v2/trade/strategies/{record_id}`.

<Note>
  A `PENDING` status on a managed strategy is **not** a rejection. It means the engine has accepted the strategy and is waiting for market conditions to satisfy its entry criteria. Monitor the strategy record rather than treating `PENDING` as an error state.
</Note>

### LIMIT order example

```json theme={null}
{
  "type": "LIMIT",
  "symbol": "71321045679252212594626385532706912750332728571942532289631379312455583992646",
  "side": "BUY",
  "price": "0.62",
  "size": "100"
}
```

### TWAP order example

```json theme={null}
{
  "type": "TWAP",
  "symbol": "71321045679252212594626385532706912750332728571942532289631379312455583992646",
  "side": "BUY",
  "budget_usdc": "200",
  "execution": {
    "duration_sec": 3600,
    "interval_sec": 60,
    "price_tolerance_pct": 2
  }
}
```

### TRAILING\_STOP example

```json theme={null}
{
  "type": "TRAILING_STOP",
  "symbol": "71321045679252212594626385532706912750332728571942532289631379312455583992646",
  "side": "SELL",
  "size": "500",
  "execution": {
    "high_water_mark": "0.80",
    "trailing_offset": "0.05"
  }
}
```

## Bracket orders

A bracket order attaches a `take_profit` and/or `stop_loss` leg to a `LIMIT` or `MARKET` buy entry. When the entry fills, the bracket legs are submitted automatically.

Bracket orders are **best-effort**: if the entry fill succeeds but a bracket leg cannot be submitted (for example, due to a market minimum), the entry is **not** rolled back. You still hold the position. Bravado simply records the bracket failure in the response.

<Warning>
  Always inspect `warnings[]` and `brackets.take_profit.error` / `brackets.stop_loss.error` in every order response. A missing bracket leg will not surface as an HTTP error. It will only appear in those fields.
</Warning>

```json theme={null}
{
  "type": "LIMIT",
  "symbol": "71321045679252212594626385532706912750332728571942532289631379312455583992646",
  "side": "BUY",
  "price": "0.55",
  "size": "200",
  "take_profit": {
    "price": "0.80",
    "size": "200"
  },
  "stop_loss": {
    "price": "0.40",
    "size": "200"
  }
}
```

## Market microstructure constraints

Some rejections are enforced by the CLOB or Polymarket protocol. They are not Bravado bugs. The most common ones are:

* **Resting order share minimum**: most markets require at least 5 shares per resting limit order. Sending `size: "1"` on a `LIMIT` order will be rejected.
* **Market order notional minimum**: `MARKET` orders require a minimum spend of \$1. Sending `budget_usdc: "0.50"` will be rejected.
* **Iceberg slices are post-only**: each `ICEBERG` slice is submitted as a passive order. For a buy, the slice price must be at or below the current best bid. Aggressive iceberg slices are not supported.

Refer to the [Polymarket CLOB documentation](https://docs.polymarket.com) for the full list of per-market parameters.

<Note>
  Check `warnings[]` on **every** order response, even successful ones. Warnings surface non-fatal issues such as partial fills, clamped prices, and failed bracket legs that would otherwise be silent.
</Note>

## Positions

Positions on Bravado represent outcome token balances held in your Polymarket Safe wallet. When you buy YES or NO shares in a Polymarket market, those ERC-1155 tokens land in your wallet and Bravado surfaces them as a position record with a live mark price, cost basis, and PnL attribution. This page explains the full lifecycle of a position, from the moment you enter a trade to the point where you redeem a resolved market.

<Tip>
  Poll `GET /v2/trade/positions?status=active` to retrieve only your open positions. Omitting the `status` filter returns both active and closed positions, which can be a large payload for active wallets.
</Tip>

## Position lifecycle

<Steps>
  <Step title="Open">
    You buy outcome token shares. Bravado creates a position record with `status: active`, an average cost basis, and a live mark price derived from the CLOB midpoint.
  </Step>

  <Step title="Partially closed">
    You sell a portion of your shares. The position remains `active` but `size` decreases. Realized PnL is updated to reflect the cashflow from the partial exit.
  </Step>

  <Step title="Fully closed or resolved">
    You sell all remaining shares, or the market resolves. The position moves to `status: closed`. Live fields (`current_value`, `unrealized_pnl`, `mark_price`) are zeroed; only `realized_pnl` is retained.
  </Step>
</Steps>

## Active vs. closed positions

<Tabs>
  <Tab title="Active positions">
    An active position has a full set of live fields updated on each response:

    | Field            | Description                                                                           |
    | ---------------- | ------------------------------------------------------------------------------------- |
    | `mark_price`     | Latest CLOB midpoint for the outcome token                                            |
    | `size`           | Current share balance                                                                 |
    | `current_value`  | `size × mark_price` in USDC                                                           |
    | `unrealized_pnl` | `size × (mark_price − avg_cost)`                                                      |
    | `avg_cost`       | Volume-weighted average entry price                                                   |
    | `redeemable`     | `true` when the market has resolved and shares can be redeemed                        |
    | `mergeable`      | `true` when you hold a complete set of outcome tokens that can be merged back to pUSD |
  </Tab>

  <Tab title="Closed positions">
    A closed position retains only the historical cashflow data:

    | Field                                           | Description                                   |
    | ----------------------------------------------- | --------------------------------------------- |
    | `realized_pnl`                                  | Net cashflow (proceeds minus cost) after fees |
    | `status`                                        | `closed`                                      |
    | `mark_price`, `current_value`, `unrealized_pnl` | All zero                                      |

    Use closed positions to calculate your historical win rate and total PnL per market.
  </Tab>
</Tabs>

## PnL model

Bravado uses a **cashflow model** for realized PnL. It measures the actual USDC that flowed in and out of your wallet, net of trading fees.

<CardGroup cols={3}>
  <Card title="Realized PnL">
    The net USDC received from closed or partially closed positions minus the cost of the shares sold, after fees.

    ```
    realized_pnl = Σ(sell_usdc) − Σ(buy_usdc) − fees
    ```
  </Card>

  <Card title="Unrealized PnL">
    The paper gain or loss on your open share balance, marked to the current CLOB midpoint.

    ```
    unrealized_pnl = size × (mark_price − avg_cost)
    ```
  </Card>

  <Card title="Total PnL">
    The sum of both components, representing your complete economic position.

    ```
    total_pnl = realized_pnl + unrealized_pnl
    ```
  </Card>
</CardGroup>

## Collateral

Polymarket uses two collateral tokens, and Bravado supports both:

| Token      | Status      | Notes                                                                        |
| ---------- | ----------- | ---------------------------------------------------------------------------- |
| **pUSD**   | Active (V2) | The primary collateral token for all V2 markets. Use this for new positions. |
| **USDC.e** | Legacy      | Used in older V1 markets. Can be wrapped into pUSD for use in V2 markets.    |

Call `GET /v2/trade/balances` to retrieve your current balance of both tokens alongside your total portfolio value.

```json theme={null}
{
  "pusd": "1500.00",
  "usdc_e": "200.00",
  "total_value_usdc": "1700.00"
}
```

## Redeeming resolved positions

When a Polymarket market resolves, the winning outcome token is redeemable for \$1 per share. Redemption is **not automatic**. You must call the redeem endpoint to receive your payout.

```bash theme={null}
POST /v2/trade/positions/redeem
```

```json theme={null}
{
  "token_id": "71321045679252212594626385532706912750332728571942532289631379312455583992646"
}
```

The endpoint is synchronous and returns `payout_base_units`, the raw on-chain payout amount. Check `position.redeemable === true` before calling to avoid a no-op transaction.

<Note>
  Losing positions pay out **\$0 per share**. This is the expected behavior of prediction markets, not a bug. Your `realized_pnl` on a losing position will be negative and equal to your total cost basis.
</Note>

## Splitting and merging outcome sets

Polymarket's conditional token framework lets you convert pUSD directly into a complete set of outcome tokens, one YES share and one NO share per dollar, without going through the order book. Bravado exposes both directions:

<Accordion title="Split: pUSD → outcome tokens">
  Splitting converts pUSD into one share of every outcome in a market. For a binary market, \$100 of pUSD becomes 100 YES shares + 100 NO shares.

  **When to use it:** Market making. You can immediately offer both sides of the book without paying the spread.

  ```bash theme={null}
  POST /v2/trade/positions/split
  ```

  ```json theme={null}
  {
    "condition_id": "0x5f65177b394277fd294cd75650044e2898f2d2b2e2f2a2c2d2e2f303132333435",
    "amount_usdc": "100"
  }
  ```
</Accordion>

<Accordion title="Merge: outcome tokens → pUSD">
  Merging is the inverse: combining a complete set of outcome tokens (one of each outcome) back into pUSD at 1:1. You must hold at least one share of every outcome to merge.

  **When to use it:** Unwinding a split position or extracting value from a portfolio that holds both sides.

  ```bash theme={null}
  POST /v2/trade/positions/merge
  ```

  ```json theme={null}
  {
    "condition_id": "0x5f65177b394277fd294cd75650044e2898f2d2b2e2f2a2c2d2e2f303132333435",
    "amount_shares": "100"
  }
  ```
</Accordion>
