Skip to main content
POST
/
v1
/
modifyOrder
Modify order
curl --request POST \
  --url https://api.testnet.arcus.xyz/v1/modifyOrder \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <api-key>' \
  --header 'X-Signature: <api-key>' \
  --header 'X-Timestamp: <api-key>' \
  --data '
{
  "address": "<string>",
  "accountIndex": 4,
  "marketId": 32767,
  "quantity": "<string>",
  "price": "<string>",
  "orderId": "<string>",
  "reduceOnly": false,
  "clientId": "<string>",
  "clientTime": "<string>"
}
'
{
  "address": "<string>",
  "accountIndex": 4,
  "clientTime": 123,
  "orderId": "<string>",
  "marketId": 32767,
  "marketDisplayName": "<string>",
  "updateTime": 123,
  "clientId": "<string>",
  "goodTilTime": "<string>",
  "remainingSize": "<string>",
  "filledSize": "<string>",
  "rateLimit": {
    "remaining": 123
  }
}
Modify the price and/or quantity of an open order (cancel + replace). Requires address query parameter matching the master Ethereum address for X-API-Key. Identify the order to modify by exactly one of orderId or clientId — setting both, or neither, is rejected with a validation error.

Response behavior

Asynchronous. Returns either 202 Accepted (common case — cancel+replace forwarded to the matching engine, body carries the replacement orderId for correlation) or 200 OK (gateway already has definitive state for the replacement order). Subscribe to the orders WebSocket channel to observe the replacement order’s lifecycle.

Authorizations

X-API-Key
string
header
required

Hex-encoded Ed25519 public key (64 chars). The public key IS the API key — register it via POST /createApiKey. Required on every authenticated request, both read-only and signed.

X-Timestamp
string
header
required

Unix time in nanoseconds as a decimal string (e.g. "1713825891591000000"). Millisecond or second epochs are rejected with 401 Unauthorized. Must be within ±30,000 ms (MaxTimestampDriftMs, the drift window stays configured in milliseconds) of server wall-clock, or the request is rejected with 401 Unauthorized. Required on all mutating / credential-creating endpoints. This same value must appear as the ct field in the ordersign typed canonical payload (single-order endpoints) or in each element's ct field (batch endpoints).

X-Signature
string
header
required

Lowercase hex-encoded Ed25519 signature (128 chars).

Single-order endpoints (placeOrder, cancelOrder, modifyOrder, and other non-batch mutating routes) sign over the ordersign typed canonical payload — a compact, key-sorted JSON object built from parsed request fields using engine-native integer values:

placeOrder:   {"ad":"0x…","ai":N,[,"c":"…"],"ct":N,"g":N,"m":N,"op":1,"p":N,"q":N,"r":0|1,"s":N,"t":N,"v":1}
cancelOrder: {"ad":"0x…","ai":N,[,"c":"…"],"ct":N,[,"id":"…"],"m":N,"op":2,"v":1}
modifyOrder: {"ad":"0x…","ai":N,[,"c":"…"],"ct":N,[,"id":"…"],"m":N,"op":3,"p":N,"q":N,"v":1}

ct must equal the X-Timestamp header value. Keys in brackets are conditional (omitted when empty). op values: 1=place, 2=cancel, 3=modify. See the ordersign package for field definitions and reference signing code.

Other signed routes (e.g. createApiKey, tokens, userPreferences) still use the legacy scheme: signing_message = X-Timestamp + ACTION + canonicalJSON(body), where ACTION is the camelCase final path segment.

Batch endpoints (batchPlaceOrders, batchCancelOrders) do NOT use this header. They authenticate with per-element typed ordersign signatures embedded in the request body (see the global auth description and the per-field signature descriptions on OrderRequest / CancelOrderRequest).

Read endpoints are authenticated by ?address= (and optionally X-API-Key) only — no signature is required. canonicalJSON(body) is the JSON body with object keys sorted lexicographically at every level and no whitespace; the server canonicalizes the received body before verifying, so only the bytes signed over must be canonical. Required on all mutating / credential-creating endpoints.

Body

application/json

Modify the price and/or size of a single open order (processed as an atomic cancel + replace).

