> For the complete documentation index, see [llms.txt](https://titan-exchange.gitbook.io/titan/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://titan-exchange.gitbook.io/titan/developer-doc/special-order-types/order-types/oco.md).

# OCO Brackets

One deposit, two triggers — a take-profit ceiling and a stop-loss floor where the first fill cancels the other.

**An `oco` order brackets a position with one deposit: a take-profit above and a stop-loss below.** Whichever leg fires first swaps the full `amount` and cancels the other. One-Cancels-Other — hence the name.

The alternative is two separate orders, which would lock the deposit twice. OCO reserves it once.

| Leg         | Fires when                 |
| ----------- | -------------------------- |
| Take-profit | `price >= takeProfitPrice` |
| Stop-loss   | `price <= stopLossPrice`   |

Prices use the same fixed-point encoding and [price basis](/titan/developer-doc/special-order-types/order-types/stop-loss-take-profit.md#price-basis) as stop-loss and take-profit — a pair ratio by default, or USD per input token with `priceBasis: "usd"`. Both legs share one `priceDecimals` and one `priceBasis`.

## Config

```http
POST /orders/intent
X-Titan-Key: <partner-api-key>
X-Titan-User: <your stable user id>
Content-Type: application/json

{
  "orderType": "oco",
  "userPubkey": "<user's external Solana wallet>",
  "config": {
    "inputMint":  "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000",
    "takeProfitPrice": "200000000",
    "stopLossPrice": "50000000",
    "priceDecimals": 6,
    "expiresAt": 1767225600
  }
}
```

| Field             | Required | Notes                                                                                                                                                                                  |
| ----------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inputMint`       | ✅        | Must differ from `outputMint`.                                                                                                                                                         |
| `outputMint`      | ✅        |                                                                                                                                                                                        |
| `amount`          | ✅        | String, `> 0`. One deposit, shared by both legs.                                                                                                                                       |
| `takeProfitPrice` | ✅        | String, `> 0`. On the order's `priceBasis`, scaled by `10^priceDecimals`.                                                                                                              |
| `stopLossPrice`   | ✅        | String, `> 0`, and **strictly less than** `takeProfitPrice`.                                                                                                                           |
| `priceDecimals`   | ✅        | Integer `0`–`18`, shared by both legs.                                                                                                                                                 |
| `priceBasis`      | ❌        | `"pair"` (default) or `"usd"`, shared by both legs. Same rules as [stop-loss](/titan/developer-doc/special-order-types/order-types/stop-loss-take-profit.md#rules-for-pricebasis-usd). |
| `expiresAt`       | ❌        | Unix seconds, must be in the future. At expiry the deposit is auto-returned.                                                                                                           |
| `trailingStopBps` | ❌        | Integer `1`–`9999`. Makes the **stop-loss leg** trailing — see [Trailing Stops](/titan/developer-doc/special-order-types/order-types/trailing.md).                                     |

{% hint style="warning" %}
`stopLossPrice >= takeProfitPrice` returns `400 VALIDATION_ERROR` — the bracket has to have a gap. And `minOutputAmount` is **not supported on OCO**: it's silently ignored if you send it, so don't offer it in your OCO UI.
{% endhint %}

Top-level fields (`userPubkey`, `outputRecipientAddress`, `platformFee`, `onboardIfNeeded`) and the `confirm` step are identical to every other order type — see [Creating Orders](/titan/developer-doc/special-order-types/guides/creating-orders.md). The minimum-notional floor applies to the full `amount`, as with any trigger order.

## Read

`GET /oco/{orderId}` returns the base [Order](/titan/developer-doc/special-order-types/reference/schema.md#order) shape plus `amount`, `takeProfitPrice`, `stopLossPrice`, `priceDecimals`, `priceBasis`, `expiresAt?`, `executedPrice?`, `executedPriceDecimals?`, `amountReceived?`, `pendingLeg?`, `parentOrderId?`, and the stop-loss leg's trailing state (`trailingStopBps?`, `currentTriggerPrice`, `highestObservedPrice?`).

`parentOrderId` is set when the OCO was created automatically as the bracket of a [conditional entry](/titan/developer-doc/special-order-types/order-types/otoco.md). Scale `executedPrice` by `executedPriceDecimals` — see [`executedPrice` scale](/titan/developer-doc/special-order-types/order-types/stop-loss-take-profit.md#executedprice-scale).

`pendingLeg` — values `stop_loss` or `take_profit` — labels which leg is mid-execution while the order is `executing`, and is absent otherwise. Use it to show the user which side is filling.

Returns `404 NOT_FOUND` if the order doesn't exist, isn't this user's, or isn't an `oco` order.

## Executions

An OCO fill is recorded under **its leg's** type — `stop_loss` or `take_profit_full`. There is no `oco` execution type. Read `executionType` on the single execution row to show which side fired.

## Lifecycle

Identical to [stop-loss and take-profit](/titan/developer-doc/special-order-types/order-types/stop-loss-take-profit.md#lifecycle): `active` immediately after confirm, no retry, and auto-return on both `failed` and `expired`. Both legs' prices, expiry and trail can be changed in place with `PATCH /oco/{orderId}` — see [Modify a trigger order](/titan/developer-doc/special-order-types/guides/managing-orders.md#modify-a-trigger-order). Cancelling before either leg fires leaves the deposit in the manager, so a `cancelled` OCO is the one case where order-level withdrawal matters.

Pausing stops both legs from being watched at once; resuming re-arms both.

## Related pages

* [Stop-Loss & Take-Profit](/titan/developer-doc/special-order-types/order-types/stop-loss-take-profit.md) — price basis and the single-leg types
* [Conditional Entry & Bracket](/titan/developer-doc/special-order-types/order-types/otoco.md) — an OCO created automatically when an entry order fills
* [Trailing Stops](/titan/developer-doc/special-order-types/order-types/trailing.md) — making the stop-loss leg trail while the ceiling stays put
* [Creating Orders](/titan/developer-doc/special-order-types/guides/creating-orders.md) — the shared two-step flow
