Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.redbark.co/llms.txt

Use this file to discover all available pages before exploring further.

The REST API is in beta. This endpoint’s response shape may change.
Returns a paginated list of trades for a brokerage connection. Trades are fetched live from the brokerage provider. No investment data is stored on Redbark servers.
This endpoint requires a Professional plan subscription. Saver-plan API keys get a generic 403 (API access requires a Developer or Professional plan). Developer-plan keys get a 403 with "code": "professional_required" specifically for this endpoint.

Request

GET /v1/trades

Headers

HeaderRequiredDescription
AuthorizationYesBearer YOUR_API_KEY
Trialing customers retain general API access but do not receive brokerage access. The brokerage entitlement requires an active (or past_due) subscription on a Professional price — a trialing Professional subscription returns a 403 professional_required on /holdings and /trades.

Response headers

HeaderDescription
X-CacheHIT, MISS, or BYPASS. Set unconditionally by the cache layer; useful for debugging stale data and tuning poll frequency.
X-Redbark-Truncatedtrue if the row ceiling fired (see Response limits).

Query parameters

ParameterTypeRequiredDefaultDescription
connectionIdstringYesBrokerage connection to fetch trades from
accountIdstringNoAll accountsFilter to a specific brokerage account
accountIdsstringNoAll accountsComma-separated subset of brokerage account UUIDs on the connection (max 4 000 chars). Takes precedence over accountId when both are passed. Any id not on the connection is a 404.
fromstringNo(provider default)Start date (YYYY-MM-DD or ISO 8601). No from is passed through to the brokerage provider as-is; SnapTrade’s behaviour without from depends on the underlying broker.
tostringNo(provider default)End date (YYYY-MM-DD or ISO 8601)
limitintegerNo200Maximum items to return (1 to 500)
offsetintegerNo0Number of items to skip
connectionId must refer to a brokerage connection. Passing a banking connection ID returns a 400 error. Use the List Connections endpoint to find your brokerage connection IDs.

Response limits

To bound memory under wide date ranges, the service stops fetching upstream pages once it has roughly 5,000 matching rows for a single request. When this happens:
  • The response sets X-Redbark-Truncated: true.
  • pagination.hasMore is true and pagination.total is null (the exact total isn’t known when paging stops early).
  • Continue paginating with the next offset + limit window — the same cap applies per request, not per session.

Response

Cached at the edge for 10 minutes. Cache key is userId + path + sorted query string, so different orderings of query parameters (or different deduplications of accountIds) produce different cache entries.
{
  "data": [
    {
      "id": "2026-03-15-VAS.AX-BUY-4487.5-50-2026-03-17-9.5-",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "VAS.AX",
      "name": "Vanguard Australian Shares ETF",
      "type": "buy",
      "quantity": "50",
      "price": "89.75",
      "currency": "AUD",
      "totalAmount": "4487.5",
      "fees": "9.5",
      "tradeDate": "2026-03-15",
      "settlementDate": "2026-03-17",
      "description": null
    },
    {
      "id": "2026-03-10-CBA.AX-SELL-2846-20-2026-03-12-9.5-",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "CBA.AX",
      "name": "Commonwealth Bank of Australia",
      "type": "sell",
      "quantity": "20",
      "price": "142.3",
      "currency": "AUD",
      "totalAmount": "2846",
      "fees": "9.5",
      "tradeDate": "2026-03-10",
      "settlementDate": "2026-03-12",
      "description": null
    }
  ],
  "pagination": {
    "total": null,
    "limit": 200,
    "offset": 0,
    "hasMore": true
  }
}

Trade object

FieldTypeDescription
idstringDeterministic trade identifier built from tradeDate-symbol-TYPE-totalAmount-quantity-settlementDate-fees-description. Treat as an opaque string — the format is not a stable API contract.
accountIdstringUUID of the brokerage account
accountNamestringAccount display name
symbolstringTicker symbol (e.g. VAS.AX, AAPL)
namestring | nullSecurity name
typestringOne of "buy", "sell", "dividend", "split", "transfer", "fee", "interest", or "other"
quantitystringNumber of units traded (decimal string; supports fractional shares)
pricestringPrice per unit at execution
currencystringCurrency code (e.g. AUD, USD)
totalAmountstringTotal value of the trade
feesstring | nullBrokerage fees charged
tradeDatestringDate or ISO 8601 timestamp when the trade executed — the provider passes through whatever SnapTrade returns in trade_date. May be a date-only string (YYYY-MM-DD) or a full ISO datetime depending on the broker.
settlementDatestring | nullSettlement date/timestamp — same format caveat as tradeDate
descriptionstring | nullAdditional description from the broker, if any
All monetary and quantity fields are strings to preserve decimal precision. Parse them as decimals in your application.

