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

# Protect a position

> The stop and the target are one unit — attached at entry, or set and replaced after.

A stop and a target are not two orders you happen to send together. They are the primitive: one
pair, applied as one unit, held at the venue as cancel-linked siblings. You can attach the pair
when the entry goes in, or set it on a position you already hold. Both paths land in the same
place.

<Steps>
  <Step title="Attach the exits to the entry">
    `stopLoss` and `takeProfit` ride along with [Place an
    order](/api-reference/trading/place-an-order). Atomic here means the exits are placed with the
    order as one unit or not at all — there is no state where the entry landed and the protection
    silently did not.

    ```bash theme={null}
    curl -X POST "$TRDRS_API_BASE_URL/api/trading/order" \
      -H "Authorization: Bearer $TRDRS_TENANT_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "instrument": "ESU6",
        "side": "buy",
        "qty": 2,
        "clientOrderId": "entry-esu6-1787580900",
        "orderType": "limit",
        "limitPrice": 6480.5,
        "stopLoss": { "price": 6472.5, "offsetTicks": 32 },
        "takeProfit": { "price": 6495, "offsetTicks": 58 },
        "tif": "day"
      }'
    ```

    A leg on an order carries both forms the wire contract defines: the absolute `price` and the
    tick offset from the entry.

    Read `warnings` on the response even when it succeeds: it reports non-fatal degradations on an
    otherwise accepted request, and they are yours to surface.
  </Step>

  <Step title="Set or replace the exits after entry">
    [Set position exits](/api-reference/trading/set-position-exits) sets or replaces the stop and
    target on a position you already hold. The pair is applied as one unit, exactly as at entry.

    ```bash theme={null}
    curl -X POST "$TRDRS_API_BASE_URL/api/trading/exits" \
      -H "Authorization: Bearer $TRDRS_TENANT_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "instrument": "ESU6",
        "stopLoss": 6472.5,
        "takeProfit": 6495,
        "clientOrderId": "exits-esu6-6472.5-6495"
      }'
    ```

    `clientOrderId` is required here — the route answers `400` without one. Key it on the
    instrument and the levels, as above, so a retry of the same intent dedups instead of fighting
    itself.
  </Step>

  <Step title="Move one leg and leave the other alone">
    Each level is three-state. A number sets it, `null` removes it, and omitting it leaves the
    resting leg untouched. Tightening a stop without touching the target is one field:

    ```bash theme={null}
    curl -X POST "$TRDRS_API_BASE_URL/api/trading/exits" \
      -H "Authorization: Bearer $TRDRS_TENANT_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "instrument": "ESU6",
        "stopLoss": 6478.5,
        "clientOrderId": "exits-esu6-6478.5"
      }'
    ```

    Sending `"takeProfit": null` in that body would have removed the target instead.
  </Step>

  <Step title="Read what is actually resting">
    [List position exits](/api-reference/account/list-position-exits) returns the exits recorded
    around the account's positions, with each entry's legs and their states, at the account
    revision they were read at.

    ```bash theme={null}
    curl "$TRDRS_API_BASE_URL/api/account/brackets" \
      -H "Authorization: Bearer $TRDRS_TENANT_KEY"
    ```

    If you already hold a snapshot you do not need this route: the same `brackets` array is in
    [the snapshot](/api-reference/account/get-the-account-snapshot), at the revision that names it.
    This read takes no venue reading and allocates no revision.
  </Step>
</Steps>

## What the states mean

A bracket is the protection around one position. Its `legs` are the individual orders.

| Bracket `state` | What it means                                                                                                           |
| --------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `pending_entry` | The entry has not filled yet.                                                                                           |
| `active`        | The protection is live around a position.                                                                               |
| `completed`     | It ended by doing its job.                                                                                              |
| `cancelled`     | It was taken down.                                                                                                      |
| `failed`        | Terminal and never quiet: the entry filled and the protection could not be established. `endReason` says what happened. |

| Leg `state`                         | What it means                                                                                       |
| ----------------------------------- | --------------------------------------------------------------------------------------------------- |
| `pre_armed`                         | Priced and recorded, deliberately not resting yet, because the position it protects does not exist. |
| `working`                           | Resting at the venue.                                                                               |
| `filled` / `cancelled` / `rejected` | Ended. `rejectReason` carries the venue's reason.                                                   |

Two details that catch clients out:

* **The sibling.** The stop and the target are cancel-linked siblings at the venue, paired by
  `ocoGroup`. The leg that does not fill is cancelled when its sibling does — you do not cancel it
  yourself, and you should not treat its disappearance as a fault.
* **Re-parenting.** A `pre_armed` leg hangs off the entry order through `parentOrderId`. Once that
  entry fills, the leg protects the position and `parentOrderId` is null. Do not key a leg by its
  parent order.

## When the engine moves the stop for you

A breakeven move or a trailing stop is run by the engine, not by you. [List server-managed
stops](/api-reference/account/list-server-managed-stops) shows those instances, the `phase` each
has reached, and — where one is `paused` — the `pauseReason` explaining why nothing is moving the
stop. A pause is honest degradation, not failure: the venue-placed stop is still resting and still
protecting the position.

Both `brackets` and `managedExits` are account state, so an [account
stream](/api-reference/account/stream-account-updates) frame carries them at the same revision as
the positions and orders. There is no separate channel to subscribe to.

A risk-locked account answers `423` to both the order route and the exits route. That is a state
to display, not an error to retry.

## Where to go deeper

* [Place your first order](/guides/place-your-first-order) — the five-step path from a key to a filled order.
* [Save and apply exit plans](/guides/save-exit-plans) — ladders, breakeven and trailing, applied by reference instead of retyped.
* [Set risk controls](/guides/manage-risk-controls) — what produces the `423`, and how it clears.
* [Idempotency](/partner-platform/overview/idempotency) — one intent, one id, forever.
