account:fills_v3_#{address}. You will receive updates when a bet locks, fails, or settles.
CHANNEL NAME FORMAT
account:trades_v3_#{address}
| Name | Type | Description |
|---|---|---|
| address | string | Your checksummed address. It must equal your realtime token’s sub — see subscribing to your own channels |
trade. Every message carries the whole current row, not a delta.
| Name | Type | Description |
|---|---|---|
| tradeId | string | The bet. Every fill for this bet carries the same value |
| userAddress | string | Your user address, checksummed |
| wallet | string | Your proxy address — where the funds live |
| marketHash | string | The market. For a parlay or quarter-line bet, the parent market |
| isBettingOutcomeOne | boolean | The side you backed |
| isParlay | boolean | true when marketHash is a parlay parent |
| totalStake | string | The amount risked, in base units. See unit conversions. |
| totalReturn | string | Gross payout if it wins, stake included |
| weightedAverageOdds | string | The odds in the sx.bet protocol format, blended across the bet’s fills. To convert to implied odds divide by 10^20. See unit conversions. |
| ceRefundAmount | string | Capital-efficiency refund on this bet. See capital efficiency |
| ceRefundFeeAmount | string | The fee taken on that refund |
| usedBetCredits | boolean | Whether bet credits paid for it |
| fillCount | number | How many fills make up this bet. A number, while every amount is a string |
| status | string | "PENDING", "LOCKED", "FAILED" or "SETTLED". See bet lifecycle |
| externalUserId | string | Optional partner tag from the order that produced this bet, present only when set. See External user id |
| betTime | string | ISO timestamp for when the bet was placed |
| gameTime | string | ISO timestamp for kickoff |
| createdAt | string | ISO timestamp for when the row was created |
| updatedAt | string | ISO timestamp for the last modification of this row |
| settlement | object or null | null on every message until status is "SETTLED" |
settlement object looks like:
| Name | Type | Description |
|---|---|---|
| outcome | number | The graded outcome |
| settleReturnAmount | string | What was returned on settlement |
| settleFeeAmount | string | The fee taken on settlement |
| settleCeRefundAmount | string | Capital-efficiency refund applied at settlement |
| settleDate | string | ISO timestamp for when the bet settled |
// To subscribe
const address = "0xbcc6D643e4159A75ED1dB4e13330230B82F2AEe5"; // checksummed
const sub = client.newSubscription(`account:trades_v3_#${address}`, { recoverable: true });
sub.on("publication", (ctx) => {
const data = ctx.data;
// message handler logic
});
sub.subscribe();
import asyncio
from centrifuge import Client, PublicationContext, SubscriptionEventHandler
async def on_publication(ctx: PublicationContext) -> None:
print(ctx.data)
async def main():
address = "0xbcc6D643e4159A75ED1dB4e13330230B82F2AEe5" # checksummed
client = Client(
"wss://realtime.sx.bet/connection/websocket",
token="YOUR_TOKEN", # from /user/realtime-token-v3/api-key
)
await client.connect()
handler = SubscriptionEventHandler(on_publication=on_publication)
sub = client.new_subscription(f"account:trades_v3_#{address}", handler)
await sub.subscribe()
await asyncio.Future() # keep running
asyncio.run(main())
{
"trade": {
"tradeId": "0xac6bb30bba6ea82d8717219a4fa49d15b58fd638fba479f294b4d402376d14d6",
"userAddress": "0xbcc6D643e4159A75ED1dB4e13330230B82F2AEe5",
"wallet": "0x4361123dbdc1D812fdf7D27045aF358C9C8AA70A",
"marketHash": "0x1fec4ed9b71c2f812db900af7d12446158a0eda56041106f99551c496efd3266",
"isBettingOutcomeOne": false,
"isParlay": false,
"totalStake": "1000000",
"totalReturn": "2500000",
"weightedAverageOdds": "40000000000000000000",
"ceRefundAmount": "0",
"ceRefundFeeAmount": "0",
"usedBetCredits": false,
"fillCount": 2,
"status": "LOCKED",
"betTime": "2026-07-31T18:47:09.577Z",
"gameTime": "2040-01-01T00:00:00.000Z",
"createdAt": "2026-07-31T18:47:09.575Z",
"updatedAt": "2026-07-31T18:47:12.837Z",
"settlement": null
}
}