Pagination object

FieldTypeDescription
totalinteger | nullTotal number of matching trades. Returns null when hasMore is true (the total is not known until all pages have been fetched). When hasMore is false, total is the exact count.
limitintegerLimit applied to this request
offsetintegerOffset applied to this request
hasMorebooleantrue if more items exist beyond this page

Error responses

Errors use the standard envelope { "error": { "message": string, "code"?: string, "details"?: string[] } }. The optional code field is set for the structured cases below — clients should branch on code rather than parsing message.
StatuscodeWhen
400invalid_paramsMissing connectionId
400(none)Invalid date format (details[] lists the offending fields)
400invalid_date_rangeInvalid date range: frommust be on or beforeto“
400wrong_endpoint_for_categoryTrades are only available for brokerage connections (passed a banking connection)
403(none)API access requires a Developer or Professional plan (Saver-plan keys)
403professional_requiredDeveloper-plan key hitting a brokerage endpoint
404connection_not_found / account_not_foundConnection or account not found, or does not belong to you
429(none)Rate limit exceeded — heavy bucket is 30/min per API key, plus a per-key cap of 4 concurrent in-flight requests (excess returns Too many concurrent requests). See Retry-After and X-RateLimit-Reset.
503(none)Brokerage provider temporarily unavailable. Retry later.
Example error body:
{
  "error": {
    "message": "Trades are only available for brokerage connections",
    "code": "wrong_endpoint_for_category"
  }
}

Date validation

The from and to parameters accept:
  • Date strings: 2026-03-01
  • Full ISO 8601 / RFC 3339 with explicit timezone: 2026-03-01T00:00:00Z or 2026-03-01T00:00:00+10:00
Naive datetimes with no Z and no ±HH:MM offset are explicitly rejected. Invalid formats return a 400 with details:
{
  "error": {
    "message": "Invalid date parameters",
    "details": [
      "from: Must be YYYY-MM-DD or RFC3339 with timezone (e.g. 2026-05-09T23:35:19Z or 2026-05-09T23:35:19+10:00)"
    ]
  }
}

Examples

All trades for a connection

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.redbark.co/v1/trades?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b"

Filter by date range

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.redbark.co/v1/trades?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b&from=2026-01-01&to=2026-03-31"

Paginate

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.redbark.co/v1/trades?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b&limit=50&offset=50"

Python: fetch all pages

import requests

API_KEY = "YOUR_API_KEY"
BASE = "https://api.redbark.co"

all_trades = []
offset = 0
limit = 200

while True:
    resp = requests.get(
        f"{BASE}/v1/trades",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params={
            "connectionId": "e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b",
            "from": "2026-01-01",
            "to": "2026-03-31",
            "limit": limit,
            "offset": offset,
        },
    )
    data = resp.json()
    all_trades.extend(data["data"])

    if not data["pagination"]["hasMore"]:
        break
    offset += limit

print(f"Fetched {len(all_trades)} trades")

JavaScript: fetch all pages

const API_KEY = "YOUR_API_KEY";
const BASE = "https://api.redbark.co";

const allTrades = [];
let offset = 0;
const limit = 200;

while (true) {
  const params = new URLSearchParams({
    connectionId: "conn_abc123",
    from: "2026-01-01",
    to: "2026-03-31",
    limit: String(limit),
    offset: String(offset),
  });

  const resp = await fetch(`${BASE}/v1/trades?${params}`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
  const { data, pagination } = await resp.json();

  allTrades.push(...data);

  if (!pagination.hasMore) break;
  offset += limit;
}

console.log(`Fetched ${allTrades.length} trades`);