> For the complete documentation index, see [llms.txt](https://docs.dimes.fi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dimes.fi/for-developers/order-types/committed-risk-mode.md).

# Committed Risk Mode

Open a position on a fixed, published deleveraging ladder instead of the live risk engine, in exchange for extra margin posted at open.

> **Beta feature — enabled per partner.** Until it is enabled for your API key, asking for `risk_mode: "committed"` returns 400 `beta_feature_not_enabled` and `committed_unwinds` is omitted from every quote response. Contact us to have it enabled.

Every position runs in one of two risk modes.

* **`adaptive`** (default) — the live risk engine watches the market and decides when to deleverage. Nothing is shown up front, because nothing is decided up front.
* **`committed`** — the quote carries a fixed list of price-triggered unwinds, shown to the user before they open, and the user posts extra margin that sits in the vault as first-loss capital. The adaptive engine does not touch a committed position; only the published ladder does. Liquidation remains the backstop in both modes.

Committed mode trades capital for certainty. In adaptive mode a trader cannot see deleveraging coming — the engine decides in the moment, so there is no way to know in advance at what price leverage will be cut, or by how much. In committed mode the trader sets aside a margin deposit alongside their collateral, and that margin is what guarantees the published levels can actually be executed. The ladder becomes a commitment rather than a best effort.

The point is **predictable execution**: a trader can size a position knowing exactly where it will be deleveraged, and you can show that ladder to them before they open.

## Asking for the mode

`risk_mode` goes in the request body of `POST /quotes` and of the promotion endpoints (`POST /promoted-quotes/{id}`). Omitting it means `adaptive`.

```typescript
const { quote } = await client.executeQuote({
  marketTicker: "PRES-2028-DEM",
  side: "yes",
  collateralUsd: 100,
  leverageBps: 30000,
  slippageBps: 100,
  riskMode: "committed",
});
```

**A committed request is answered in committed mode or not at all.** It is never silently downgraded to adaptive. When the market, the entry price or the requested leverage rules the mode out, the request is rejected with `quote_committed_risk_mode_unavailable`.

**Draft quotes ignore `risk_mode`.** A draft always reports `risk_mode: "adaptive"` and `margin_usdc_units: "0"`, but it still prices and returns the ladder in `committed_unwinds` — so take a draft first to find out whether the mode is available, and at what cost, before committing the user to it. The mode is chosen once, at promotion.

## Reading the ladder

Every quote and draft quote carries `committed_unwinds`:

```json
"committed_unwinds": {
  "available": true,
  "margin_required_usd": "67.00",
  "margin_required_usdc_units": "67000000",
  "debt_clear_price_usd": "0.27",
  "debt_clear_price_usd_pips": "2700",
  "planned_unwinds": [
    {
      "sequence": 0,
      "trigger_price_usd": "0.42",
      "trigger_price_usd_pips": "4200",
      "target_leverage_bps": 15000,
      "estimated_sell_tokens": "30",
      "estimated_sell_token_units": "30000000"
    }
  ]
}
```

| Field                                     | Description                                                                                                                                                              |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `available`                               | Whether committed mode can be offered for this quote. When `false`, every other field is `null`.                                                                         |
| `margin_required_*`                       | Extra margin the user posts on top of collateral, held in the vault as first-loss capital. Whatever the ladder does not consume comes back with the position's proceeds. |
| `debt_clear_price_*`                      | Price at which selling the remaining tokens repays the protocol capital in full.                                                                                         |
| `planned_unwinds`                         | The rungs, in the order they fire.                                                                                                                                       |
| `planned_unwinds[].sequence`              | Firing order, starting at 0.                                                                                                                                             |
| `planned_unwinds[].trigger_price_*`       | Price at which this rung fires.                                                                                                                                          |
| `planned_unwinds[].target_leverage_bps`   | Book leverage the position is unwound to when it fires (10000 = 1x).                                                                                                     |
| `planned_unwinds[].estimated_sell_token*` | Estimated size sold to reach that target. An estimate — the executed amount depends on the fill.                                                                         |

An adaptive or unspecified request is never rejected over this: it simply comes back with `committed_unwinds.available: false` and no rungs.

## Paying for it

A committed quote returns two extra fields on top of the usual ones:

| Field               | Description                                                            |
| ------------------- | ---------------------------------------------------------------------- |
| `risk_mode`         | `committed` or `adaptive` — the mode the quote was actually issued in. |
| `margin_usdc_units` | The margin to post, in USDC units. `"0"` on adaptive quotes.           |

`total_user_amount_usdc_units` already includes the margin (collateral + origination fee + expected open trading fee + margin), so approve and fund that amount exactly as you would for an adaptive quote.

The margin sits outside every limit and every fee. It does not count toward user, market or partner position limits, and no fee is charged on it.

## Opening a committed position

A committed quote is signed over a different EIP-712 struct and **must** be submitted to `createPositionWithMargin`, not `createPosition`. A signature for one entry point will not authorize the other — the transaction reverts.

The SDK reads the mode off the quote and picks the entry point for you:

```typescript
import { buildCreatePositionTx, isCommittedQuote } from "@dimes-dot-fi/sdk/contract";

const tx = buildCreatePositionTx(quote); // createPositionWithMargin when the quote is committed

await walletClient.writeContract(tx);
```

If you build the call yourself, branch on `quote.risk_mode`:

```
risk_mode === "committed"  →  createPositionWithMargin(..., marginUsdcUnits, signature, signatureExpiry)
risk_mode === "adaptive"   →  createPosition(..., signature, signatureExpiry)
```

`createPositionWithMargin` takes the same arguments as `createPosition` with `marginUsdcUnits` inserted before the signature. The canonical vault ABI in the [UI repo](https://github.com/dimes-fi/dimes-demo-ui/blob/main/src/contract/canonical-leveraged-prediction-vault-v1-abi.json) carries both.

## After the position is open

The position reports the mode it opened in and the margin it locked, as `entry.risk_mode` and `entry.locked_margin_usdc_units`. Fetch the ladder with `expand=planned_unwinds` on `GET /positions` or `GET /positions/{id}`. Each ladder row carries a `status`:

| `status`     | Meaning                                                                                         |
| ------------ | ----------------------------------------------------------------------------------------------- |
| `planned`    | Still ahead of the position. Fires if the price reaches `trigger_price_usd_pips`.               |
| `triggered`  | Its price was reached and the deleverage was sent. `executed_at` is stamped.                    |
| `superseded` | It can never fire: a partial close already took the position below this step's target leverage. |

Ladder rows are what was promised; `expand=unwinds` returns what actually happened. Keep the two lists apart — a fill can land at a different leverage than the step targeted. See [Position unwinds](/for-developers/api-and-events/api-reference.md#position-unwinds-sub-resource).

## Promotion honours the draft's terms

When you promote a draft as committed, the ladder the draft showed is the ladder you get — provided it is still at least as safe as one priced today. If the market has moved such that a fresh ladder would demand more margin, an extra rung, or a harder target, promotion does not quietly reprice the promise: it rejects with `quote_committed_plan_more_restrictive`, carrying the current margin, the current rungs, and the highest leverage that would still honour the draft. Re-quote, or resubmit at that leverage.

## Errors

| Code                                    | Status | When                                                                                                    |
| --------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------- |
| `beta_feature_not_enabled`              | 400    | Committed mode is not enabled for your partner account. `params.feature` is `committed_risk_mode`.      |
| `quote_committed_risk_mode_unavailable` | 400    | Committed mode could not be priced for this request. See `params.reason` and `params.max_leverage_bps`. |
| `quote_committed_plan_more_restrictive` | 400    | A promotion's fresh ladder is harsher than the one the draft agreed to.                                 |

`quote_committed_risk_mode_unavailable` carries:

* `reason` — `unsupportedMarket`, `unsupportedPriceBand`, `marginTooLarge`, `tooManyUnwinds`, or `notQuotedOnDraft` when a promotion asks for a mode the draft never priced.
* `max_leverage_bps` — the highest leverage at which the same request *would* have priced a ladder, or `null` when no leverage would. Resubmit at that leverage to get committed mode, or resubmit without `risk_mode` to keep the leverage and take the adaptive quote.
* `requested_leverage_bps` — what was asked for.
