Skip to content

Own tech

If your firm does not run Axcera, expose these read only endpoints on your own platform. Rubi polls them, upserts by id, and uses the data to prepare interviews and score trading activity.

Transport#

  • HTTPS only, TLS 1.2 or later, JSON bodies in UTF-8.
  • You choose the base URL, for example https://risk.example-firm.com/rubi/v1. Every path below is appended to it. No trailing slash.
  • Authentication is a static secret you generate, sent as Authorization: Bearer <api key>. Rotate it whenever you want and paste the new value in the Rubi dashboard. Rubi also sends Accept: application/json.
  • Restrict the API to the Rubi egress IP ranges shown under Integrations. Each range has a copy button.
  • Rubi never writes. A request without the key must not return 200.
  • Timestamps are RFC 3339 in UTC (2026-09-23T14:05:00Z). Money is a JSON number. Unknown optional fields may be null or omitted.

Pagination#

List endpoints accept these query parameters and must keep a stable order.

ParameterTypeRules
updated_sincetimestampReturn records whose updated_at is greater than or equal to this value. Omit the filter when the parameter is absent.
cursorstringOpaque value you returned as next_cursor. Absent on the first page.
limitintegerPage size. Rubi sends 5 during the live check and 200 during sync. Accept 1 to 500. Default 100 if omitted.

The response shape is { "data": [...], "next_cursor": "..." }. next_cursor is null on the last page. Rubi also accepts the array under items, results or records, or a bare JSON array, but data is the contract to implement.

Order records by updated_at ascending, then id ascending, so a cursor never skips a row that was updated while a page was being read. Returning the same record twice is safe: Rubi upserts by id.

Ten minute overlap
After the first backfill, each incremental sync sends updated_since equal to the previous success minus 10 minutes. Implement the filter as greater than or equal to.

Sync cadence#

ResourceFirst runLater runs
TradersEvery trader. updated_since is omitted.updated_since with the 10 minute overlap, page size 200.
AccountsEvery account. updated_since is omitted.Same overlap as traders.
Tradesupdated_since set to 90 days ago, even on the first run.updated_since with the 10 minute overlap.
PayoutsEvery payout, unless the endpoint answers 404.Same overlap as traders. A later 404 stops payout sync.

The default interval is 5 minutes, configurable from 1 to 60 minutes in the dashboard or via the integrations API.

Errors, limits and latency#

Use the matching HTTP status and this body:

json
{ "error": { "code": "not_found", "message": "Unknown trader cus_18422" } }
StatusWhenWhat Rubi does
401 or 403Missing or rejected key, or an IP that is not allowlisted.The live check fails. Sync stops until you fix the key or the allowlist.
404Unknown single resource, or payouts you do not expose.A missing trader is an error. Payouts 404 is accepted and payout sync is skipped.
429You are throttling.Rubi reads Retry-After in seconds (clamped from 1 to 60, otherwise waits 10) and retries.
5xx or timeoutYour server failed or took more than 20 seconds.Rubi retries with backoff. The dashboard shows the endpoint and the status.
200 with invalid JSONBody is not a JSON object with the expected fields.Reported as an unexpected response. The check fails.

Support at least 5 requests per second. Aim to answer within 10 seconds: the live check warns above that. The hard timeout is 20 seconds.

Live check#

Saving the connection runs these steps in order. Polling starts only when every required step passes.

  1. GET /health returns 200 and { "status": "ok" }.
  2. GET /traders?limit=1 without an Authorization header does not return 200. Answer 401 or 403.
  3. GET /traders?limit=5 returns the list shape. Every record has non-null id and updated_at.
  4. When next_cursor is a non-empty string, GET /traders?limit=5&cursor=... loads the next page. A single page is skipped, not failed.
  5. GET /accounts?limit=5 returns records with id, trader_id and updated_at.
  6. GET /trades?limit=5 returns records with id, account_id, symbol, side, open_time and updated_at.
  7. GET /payouts?limit=5 returns records with id, trader_id, status and updated_at, or answers 404.

Each step shows its status, latency and a hint in the dashboard. The last error keeps the endpoint and the HTTP status.

Connect from the dashboard

  1. Open Integrations and choose Own tech.
  2. Paste the base URL and the bearer key.
  3. Run the live check. Fix any failed step, then save.

The same connection can be created with POST /v1/integrations using "kind": "custom_api". See the integrations endpoints.