ADDR=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
TRADE_ID=12345
curl "https://api.arcus.xyz/v1/fill/${TRADE_ID}?address=${ADDR}"import requests
tradeId = "12345"
r = requests.get(
f"https://api.arcus.xyz/v1/fill/{tradeId}",
params={"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"},
)
print(r.json())
const tradeId = "12345";
const url = new URL(`https://api.arcus.xyz/v1/fill/${tradeId}`);
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/fill/{tradeId}', 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/fill/{tradeId}",
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/fill/{tradeId}"
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/fill/{tradeId}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcus.xyz/v1/fill/{tradeId}")
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{
"tradeId": "12345",
"orderId": "order-abc-123",
"marketId": 32767,
"marketDisplayName": "BTC-USD",
"side": "BUY",
"originalSize": "1.0",
"size": "0.01",
"price": "50000.5",
"fee": "0.5",
"role": "MAKER",
"createdAt": 123,
"address": "0x0000000000000000000000000000000000000000",
"accountIndex": 4,
"clientId": "<string>",
"closedPnl": "12.34",
"remainingSize": "<string>",
"positionEffect": "OPEN_LONG",
"sequenceNumber": 123,
"liquidation": {
"method": "LIQUIDATION",
"liquidatedUser": "<string>"
}
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED",
"errorSource": "Order",
"errorType": "Tick",
"rejectionReason": "POST_ONLY_WOULD_CROSS"
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED",
"errorSource": "Order",
"errorType": "Tick",
"rejectionReason": "POST_ONLY_WOULD_CROSS"
}{
"error": "rate limited",
"reason": "account_empty",
"retryAfterMs": 850,
"clientId": "my-order-42"
}Get fill by ID
Returns the single fill belonging to the requested account for the given trade ID. Requires the address query parameter (optional accountIndex selects a subaccount, default 0): fill data is partitioned by account, so the lookup needs the owning account. A trade can produce one fill per participant that share a tradeId; this returns the leg owned by the requested account. No authentication header is required.
ADDR=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
TRADE_ID=12345
curl "https://api.arcus.xyz/v1/fill/${TRADE_ID}?address=${ADDR}"import requests
tradeId = "12345"
r = requests.get(
f"https://api.arcus.xyz/v1/fill/{tradeId}",
params={"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"},
)
print(r.json())
const tradeId = "12345";
const url = new URL(`https://api.arcus.xyz/v1/fill/${tradeId}`);
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/fill/{tradeId}', 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/fill/{tradeId}",
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/fill/{tradeId}"
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/fill/{tradeId}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcus.xyz/v1/fill/{tradeId}")
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{
"tradeId": "12345",
"orderId": "order-abc-123",
"marketId": 32767,
"marketDisplayName": "BTC-USD",
"side": "BUY",
"originalSize": "1.0",
"size": "0.01",
"price": "50000.5",
"fee": "0.5",
"role": "MAKER",
"createdAt": 123,
"address": "0x0000000000000000000000000000000000000000",
"accountIndex": 4,
"clientId": "<string>",
"closedPnl": "12.34",
"remainingSize": "<string>",
"positionEffect": "OPEN_LONG",
"sequenceNumber": 123,
"liquidation": {
"method": "LIQUIDATION",
"liquidatedUser": "<string>"
}
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED",
"errorSource": "Order",
"errorType": "Tick",
"rejectionReason": "POST_ONLY_WOULD_CROSS"
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED",
"errorSource": "Order",
"errorType": "Tick",
"rejectionReason": "POST_ONLY_WOULD_CROSS"
}{
"error": "rate limited",
"reason": "account_empty",
"retryAfterMs": 850,
"clientId": "my-order-42"
}address query parameter (optional accountIndex selects a subaccount, default 0): fill data is partitioned by account, so the lookup needs the owning account. A trade can produce one fill per participant that share a tradeId; this returns the leg owned by the requested account. No authentication header is required.Path Parameters
Trade identifier of the fill (the tradeId field returned by GET /v1/fills). A non-integer value → 400.
"12345"
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}$Subaccount index (0–9) to scope the request to. Defaults to 0 (the primary account). Values above 9 → 400.
0 <= x <= 9Response
Fill details.
Unified fill 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.
Unique trade identifier.
"12345"
Order ID that generated this fill.
"order-abc-123"
Perpetual market identifier (uint16). Map to display name via GET /markets. Used for orders, positions, funding, and market metadata.
0 <= x <= 65535Market symbol (e.g. BTC-USD).
"BTC-USD"
Order side.
BUY, SELL Original order size in human-readable base-asset units (decimal string).
"1.0"
Fill size in human-readable base-asset units (decimal string).
"0.01"
Fill price in human-readable USD (decimal string).
"50000.5"
Fee amount (decimal string). On the liquidated leg of an engine liquidation this is the liquidation penalty (the market's liquidation fee rate applied to the fill notional, paid to the insurance fund) — "0" when the market has no liquidation fee configured. ADL legs carry no fee.
"0.5"
Liquidity role (maker or taker).
MAKER, TAKER Fill timestamp (epoch microseconds).
Ethereum address (lowercase 0x + 40 hex). Only present on REST and snapshot responses.
"0x0000000000000000000000000000000000000000"
Account index (account index, 0–9). Identifies the account for orders, positions, fills, and API keys.
0 <= x <= 9Client-provided order ID. Only present on streaming updates.
Realized PnL for this fill (decimal string, quote currency): cost-basis release (old borrowedCapital − new borrowedCapital − Δsize × price) minus the fill's fee. Opening and same-direction add legs contribute −fee (price PnL is 0). On a flat account, Σ closedPnl + Σ funding equals netQuoteBalance − net deposits. On the liquidated leg of a forced closure (liquidation.method == LIQUIDATION) the engine does not stamp realized PnL on the fill — closedPnl reads "0" by design; the realized loss is already reflected in the account's netQuoteBalance on the accompanying account update.
"12.34"
Remaining unfilled order size after this fill. Only present on streaming updates.
How this fill affected the account's position in marketId. For taker fills the value is the net effect across all fills in the aggregated update (FLIP_* covers a position that closed and reopened on the opposite side within one user order). May be absent on persisted rows from before the field was introduced.
OPEN_LONG, OPEN_SHORT, ADD_LONG, ADD_SHORT, CLOSE_LONG, CLOSE_SHORT, FLIP_LONG_TO_SHORT, FLIP_SHORT_TO_LONG Sequence number for ordering and reconciliation. Only present on streaming updates.
Present only when this fill closed a position involuntarily — on the liquidated account's leg of an engine liquidation (LIQUIDATION) or the deleveraged counterparty's leg of an auto-deleverage (ADL). The voluntary counterparty leg of a liquidation match (a resting maker order that got hit) does not carry this marker. Absent on voluntary fills and on rows persisted before the marker was introduced. This field, not the order-ID format, is the supported way to detect forced closures (the engine's synthetic liq: order-ID prefix is an internal detail and not part of the API contract).
Show child attributes
Show child attributes
Was this page helpful?