---
title: "Reprice a resting limit order in place"
method: POST
path: "/orders/{order_id}/amend"
tags: ["Orders"]
---

# Reprice a resting limit order in place

`POST /orders/{order_id}/amend`

## Request

- Base URL: `https://execution.kairos.trade`
- URL: `https://execution.kairos.trade/orders/{order_id}/amend`
- Auth: API key in header `X-Client-Id` and API key in header `X-Api-Key` and API key in header `X-Api-Secret`

Moves a resting limit order's price in one venue round trip. The order keeps its Kairos `order_id` AND its venue `exchange_order_id` — that is the property this endpoint exists to provide: no supersession to record, and no second order whose fill could be booked twice. The cancel-and-replace it replaces leaves the book empty of the order for the whole cancel round trip and mints a second id to reconcile.
**Venue support.** Only venues advertising `supports_native_amend` in `GET /exchanges/{exchange_id}/capabilities` — today `kalshi` alone. Anything else is `409` `EXCHANGE_AMEND_UNSUPPORTED`, answered before the order's own state is inspected so the verdict is a permanent property of the venue rather than of this moment. There is deliberately NO internal cancel-and-replace fallback: that substitution changes queue position, order identity and the caller's failure modes, so it is the caller's decision.
**Reprice only.** `quantity` is accepted solely to be refused with `409` `EXCHANGE_AMEND_QUANTITY_UNSUPPORTED`, before the order is read — refused rather than silently ignored so a caller never believes it resized. Limit orders only; `price` must be strictly between 0 and 1, in the order's own outcome's terms.
**This endpoint almost always returns `200`.** `success: false` is an ambiguous venue outcome, never a transport failure — the same convention `POST /orders/{order_id}/cancel` uses, because a 5xx invites a retry against an order that may already have been amended. It covers a terminal order, an order not yet at the venue, and a venue that refused; on every one of those the order is untouched and still resting on its old price. Branch on `success`, not on the status code.
**Queue position.** Kalshi preserves it only when an amend DECREASES size; a reprice forfeits it — but so does the cancel/replace this replaces, so nothing is lost. The win is the closed off-book window, not priority.
**Admission.** Runs the same checks a submit does — kill switch, side/kind/TIF circuit breakers evaluated against the order's own side and kind (an amend changes neither), and the order rate limit. An immediate fill from a crossing amend is booked through the normal poller path, not from this response.
**Auth & scope.** Requires `trade:execute` and ownership of the order.

## Path parameters

- `order_id` string, uuid, required

## Request body

- OrderAmendRequest: Request body for `POST /orders/{order_id}/amend`. Reprice only — `quantity` exists solely to be refused.
  - `price` number: New limit price, strictly greater than 0 and less than 1, in the order's OWN outcome's terms (send a Kalshi `No` order's `No` price; do not complement it client-side). Omitted re-sends the price the order already has.
  - `quantity` number: Accepted only to be REFUSED with `409` `EXCHANGE_AMEND_QUANTITY_UNSUPPORTED`, before the order is even read. This route reprices; it does not resize. Refused rather than ignored so a caller never believes an order was resized when it was not.

## Response `200`

Amend outcome. Check `success` — a `200` does not guarantee the order was actually amended (see description).

- OrderAmendResponse: Response for `POST /orders/{order_id}/amend`. Returned with HTTP 200 even when `success` is `false`.
  - `success` boolean, required: Whether the venue confirmed the amend. `false` is an AMBIGUOUS outcome, not an error status — the amend may have been refused, or it may have reached the venue and been applied without us learning so. That ambiguity is why it is not a 5xx, which would invite a blind retry against an order that may already carry the new price. A non-amendable status answers 200 with a false `success` too. On any `false`, re-read the order before acting on it.
  - `order_id` string, uuid, required: The id that was addressed, always unchanged. An amend never mints a new order.
  - `exchange_order_id` string: The venue's order id, also unchanged — Kalshi AmendOrder v2 answers with the same id it was given, so there is no supersession to record. Omitted only on the pre-submission path, where the order has no venue identity yet.
  - `price` string: Decimal string. The new resting price on success. On an unsuccessful path it is the price we last recorded — the resting price when the venue explicitly refused, but only our last known value when the call failed in transit or came back unreadable, where the venue may in fact hold the new price. Omitted when unknown.
  - `quantity` string: Decimal string, the order's total size — always the size it was placed for. This route never resizes. Omitted when unknown.
  - `message` string: Human-readable outcome detail, e.g. "Order amended on exchange", "Order cannot be amended - status is filled", or "Could not amend on the exchange: <reason>". A success whose row write failed reads "Order amended on exchange (price not persisted)".

## Other responses

- `400`: The order is not a limit order, the requested price is not strictly between 0 and 1, or the price is off the market's tick grid — checked before any venue request, against the same grid a submit is held to, with the message naming the tick (`VALIDATION_INVALID_ORDER` / `VALIDATION_INVALID_PRICE`). A non-UUID `{order_id}` or a missing/unparseable JSON body is rejected before the handler runs and answers `400` with a plain-text body rather than the `OrderErrorResponse` envelope. Both representations are modelled below; branch on the response `Content-Type` and do not assume `error_details` is present on every `400` from this path.
- `401`: No valid credential presented — missing/invalid API-key headers or an invalid/expired session token.
- `403`: Missing `trade:execute` scope, or API-key access to the order's venue is disabled (`AUTH_INSUFFICIENT_SCOPE`). This endpoint is also behind the service-token/CSRF/API-key mutation gate, whose own rejections are `403` with a minimal `error` body.
- `404`: No order with that id, or the order belongs to another user — both answer the same way (`VALIDATION_INVALID_ORDER`) so an id is not a probe.
- `409`: The venue has no native amend or is unknown (`EXCHANGE_AMEND_UNSUPPORTED`), or the request carried a `quantity` (`EXCHANGE_AMEND_QUANTITY_UNSUPPORTED`).
- `429`: Order rate limit exceeded — an amend charges the same limiter a submit does. Carries `VALIDATION_INVALID_ORDER`; match the status, not the code.
- `500`: The order could not be read (`INTERNAL_ERROR`).
- `503`: Execution disabled by a circuit breaker (`MARKET_PAUSED`), no executor registered for the venue (`EXCHANGE_ERROR`), venue credentials unavailable (`AUTH_CREDENTIALS_NOT_FOUND`), or the API-key provider-access lookup was unavailable (reported with `AUTH_INSUFFICIENT_SCOPE` — match the status here, not the code).

---

[API](https://skmtc.dev/kairos/apis/kairos-order-execution-api.md) - [All operations](https://skmtc.dev/kairos/apis/kairos-order-execution-api/llms.txt) - [OpenAPI document](https://skmtc.dev/kairos/apis/kairos-order-execution-api/revisions/9ba7d463d505?raw)