Identify the order to modify by exactly one of orderId (the server-generated id) or clientId (resolved engine-side against the account's client-id index). Setting both is rejected, and so is setting neither — supply one or the other, never both.

address
string
required

Master Ethereum address for this API key (must match POST /createApiKey for the same key).

Pattern: ^(0x|0X)?[0-9a-fA-F]{40}$
accountIndex
integer
required

Account index (account index, 0–9). Identifies the account for orders, positions, fills, and API keys.

Required range: 0 <= x <= 9
marketId
integer
required

Perpetual market identifier (uint16). Map to display name via GET /markets. Used for orders, positions, funding, and market metadata.

Required range: 0 <= x <= 65535
quantity
string
required

New size in human-readable base-asset units (e.g. "0.5" for 0.5 BTC).

Minimum string length: 1
Pattern: ^(0\.[0-9]*[1-9][0-9]*|[1-9][0-9]*\.?[0-9]*)$
price
string
required

New price in human-readable USD (e.g. "50000.5").

Minimum string length: 1
Pattern: ^(0\.[0-9]*[1-9][0-9]*|[1-9][0-9]*\.?[0-9]*)$
side
enum<string>
required
Available options:
BUY,
SELL
timeInForce
enum<string>
required

GTT = Good Till Time (rests until goodTilTime), IOC = Immediate or Cancel, FOK = Fill or Kill, ALO = Add Liquidity Only (post-only)

Available options:
GTT,
IOC,
FOK,
ALO
orderId
string

Server-generated order ID to modify (hex string). Provide exactly one of orderId or clientId, never both.

Minimum string length: 1
reduceOnly
boolean | null
default:false

If true, the order can only reduce an existing position. Requires timeInForce to be IOC or FOK.

clientId
string | null

Identify the order to modify by its placement-time clientId. Subject to the same constraints as at placement: 1–36 characters, [A-Za-z0-9_-] only. The gateway resolves the value against the account's client-id index engine-side. Provide exactly one of orderId or clientId; supplying both is rejected with HTTP 400.

Maximum string length: 36
Pattern: ^[A-Za-z0-9_-]+$
clientTime
string | null

Client-side timestamp (epoch ms as string).

Response

Modify processed and the gateway already has definitive state for the replacement order. Treat as best-effort enrichment of the 202 path; the orders WebSocket channel is still the source of truth.

Modify-order response. The HTTP call is asynchronous and may return either:

  • 202 Accepted — common case. status is ACK and the body carries the replacement orderId for correlation; the orders WebSocket channel delivers the lifecycle.
  • 200 OK — the gateway already had definitive state for the replacement order by the time it responded.
address
string
required

Master Ethereum address of the account that modified the order.

Example:

"0x1234567890abcdef1234567890abcdef12345678"

accountIndex
integer
required

Account index (subaccount) that modified the order.

Required range: 0 <= x <= 9
clientTime
integer<int64>
required

Parsed clientTime from the request when provided as an integer-like string; otherwise 0.

orderId
string
required

Server-generated id of the replacement order created by the modify operation.

marketId
integer
required

Perpetual market identifier (uint16). Map to display name via GET /markets. Used for orders, positions, funding, and market metadata.

Required range: 0 <= x <= 65535
marketDisplayName
string
required

Market symbol (e.g. BTC-USD).

Example:

"BTC-USD"

status
enum<string>
required

ACK on the 202 path. On the 200 path, the definitive go-core state.

Available options:
PENDING,
OPEN,
PARTIALLY_FILLED,
FILLED,
CANCELED,
MARGIN_CANCELED,
REJECTED,
UNTRIGGERED,
TPSL_PLACED,
TPSL_TRIGGERED,
TPSL_CANCELED,
LIQUIDATED,
ADL,
ACK,
CANCEL_ACKNOWLEDGED,
CANCEL_ALL_ACKNOWLEDGED,
CANCEL_PENDING,
ERROR
Example:

"ACK"

updateTime
integer<int64>
required

Gateway clock (epoch microseconds) at the moment the modify was forwarded to go-core.

clientId
string

Echo of the client id attached to the replacement order, when provided.

timeInForce
enum<string>

Echo of the time-in-force from the modify request.

Available options:
GTT,
IOC,
FOK,
ALO
goodTilTime
string

The resting order's expiration timestamp in epoch microseconds (as string). Sourced from the firehose AccountUpdate once go-core confirms the modify. Present only on the 200 path for GTD/ALO orders; absent on 202 and for GTC/IOC/FOK orders.

remainingSize
string

Unfilled size of the replacement order. Populated only on the 200 path.

filledSize
string

Cumulative filled size of the replacement order. Populated only on the 200 path.

rejectionReason
enum<string>

Populated when status is REJECTED on the 200 path.

Available options:
POST_ONLY_WOULD_CROSS,
SELF_TRADE,
UNDERCOLLATERALIZED,
COULD_NOT_FILL,
IOC_CANCELED,
FOK_FAILED,
REDUCE_ONLY_WOULD_INCREASE,
TOO_MANY_CLIENT_IDS,
DUPLICATE_CLIENT_ID,
POSITION_TPSL_ALREADY_EXISTS,
ENTRY_TPSL_CANNOT_BE_POSITION_TPSL,
ORDER_WILL_TAKE_LIQUIDITY_DURING_MARKET_HALT,
ORDER_NOT_FOUND_FOR_MODIFY,
MODIFY_CHANGED_IMMUTABLE_FIELD,
MODIFY_ZERO_SIZE,
PRICE_WILL_EXCEED_MAXIMUM_OUTSIDE_RTH_TRADING_BOUND,
MODIFY_WOULD_CROSS_OUTSIDE_RTH_TRADING_BOUNDARY
rateLimit
object

Per-subaccount order-pool rate-limit snapshot after this modify. Omitted when rate limiting is not configured.