> ## Documentation Index
> Fetch the complete documentation index at: https://docs.redbark.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List Trades

> Retrieve trade history for a brokerage connection with date filters and pagination

<Info>
  The REST API is in **beta**. This endpoint's response shape may change.
</Info>

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.

<Warning>
  This endpoint requires brokerage access. Trialing subscriptions on any plan receive full brokerage access. Outside a trial, brokerage access requires an `active` (or `past_due`) subscription on a **Professional** price. A key with no general API access (for example a Saver-plan key) gets a `403` with `"code": "plan_upgrade_required"`. A Developer-plan key that has API access but not brokerage gets a `403` with `"code": "professional_required"` on this endpoint.
</Warning>

## Request

```
GET /v1/trades
```

### Headers

| Header          | Required | Description           |
| --------------- | -------- | --------------------- |
| `Authorization` | Yes      | `Bearer YOUR_API_KEY` |

Trialing subscriptions on any plan receive full brokerage access, so you can evaluate `/holdings` and `/trades` during a trial. Outside a trial, brokerage access requires an `active` (or `past_due`) subscription on a Professional price.

### Query parameters

| Parameter      | Type      | Required | Default              | Description                                                                                                                                                                             |
| -------------- | --------- | -------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `connectionId` | `string`  | Yes      |                      | Brokerage connection to fetch trades from                                                                                                                                               |
| `accountId`    | `string`  | No       | All accounts         | Filter to a specific brokerage account                                                                                                                                                  |
| `accountIds`   | `string`  | No       | All accounts         | Comma-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`. |
| `from`         | `string`  | No       | *(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.              |
| `to`           | `string`  | No       | *(provider default)* | End date (`YYYY-MM-DD` or ISO 8601)                                                                                                                                                     |
| `limit`        | `integer` | No       | `200`                | Maximum items to return (1 to 500)                                                                                                                                                      |
| `offset`       | `integer` | No       | `0`                  | Number of items to skip                                                                                                                                                                 |

<Info>
  `connectionId` must refer to a brokerage connection. Passing a banking connection ID returns a `400` error. Use the [List Connections](/api-reference/connections) endpoint to find your brokerage connection IDs.
</Info>

### 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:

* `pagination.hasMore` is `true` and `pagination.total` is `null` (the exact total isn't known when paging stops early). There is no dedicated header for this; the row ceiling surfaces only through the pagination fields.
* Continue paginating with the next `offset + limit` window. The same cap applies per request, not per session.

## Response

Responses are not cached; every request fetches live from the brokerage provider.

```json theme={null}
{
  "data": [
    {
      "id": "snap_a1f4c7e0b93d26584f0c1a2b",
      "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": "snap_7c2e9b04a15f38d6e2b0c4a9",
      "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

| Field            | Type             | Description                                                                                                                                                                                                                                                                                             |
| ---------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`             | `string`         | Opaque, `snap_`-prefixed deterministic trade identifier. It is a hash over a canonical subset of trade attributes (trade date, symbol, type, units, price, amount), so it stays stable across fetches of the same trade. Treat it as an opaque string; the internal shape is not a stable API contract. |
| `accountId`      | `string`         | UUID of the brokerage account                                                                                                                                                                                                                                                                           |
| `accountName`    | `string`         | Account display name                                                                                                                                                                                                                                                                                    |
| `symbol`         | `string`         | Ticker symbol (e.g. `VAS.AX`, `AAPL`)                                                                                                                                                                                                                                                                   |
| `name`           | `string \| null` | Security name                                                                                                                                                                                                                                                                                           |
| `type`           | `string`         | One of `"buy"`, `"sell"`, `"dividend"`, `"split"`, `"transfer"`, `"fee"`, `"interest"`, or `"other"`                                                                                                                                                                                                    |
| `quantity`       | `string`         | Number of units traded (decimal string; supports fractional shares)                                                                                                                                                                                                                                     |
| `price`          | `string`         | Price per unit at execution                                                                                                                                                                                                                                                                             |
| `currency`       | `string`         | Currency code (e.g. `AUD`, `USD`)                                                                                                                                                                                                                                                                       |
| `totalAmount`    | `string`         | Total value of the trade                                                                                                                                                                                                                                                                                |
| `fees`           | `string \| null` | Brokerage fees charged                                                                                                                                                                                                                                                                                  |
| `tradeDate`      | `string`         | Date 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.                                                                                   |
| `settlementDate` | `string \| null` | Settlement date/timestamp — same format caveat as `tradeDate`                                                                                                                                                                                                                                           |
| `description`    | `string \| null` | Additional description from the broker, if any                                                                                                                                                                                                                                                          |

<Tip>
  All monetary and quantity fields are strings to preserve decimal precision. Parse them as decimals in your application.
</Tip>

### Pagination object

| Field     | Type              | Description                                                                                                                                                                                 |
| --------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `total`   | `integer \| null` | Total 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. |
| `limit`   | `integer`         | Limit applied to this request                                                                                                                                                               |
| `offset`  | `integer`         | Offset applied to this request                                                                                                                                                              |
| `hasMore` | `boolean`         | `true` 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`.

| Status | `code`                                       | When                                                                                                                                                                                                                |
| ------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | *(none)*                                     | `Invalid request parameters` (missing `connectionId`; schema validation, offending fields in `details[]`)                                                                                                           |
| `400`  | *(none)*                                     | Invalid date format (`details[]` lists the offending fields)                                                                                                                                                        |
| `400`  | `invalid_date_range`                         | `Invalid date range: `from`must be on or before`to\`\`                                                                                                                                                              |
| `400`  | `wrong_endpoint_for_category`                | `Trades are only available for brokerage connections` (passed a banking connection)                                                                                                                                 |
| `403`  | `plan_upgrade_required`                      | `Your plan does not include API access. The Redbark API and MCP server require the Developer or Professional plan (this is a plan limit, not a credentials issue)...` (keys with no API access, e.g. Saver plan)    |
| `403`  | `professional_required`                      | Developer-plan key hitting a brokerage endpoint                                                                                                                                                                     |
| `404`  | `connection_not_found` / `account_not_found` | Connection 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:

```json theme={null}
{
  "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:

```json theme={null}
{
  "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

```bash theme={null}
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.redbark.com/v1/trades?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b"
```

### Filter by date range

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

### Paginate

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

### Python: fetch all pages

```python theme={null}
import requests

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

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

```javascript theme={null}
const API_KEY = "YOUR_API_KEY";
const BASE = "https://api.redbark.com";

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`);
```
