Trades
Closed and open positions. This is the feed behind the activity analysis: bursts, one sided flow, holding time and the cross checks against what the trader says.
https://risk.example-firm.com/rubi/v1 with no trailing slash. GET /traders is then requested as https://risk.example-firm.com/rubi/v1/traders.Shared rules for authentication, pagination, errors and the live check are on the Own tech overview.
GET/trades
Returns { data, next_cursor }
Every call, including GET /health, sends Authorization: Bearer <api key> and Accept: application/json. The key is the secret you paste in the dashboard. Rubi never sends a body: every endpoint is GET.
| Query | Required | Rules |
|---|---|---|
updated_since | sent by Rubi | Inclusive lower bound on updated_at. On the first sync Rubi sets this to 90 days ago, even though other resources omit it. Later syncs use the last success minus 10 minutes. |
cursor | no | Opaque cursor from the previous page. |
limit | no | 1 to 500. Rubi sends 200 during sync and 5 during the live check. |
account_id | no | Optional filter for one account. Rubi does not send it today. Supporting it is useful for your own debugging. |
| Field | Type | Description |
|---|---|---|
id | string | Required. Unique per account: ticket or position id. Stable across open and close. Numbers are accepted. |
account_id | string | Required. Must match an account id from GET /accounts. |
symbol | string | Required. Broker symbol, for example EURUSD or XAUUSD. |
side | buy | sell | Required. buy or sell. Rubi also accepts long and short, and 0 or 1, but send buy or sell. |
open_time | timestamp | Required. When the position opened. |
updated_at | timestamp | Required. Change this when the position opens, changes, or closes, or incremental sync will miss it. |
volume | number | null | Lots. lots is accepted as an alias. This is not contract units. |
close_time | timestamp | null | Null while the position is open. A null close_time marks the trade as open. |
open_price | number | null | Entry price. |
close_price | number | null | Null while open. Set both close_time and close_price together when the position closes. |
stop_loss, take_profit | number | null | Prices. Null when the order has none. |
commission, swap | number | null | In account currency. Commission is typically negative. |
profit | number | null | Net result in account currency, after commission and swap when you have them. |
{
"data": [
{
"id": "pos_5512009",
"account_id": "acc_99812",
"symbol": "EURUSD",
"side": "buy",
"volume": 1.5,
"open_time": "2026-09-22T13:01:07Z",
"close_time": "2026-09-22T13:42:55Z",
"open_price": 1.10412,
"close_price": 1.10501,
"stop_loss": 1.1021,
"take_profit": null,
"commission": -10.5,
"swap": 0,
"profit": 123.0,
"updated_at": "2026-09-22T13:42:56Z"
}
],
"next_cursor": "c_20260922_5512009"
}{
"id": "pos_5512010",
"account_id": "acc_99812",
"symbol": "GBPUSD",
"side": "sell",
"volume": 0.4,
"open_time": "2026-09-23T08:11:02Z",
"close_time": null,
"open_price": 1.2711,
"close_price": null,
"stop_loss": 1.274,
"take_profit": null,
"commission": 0,
"swap": 0,
"profit": -18.2,
"updated_at": "2026-09-23T08:11:02Z"
}Backfill and updates#
Keep at least 90 days of closed trades addressable through updated_since. Older history is not requested. When a position is modified or closed, bump updated_at so the next incremental poll returns it again. Rubi upserts by id, so the closed version replaces the open one.
close_time and close_price null until the position closes. Filtering the list down to closed trades only hides live exposure from the report.The live check calls GET /trades?limit=5 and requires id, account_id, symbol, side, open_time and updated_at on every record. An empty data array is valid when you have no trades yet.