ADDR=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
ORDER_ID=a1b2c3d4e5f6g7h8
curl "https://api.arcus.xyz/v1/order/${ORDER_ID}?address=${ADDR}"import requests
orderId = "a1b2c3d4e5f6g7h8"
r = requests.get(
f"https://api.arcus.xyz/v1/order/{orderId}",
params={"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"},
)
print(r.json())
const orderId = "a1b2c3d4e5f6g7h8";
const url = new URL(`https://api.arcus.xyz/v1/order/${orderId}`);
url.searchParams.set("address", "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb");
const res = await fetch(url);
console.log(await res.json());
const options = {method: 'GET'};
fetch('https://api.arcus.xyz/v1/order/{orderId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.arcus.xyz/v1/order/{orderId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.arcus.xyz/v1/order/{orderId}"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.arcus.xyz/v1/order/{orderId}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcus.xyz/v1/order/{orderId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"orderId": "<string>",
"marketId": 32767,
"marketDisplayName": "BTC-USD",
"side": "BUY",
"status": "PENDING",
"price": "<string>",
"originalSize": "<string>",
"remainingSize": "<string>",
"updatedAt": 123,
"clientId": "<string>",
"address": "<string>",
"accountIndex": 4,
"type": "LIMIT",
"filledSize": "<string>",
"avgFillPrice": "<string>",
"timeInForce": "GTC",
"goodTilTime": "<string>",
"reduceOnly": true,
"triggerPrice": "<string>",
"tpslType": "STOP_LOSS",
"isPositionTPSL": true,
"parentOrderId": "<string>",
"rejectionReason": "POST_ONLY_WOULD_CROSS",
"cancelReason": "MODIFY_CANCELED",
"state": "OPEN",
"positionEffect": "OPEN_LONG",
"createdAt": 123,
"sequenceNumber": 123
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED"
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED"
}{
"error": "rate limited",
"reason": "account_empty",
"retryAfterMs": 850,
"clientId": "my-order-42"
}Get order status
Returns the status of a specific order by order ID. Requires address query parameter for the owning account because order data is partitioned by account, so the lookup needs the owning account.
ADDR=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
ORDER_ID=a1b2c3d4e5f6g7h8
curl "https://api.arcus.xyz/v1/order/${ORDER_ID}?address=${ADDR}"import requests
orderId = "a1b2c3d4e5f6g7h8"
r = requests.get(
f"https://api.arcus.xyz/v1/order/{orderId}",
params={"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"},
)
print(r.json())
const orderId = "a1b2c3d4e5f6g7h8";
const url = new URL(`https://api.arcus.xyz/v1/order/${orderId}`);
url.searchParams.set("address", "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb");
const res = await fetch(url);
console.log(await res.json());
const options = {method: 'GET'};
fetch('https://api.arcus.xyz/v1/order/{orderId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.arcus.xyz/v1/order/{orderId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.arcus.xyz/v1/order/{orderId}"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.arcus.xyz/v1/order/{orderId}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcus.xyz/v1/order/{orderId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"orderId": "<string>",
"marketId": 32767,
"marketDisplayName": "BTC-USD",
"side": "BUY",
"status": "PENDING",
"price": "<string>",
"originalSize": "<string>",
"remainingSize": "<string>",
"updatedAt": 123,
"clientId": "<string>",
"address": "<string>",
"accountIndex": 4,
"type": "LIMIT",
"filledSize": "<string>",
"avgFillPrice": "<string>",
"timeInForce": "GTC",
"goodTilTime": "<string>",
"reduceOnly": true,
"triggerPrice": "<string>",
"tpslType": "STOP_LOSS",
"isPositionTPSL": true,
"parentOrderId": "<string>",
"rejectionReason": "POST_ONLY_WOULD_CROSS",
"cancelReason": "MODIFY_CANCELED",
"state": "OPEN",
"positionEffect": "OPEN_LONG",
"createdAt": 123,
"sequenceNumber": 123
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED"
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED"
}{
"error": "rate limited",
"reason": "account_empty",
"retryAfterMs": 850,
"clientId": "my-order-42"
}address query parameter for the owning account because order data is partitioned by account, so the lookup needs the owning account.Query Parameters
Master Ethereum address for this API key (must match address from POST /createApiKey for the same key). Required on REST for account-scoped reads and for place/cancel. Invalid hex → 400; mismatch with key → 403.
20-byte EVM address as hex: optional 0x or 0X prefix and exactly 40 hexadecimal digits. API responses normalize to lowercase a–f after 0x.
^(0x|0X)?[0-9a-fA-F]{40}$Response
Order status details.
Unified order shape used across REST responses, WebSocket snapshots, and streaming updates. Fields only available from the store are optional and may be absent in streaming updates.
Client-provided order identifier. Optional; max 36 characters. An account may have at most 10,000 live clientIds simultaneously — placing an order with a new clientId while at this limit is rejected with TOO_MANY_CLIENT_IDS. A clientId slot is freed when the order reaches a terminal state (FILLED, CANCELED, or REJECTED). Reusing an already-active clientId is rejected with DUPLICATE_CLIENT_ID.
36True when the TPSL closes the user's full open position at trigger time (resized against the live position) rather than a sized leg (partialTpsl) or an entryTpsl child. Only present on TPSL orders; absent on plain orders. At most one position-level TPSL of each trigger class (TP, SL) may be active per account+market — a second placement is rejected with POSITION_TPSL_ALREADY_EXISTS.
Machine-readable reason emitted by the matching engine when an order is rejected. See the canonical RejectionReason schema for the full enum and per-value descriptions.
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, FILL_WILL_EXCEED_TRADING_BOUND, OPEN_INTEREST_CAP_EXCEEDED, POSITION_SIZE_CAP_EXCEEDED, MODIFY_TPSL_NOT_SUPPORTED, MODIFY_SUPERSEDED_BY_CANCEL, MODIFY_SIZE_ALREADY_FILLED, ORDER_NOT_FOUND, OPEN_ORDER_CAP_EXCEEDED, EXPIRED Engine-authoritative lifecycle position after this event. Sourced directly from the matching engine and stamped on every streaming update — clients can drive an order state machine off this alone without parsing event types or comparing sizes:
- Partial fill of a resting order: state=PARTIALLY_FILLED (status is "OPEN").
- IOC partial: state=PARTIALLY_FILLED is terminal; the implicit
cancel of the IOC remainder is conveyed by
timeInForce == IOCwith no follow-up event (status is "CANCELED" instead). - Explicit cancel after prior partial fills: state=CANCELED.
statuscarries broader signals (ACK, CANCEL_PENDING, MARGIN_CANCELED, TPSL_*, etc.) that have no equivalent here.
OPEN, PARTIALLY_FILLED, FILLED, CANCELED, REJECTED How a fill on this order changed the account's position in marketId. Only set on fill events; absent on placements / cancels / rejects. For taker fills the value is the net effect across all fills in the same aggregated update (FLIP_* covers a position that closed and reopened on the opposite side within one user order).
OPEN_LONG, OPEN_SHORT, ADD_LONG, ADD_SHORT, CLOSE_LONG, CLOSE_SHORT, FLIP_LONG_TO_SHORT, FLIP_SHORT_TO_LONG Was this page helpful?