{
"type": "subscribe",
"channel": "exchangeAttributeUpdates"
}{
"type": "subscribed",
"channel": "exchangeAttributeUpdates",
"id": "",
"contents": {
"isSnapshot": true,
"entries": [
{
"type": "feeTierConfig",
"tiers": [
{
"level": 0,
"name": "Base",
"volumeThreshold": 0,
"makerFeePpm": 200,
"takerFeePpm": 500
},
{
"level": 1,
"name": "Bronze",
"volumeThreshold": 100000000000,
"makerFeePpm": 150,
"takerFeePpm": 450
}
]
}
]
}
}{
"type": "channel_data",
"channel": "exchangeAttributeUpdates",
"id": "",
"contents": {
"isSnapshot": false,
"entries": [
{
"type": "feeTierConfig",
"tiers": [
{
"level": 0,
"name": "Base",
"volumeThreshold": 0,
"makerFeePpm": 200,
"takerFeePpm": 500
}
]
}
]
}
}Exchange attribute updates
Endpoint:
wss://api.arcus.xyz/v1/ws— one socket multiplexes every channel and RPC request. Click Connect, then send the example subscribe message below to start receiving data.
Exchange-wide attribute state, discriminated by entry type:
"feeTierConfig" carries the full fee tier table whenever an operator updates it via PUT /internal/feetiers or POST /internal/feetiers/{level}.
"marketAttributes" (DEPRECATED — superseded by the dedicated marketAttributes channel, whose entries carry the market’s full attribute state; this variant keeps streaming for existing consumers and will be removed after a deprecation window) carries per-market Regular Trading Hours and off-hours trading-bound events: RTH boundary crossings (isOutsideRth, with boundEvent: exitRth / enterRth), VWAP settlement seals (sealedVwapSettlementPrice), and off-hours expansion-zone events (boundEvent: expansionZoneEntered when a side’s impact-price EWMA crosses within 90% of its trading boundary, starting the 1-hour expansion clock; expansionZoneExited when the EWMA relaxes out of the zone and the clock resets; tradingBoundExpanded when the clock completes and that side’s band widens one level on the 0.5×→1×→2×→4× ladder).
Global channel — no id required. All subscribers receive the same stream.
On subscribe: snapshot of the current fee tier table (one feeTierConfig entry, isSnapshot: true). Streaming: fee tier table replacements and marketAttributes edge events (isSnapshot: false).
The equivalent REST reads are GET /v1/feetiers and GET /v1/markets (isOutsideRth, isUpperInExpansionZone / isLowerInExpansionZone, upperTradingBound / lowerTradingBound).
{
"type": "subscribe",
"channel": "exchangeAttributeUpdates"
}{
"type": "subscribed",
"channel": "exchangeAttributeUpdates",
"id": "",
"contents": {
"isSnapshot": true,
"entries": [
{
"type": "feeTierConfig",
"tiers": [
{
"level": 0,
"name": "Base",
"volumeThreshold": 0,
"makerFeePpm": 200,
"takerFeePpm": 500
},
{
"level": 1,
"name": "Bronze",
"volumeThreshold": 100000000000,
"makerFeePpm": 150,
"takerFeePpm": 450
}
]
}
]
}
}{
"type": "channel_data",
"channel": "exchangeAttributeUpdates",
"id": "",
"contents": {
"isSnapshot": false,
"entries": [
{
"type": "feeTierConfig",
"tiers": [
{
"level": 0,
"name": "Base",
"volumeThreshold": 0,
"makerFeePpm": 200,
"takerFeePpm": 500
}
]
}
]
}
}Initial snapshot sent once on subscribe. Contains one feeTierConfig entry with the complete current fee tier table (isSnapshot: true).
Streaming update pushed whenever an operator edits the exchange fee tier config. Always carries the full updated table in a single feeTierConfig entry (isSnapshot: false). Clients should replace their local copy atomically.
Was this page helpful?