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

# tpSl: Create Take-Profit and Stop-Loss Orders

> Create TP/SL trigger orders for an existing position. These orders don't consume margin and fire automatically when the trigger price is reached.

The `tpSl` action creates take-profit (TP) and stop-loss (SL) trigger orders for an existing position. Unlike regular orders, TP/SL orders do not consume margin when created — they sit dormant and automatically place a real closing order when the market reaches the trigger price.

You can set a TP only, an SL only, or both in a single request. For position-level TP/SL (`isPositionTpsl: true`), the closing direction is determined automatically from the position side — you don't need to specify it. The position must already exist before you create position-level TP/SL orders.

## Endpoint

```
POST https://dev.upsidemax.xyz/exchange
```

## Request

All requests must include an ECDSA signature and a millisecond-precision nonce.

```json theme={"system"}
{
  "action": {
    "type": "tpSl",
    "a": 1,
    "positionSide": 0,
    "isPositionTpsl": true,
    "tpPrice": "90000",
    "slPrice": "80000",
    "tpLimitPrice": "0",
    "slLimitPrice": "0",
    "tpSize": "0",
    "slSize": "0",
    "tpTriggerType": 0,
    "slTriggerType": 0
  },
  "signature": { "r": "0x...", "s": "0x...", "v": 28 },
  "nonce": 1778858600000
}
```

### Action fields

<ParamField body="type" type="string" required>
  Fixed value: `"tpSl"`.
</ParamField>

<ParamField body="a" type="int32" required>
  The contract ID the TP/SL orders apply to.
</ParamField>

<ParamField body="positionSide" type="int8">
  Identifies the position side: `0` = ONE\_WAY, `1` = LONG, `2` = SHORT. Defaults to `0`.
</ParamField>

<ParamField body="isPositionTpsl" type="boolean">
  When `true`, creates position-level TP/SL orders that automatically close the position when triggered. When `false`, creates standalone trigger orders. Defaults to `false`.
</ParamField>

<ParamField body="orderSide" type="string">
  The side of the order placed when the trigger fires: `"B"` = buy, `"S"` = sell. Used only for standalone trigger orders (`isPositionTpsl` = `false`); for position-level TP/SL the closing direction is inferred automatically.
</ParamField>

<ParamField body="reduceOnly" type="boolean">
  When `true`, the triggered order is marked reduce-only and will only execute if it reduces an open position. Defaults to `false`.
</ParamField>

<ParamField body="tpPrice" type="string">
  Trigger price for the take-profit leg. Set to `"0"` to skip the TP leg. At least one of `tpPrice` or `slPrice` must be greater than `"0"`.
</ParamField>

<ParamField body="slPrice" type="string">
  Trigger price for the stop-loss leg. Set to `"0"` to skip the SL leg. At least one of `tpPrice` or `slPrice` must be greater than `"0"`.
</ParamField>

<ParamField body="tpLimitPrice" type="string">
  Limit price used when the TP trigger fires. `"0"` = execute as a market IOC order after triggering. Any positive value = execute as a GTC limit order at that price.
</ParamField>

<ParamField body="slLimitPrice" type="string">
  Limit price used when the SL trigger fires. `"0"` = execute as a market IOC order after triggering. Any positive value = execute as a GTC limit order at that price.
</ParamField>

<ParamField body="tpSize" type="string">
  The position size to close when the TP triggers. `"0"` = close the entire position.
</ParamField>

<ParamField body="slSize" type="string">
  The position size to close when the SL triggers. `"0"` = close the entire position.
</ParamField>

<ParamField body="tpTriggerType" type="int8">
  The price feed used to evaluate the TP trigger: `0` = mark price, `1` = index price, `2` = last traded price. Defaults to `0`.
</ParamField>

<ParamField body="slTriggerType" type="int8">
  The price feed used to evaluate the SL trigger: `0` = mark price, `1` = index price, `2` = last traded price. Defaults to `0`.
</ParamField>

## Response

### Success

```json theme={"system"}
{
  "status": "ok",
  "response": {
    "type": "tpSl",
    "data": { "tpOrderId": 123, "slOrderId": 124 }
  }
}
```

### Response fields

<ResponseField name="tpOrderId" type="int64">
  The order ID assigned to the take-profit trigger order. Returns `0` if the TP leg was not set (i.e., `tpPrice` was `"0"`).
</ResponseField>

<ResponseField name="slOrderId" type="int64">
  The order ID assigned to the stop-loss trigger order. Returns `0` if the SL leg was not set (i.e., `slPrice` was `"0"`).
</ResponseField>

<Tip>
  Save the returned `tpOrderId` and `slOrderId` values if you need to cancel individual legs later using [cancelConditional](/exchange/cancel-conditional). To cancel all TP/SL orders for a position at once, use [cancelTpSl](/exchange/cancel-tp-sl).
</Tip>
