ADDR=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
# Fee-rate poll (cheap):
curl "https://api.arcus.xyz/v1/account/stats?address=${ADDR}&include=feeTier"
# Trading figures with fixed windows (on demand):
curl "https://api.arcus.xyz/v1/account/stats?address=${ADDR}&include=volumes&windows=24h,7d,30d"import requests
r = requests.get(
"https://api.arcus.xyz/v1/account/stats",
params={"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"},
)
print(r.json())
const url = new URL("https://api.arcus.xyz/v1/account/stats");
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/account/stats', 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/account/stats",
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/account/stats"
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/account/stats")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcus.xyz/v1/account/stats")
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{
"address": "<string>",
"rollingVolume": 123,
"lifetimeVolume": 123,
"lifetimeFeesPaid": 123,
"rollingFeesPaid": 123,
"windowedStats": {
"24h": {
"volume": 123,
"feesPaid": 123
},
"7d": {
"volume": 123,
"feesPaid": 123
},
"30d": {
"volume": 123,
"feesPaid": 123
}
},
"tradingFeeTier": {
"level": 123,
"makerFeePpm": 123,
"takerFeePpm": 123
}
}{
"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"
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED",
"errorSource": "Order",
"errorType": "Tick",
"rejectionReason": "POST_ONLY_WOULD_CROSS"
}Get account stats
Returns trading statistics for any Ethereum address, in selectable sections so clients fetch only what they need:
feeTier— the current trading fee tier (level + BPS).
ADDR=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
# Fee-rate poll (cheap):
curl "https://api.arcus.xyz/v1/account/stats?address=${ADDR}&include=feeTier"
# Trading figures with fixed windows (on demand):
curl "https://api.arcus.xyz/v1/account/stats?address=${ADDR}&include=volumes&windows=24h,7d,30d"import requests
r = requests.get(
"https://api.arcus.xyz/v1/account/stats",
params={"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"},
)
print(r.json())
const url = new URL("https://api.arcus.xyz/v1/account/stats");
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/account/stats', 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/account/stats",
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/account/stats"
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/account/stats")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.arcus.xyz/v1/account/stats")
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{
"address": "<string>",
"rollingVolume": 123,
"lifetimeVolume": 123,
"lifetimeFeesPaid": 123,
"rollingFeesPaid": 123,
"windowedStats": {
"24h": {
"volume": 123,
"feesPaid": 123
},
"7d": {
"volume": 123,
"feesPaid": 123
},
"30d": {
"volume": 123,
"feesPaid": 123
}
},
"tradingFeeTier": {
"level": 123,
"makerFeePpm": 123,
"takerFeePpm": 123
}
}{
"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"
}{
"error": "Invalid request body",
"code": "GEO_RESTRICTED",
"errorSource": "Order",
"errorType": "Tick",
"rejectionReason": "POST_ONLY_WOULD_CROSS"
}feeTier— the current trading fee tier (level + BPS). Cheap; the right shape for frequent polling of fee rates.volumes— notional fill volume and fees paid over the fee-tier rolling window (30 days) and all-time. Backed by analytics storage; fetch on demand (e.g. a rewards/stats page).
include query parameter (e.g. include=feeTier); omitting it returns both. Fixed 24h / 7d / 30d windows are additionally available via the windows query parameter (e.g. windows=24h,7d,30d) and are returned under windowedStats.
This endpoint always returns 200 — a brand-new address with no activity yields rollingVolume: 0 and tradingFeeTier at level 0 (Base). No authentication is required.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}$Comma-separated response sections to return. Omitting include returns feeTier + volumes (backward compatible). Excluding a section also skips its datastore reads server-side, so pass include=feeTier when polling fee rates and include=volumes when only the trading figures are needed.
feeTier, volumes Comma-separated fixed rolling windows to include under windowedStats (e.g. windows=24h,7d,30d). Omit to skip the windowed figures entirely. Independent of include.
24h, 7d, 30d Response
Account stats.
Account statistics for any Ethereum address. Always returns 200 — a fresh address with no activity yields rollingVolume: 0 and tradingFeeTier at level 0 (Base). Never 404s.
The response is sectioned via the include query parameter: the volume/fees fields belong to the volumes section and tradingFeeTier to the feeTier section. Omitting include returns both. When the volumes section is included, its four fields are always present (explicit 0 for a fresh address).
Lower-case 0x-prefixed 20-byte Ethereum address.
Notional fill volume over the fee-tier rolling window (30 days), in quote quantums (1e9 = $1). NOTE: this is the 30d fee-tier window — use lifetimeVolume for the all-time figure. Returns 0 if the rollup is temporarily unavailable; the endpoint degrades gracefully rather than failing. Omitted when include excludes the volumes section.
All-time perps notional fill volume, in quote quantums (1e9 = $1). Read from the hourly volume rollup. 0 if the rollup is temporarily unavailable. Omitted when include excludes the volumes section.
All-time perps trading fees paid, in quote quantums (1e9 = $1). Read from the hourly fees/PnL rollup. 0 if the rollup is temporarily unavailable. Omitted when include excludes the volumes section.
Perps trading fees paid over the fee-tier rolling window (30 days), in quote quantums (1e9 = $1). Same 30d window as rollingVolume. Read from the hourly fees rollup, so it can trail live fills by up to the current partial hour. 0 if the rollup is temporarily unavailable. Omitted when include excludes the volumes section.
Fixed-window (24h / 7d / 30d) volume/fees figures. Present only when the client opted in via the windows query parameter, and carries only the requested windows. Independent of include.
Show child attributes
Show child attributes
The account's current trading fee tier (level + maker/taker BPS). Omitted when include excludes the feeTier section, or when the fee-tier store is unavailable.
Show child attributes
Show child attributes
Was this page helpful?