Skip to main content
These rules apply to REST v1, REST v2, and the matching MCP tools. REST parameters and MCP arguments use the same names. The generated endpoint pages list each read’s exact parameters.

Response envelope

Every REST success has the same outer shape:
data.meta differs by read: Stats, rankings, and activity summaries also return data.filtersApplied, which holds their applied time bounds in appliedTimeRange. Errors use this envelope:
Keep the requestId when you contact support. MCP tools return the same results, meta, and filtersApplied as structured content, and report errors through the MCP response model instead of this envelope.

Server time

Every list and stats response includes meta.serverTime, the server’s UTC time when it produced the response, as an ISO-8601 string. Resolve relative phrases such as “today” or “last 7 days” into explicit startTime and endTime from this value, not from a clock you cached earlier. When the server applies a default window, appliedTimeRange.endTime comes from the same clock and matches serverTime within a few milliseconds.

Trader and asset identifiers

Numeric IDs and text references are separate parameters: REST accepts comma-separated values or repeated parameters. These requests are the same:
MCP takes arrays: {"assetRefs": ["AAPL", "crypto-btc", "700"]}, {"assetIds": [34, 700]}, or {"traderRefs": ["alpha-trades"]}.
  • A reference is always text. assetRefs=700 looks for the slug, ticker, or symbol 700. It never selects asset ID 700. MCP reference arrays reject numbers, so {"assetRefs": [700]} is invalid. Entities without a slug can still be selected by ID.
  • Use one form per entity. assetIds and assetRefs are mutually exclusive, as are traderIds and traderRefs, even when one is empty. Each entity is independent, so {"traderIds": [7], "assetRefs": ["crypto-btc"]} is valid.
  • Up to 200 entries per field. Entries are counted after splitting commas and trimming whitespace, duplicates included. A field with 201 entries fails validation, REST with 422 and MCP with an input error. Nothing runs and the list is never truncated.
  • Matching is case-insensitive. Asset lookup tries slug, then ticker, then legacy symbol. An ambiguous match at one step fails instead of falling through to the next.
  • An ambiguous reference rejects the request with 422 AMBIGUOUS_IDENTIFIER and the candidates. See Ambiguous identifiers.
  • An unknown reference matches nothing. Other references in the list still apply. If none match, the filter matches nothing. It never widens to all entities.
  • Names and handles are search inputs, not references. Use the search parameter of the trader directory or asset discovery, which can return several matches.
Malformed input, such as a reference containing spaces or a non-positive ID, fails validation. IDs in results and filtersApplied are always numeric.

Filters

Multi-value filters such as traderIds, assetIds, directions, event types, and message ids take comma-separated values or repeated parameters in REST, and arrays in MCP. Values within a filter match any of them. Different filters intersect. Some rows are left out without a placeholder: deleted rows, rows tied to ineligible entities, and rows outside your access. A response that looks narrower than expected may reflect this or the applied time bounds.

Pagination

List reads page forward with limit and cursor:
  • limit accepts up to 200. The partner feed counts source-message groups instead: default 20, maximum 100.
  • Pass meta.nextCursor as cursor to get the next page. Pagination only moves forward.
  • A cursor stays valid if matching rows disappear between requests. Those rows are missing from later pages.
  • Pages reflect the current eligible rows, not a frozen snapshot.
  • When meta.hasMore is true, the result is partial. Fetch more pages, or say the answer is partial.
Rankings and activity summaries are already aggregated and do not paginate. Use them for ranking, count, and trend questions instead of walking pages of raw rows. The partner feed also accepts since for change polling. cursor and since cannot be combined. A feed response can return a nextCursor while hasMore is false, so that token can become the next since.

Time ranges

Feed, events, messages, positions, and generated summaries accept startTime and endTime:
  • With both omitted, the server can apply a bounded default window.
  • An explicit startTime before the accessible range can be moved forward.
  • meta.appliedTimeRange reports the bounds the server used.
What the bounds select depends on the read: Open positions take no time bounds.

Stats reads

Trader stats need exactly one non-empty traderIds or traderRefs. Asset stats need exactly one non-empty assetIds or assetRefs. Neither, both, or an empty selection fails validation. Other filters are optional and follow the same one-form-per-entity rule. Stats remove duplicate selections after validation and return results in the order first requested. Several references that resolve to one entity produce one result. meta.requestedTraderIds, meta.requestedAssetIds, meta.missingTraderIds, and meta.missingAssetIds always contain numbers. For a reference request, requested IDs are the distinct resolved IDs, and missing IDs are resolved IDs with no stats. A reference request also returns meta.requestedTraderRefs and meta.missingTraderRefs, or the asset equivalents. They contain the references as you spelled them, trimmed and with exact duplicates removed. An unknown reference appears in the missing references without a missing ID, because it has no ID. A reference that resolves to an entity with no stats appears in both lists.

Ordering

Each read has a fixed order. There is no sort parameter.
  • Events, messages, the feed, positions, open positions, and generated summaries return the newest first. Feed groups sort by source post time, then Source Message ID. Events in a group sort by event time, then event ID.
  • The trader directory, trader activity, and legacy trader discovery sort by name, case-insensitive, then id.
  • Asset discovery sorts by symbol, case-insensitive, then id.
  • Trader rankings sort by the requested metric, highest first.
  • Activity summaries sort buckets by start time within each group, oldest first.

Prices

Prices are in the quote currency of the asset’s preferred market, given in the nullable quoteSymbol field on position and event rows, such as USDT, USDC, or CAD. Do not assume US dollars. quoteSymbol reflects the asset’s current preferred market, not the market the trade executed on, so treat it as the display currency for the row’s prices. Open-position rows include current marks when pricing is available. Marks are best effort for the request, not audited settlement prices, and have no separate priceAsOf timestamp.
Last modified on October 22, 2026