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

# Sample Responses

> Coherent example JSON responses for every endpoint — use these as fixtures to test your parsing code before you create a trial account

<Info>
  The REST API is in **beta**. Response shapes may change. These samples are kept in sync with the live API; the [OpenAPI spec](https://api.redbark.com/openapi.json) is the authoritative schema.
</Info>

This page provides a full, self-consistent set of example JSON responses that you can paste into your code to test parsing, before you create a trial account or generate an API key.

Every ID below is threaded end-to-end across the endpoints, so you can walk a realistic workflow — list connections, list accounts, fetch balances, transactions, holdings, trades — without making any network calls.

<Tip>
  Every code block on this page has a copy button. Save the JSON as a local fixture file and run your parser against it. Once your parser handles every fixture on this page correctly, sign up and swap in real API calls.
</Tip>

## About the IDs

* **Connection** and **account** IDs are UUIDs generated by Redbark.
* **Transaction** IDs come from the banking provider (Fiskil) and are opaque strings — treat them as arbitrary strings, not UUIDs.
* **Holding** IDs are opaque strings from the brokerage provider (SnapTrade).
* **Trade** IDs are opaque, `snap_`-prefixed strings built deterministically from a hash of core trade attributes, so they stay stable across fetches of the same trade. Treat them as opaque.
* All decimal values (balances, amounts, quantities, prices) are returned as **strings** to preserve precision — parse them with a decimal library, not a float.

## The scenario

Two connections belonging to the same user:

| Connection                             | Institution         | Category    | Accounts                              |
| -------------------------------------- | ------------------- | ----------- | ------------------------------------- |
| `b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b` | Westpac             | `banking`   | 3 (transaction, savings, credit card) |
| `e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b` | Interactive Brokers | `brokerage` | 1 (investment)                        |

## `GET /v1/connections`

Returns every active connection for the authenticated user. Connections with status `deleting` are excluded. Ordered by `createdAt DESC` (most recent first).

```json theme={null}
{
  "data": [
    {
      "id": "e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b",
      "provider": "snaptrade",
      "category": "brokerage",
      "institutionId": "a2c4d6e8-1357-9bdf-2468-ace013579bdf",
      "institutionName": "Interactive Brokers",
      "institutionLogo": "https://cdn.redbark.com/logos/ibkr.png",
      "status": "active",
      "lastRefreshedAt": "2026-04-23T03:00:00.000Z",
      "createdAt": "2026-02-20T14:30:00.000Z"
    },
    {
      "id": "b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b",
      "provider": "fiskil",
      "category": "banking",
      "institutionId": "77",
      "institutionName": "Westpac",
      "institutionLogo": "https://cdn.redbark.com/logos/westpac.png",
      "status": "active",
      "lastRefreshedAt": "2026-04-23T02:30:00.000Z",
      "createdAt": "2026-01-15T10:00:00.000Z"
    }
  ]
}
```

Possible `status` values: `active`, `invalidated`, `pending_mfa`, `revoked`. `institutionLogo` and `lastRefreshedAt` are nullable. `institutionId` is an opaque provider-specific identifier (numeric strings for Fiskil, UUIDs for SnapTrade) — treat it as an arbitrary string. See the [Connections reference](/api-reference/connections).

## `GET /v1/accounts`

Returns every account across both connections in a single paginated response. Ordered alphabetically by account `name` (ASC).

```json theme={null}
{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
      "connectionId": "b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b",
      "provider": "fiskil",
      "name": "Everyday Account",
      "type": "transaction",
      "institutionName": "Westpac",
      "accountNumber": "xxxx4567",
      "currency": "AUD"
    },
    {
      "id": "c3d4e5f6-a7b8-9012-c3d4-e5f6a7b89012",
      "connectionId": "b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b",
      "provider": "fiskil",
      "name": "Low Rate Credit Card",
      "type": "credit-card",
      "institutionName": "Westpac",
      "accountNumber": "xxxx1234",
      "currency": "AUD"
    },
    {
      "id": "b2c3d4e5-f6a7-8901-b2c3-d4e5f6a78901",
      "connectionId": "b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b",
      "provider": "fiskil",
      "name": "Savings Account",
      "type": "savings",
      "institutionName": "Westpac",
      "accountNumber": "xxxx8901",
      "currency": "AUD"
    },
    {
      "id": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "connectionId": "e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b",
      "provider": "snaptrade",
      "name": "Trading Account",
      "type": "investment",
      "institutionName": "Interactive Brokers",
      "accountNumber": "xxxx5566",
      "currency": "USD"
    }
  ],
  "pagination": {
    "total": 4,
    "limit": 50,
    "offset": 0,
    "hasMore": false
  }
}
```

<Tip>
  Possible `type` values: `transaction`, `savings`, `credit-card`, `loan`, `investment`, `term-deposit`, `other`. Note the **hyphen** in `credit-card` (not `credit_card`).
</Tip>

`provider`, `institutionName`, and `accountNumber` are nullable. `accountNumber` is masked to the last 4 digits as `xxxx<last4>`. See the [Accounts reference](/api-reference/accounts).

## `GET /v1/balances?accountIds=...`

Balances for all four accounts. Accepts a comma-separated list of up to **100** account UUIDs. Returned in the order the provider responds (not guaranteed to match the input order).

Request:

```
GET /v1/balances?accountIds=a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890,b2c3d4e5-f6a7-8901-b2c3-d4e5f6a78901,c3d4e5f6-a7b8-9012-c3d4-e5f6a7b89012,d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123
```

Response:

```json theme={null}
{
  "data": [
    {
      "accountId": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
      "currentBalance": "2345.67",
      "availableBalance": "2345.67",
      "currency": "AUD"
    },
    {
      "accountId": "b2c3d4e5-f6a7-8901-b2c3-d4e5f6a78901",
      "currentBalance": "18750.00",
      "availableBalance": "18750.00",
      "currency": "AUD"
    },
    {
      "accountId": "c3d4e5f6-a7b8-9012-c3d4-e5f6a7b89012",
      "currentBalance": "-842.15",
      "availableBalance": "4157.85",
      "currency": "AUD"
    },
    {
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "currentBalance": "6420.50",
      "availableBalance": "6420.50",
      "currency": "USD"
    }
  ]
}
```

<Tip>
  `currentBalance`, `availableBalance`, and `currency` are all **nullable**. If the provider call for a given account fails, those three fields come back as `null` for that account. Parsers must handle the null case.
</Tip>

`currentBalance` can be negative (e.g. credit cards, overdrawn accounts). See the [Balances reference](/api-reference/balances).

## `GET /v1/transactions?connectionId=...`

Since the 2026-06-30 sunset, `accountId` is **required**: a call with only `connectionId` returns `410 account_id_required`. Make one request per account and merge the results client-side. The combined response below covers the three Westpac accounts for the default 30-day window (one call each). Only transactions with status `posted` are returned; pending transactions are filtered out upstream at the provider.

Request (repeat once per account):

```
GET /v1/transactions?connectionId=b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b&accountId=a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890
```

Response:

```json theme={null}
{
  "data": [
    {
      "id": "e4a7f91b2c3d4e5f6a7b8c9d",
      "accountId": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
      "accountName": "Everyday Account",
      "status": "posted",
      "date": "2026-04-22",
      "datetime": "2026-04-21T23:14:00.000Z",
      "postDate": "2026-04-22",
      "postDatetime": "2026-04-22T03:00:00.000Z",
      "valueDate": "2026-04-22",
      "valueDatetime": "2026-04-22T03:00:00.000Z",
      "description": "Woolworths Sydney CBD",
      "amount": "-64.20",
      "direction": "debit",
      "category": "FOOD_AND_DRINK",
      "merchantName": "Woolworths",
      "merchantCategoryCode": "5411"
    },
    {
      "id": "f5b8a02c3d4e5f6a7b8c9d0e",
      "accountId": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
      "accountName": "Everyday Account",
      "status": "posted",
      "date": "2026-04-21",
      "datetime": "2026-04-21T02:00:00.000Z",
      "postDate": "2026-04-21",
      "postDatetime": "2026-04-21T02:00:00.000Z",
      "valueDate": "2026-04-21",
      "valueDatetime": "2026-04-21T02:00:00.000Z",
      "description": "TFR FROM SAVINGS",
      "amount": "500.00",
      "direction": "credit",
      "category": "TRANSFER_IN",
      "merchantName": null,
      "merchantCategoryCode": null
    },
    {
      "id": "a6c9b13d4e5f6a7b8c9d0e1f",
      "accountId": "b2c3d4e5-f6a7-8901-b2c3-d4e5f6a78901",
      "accountName": "Savings Account",
      "status": "posted",
      "date": "2026-04-21",
      "datetime": "2026-04-21T02:00:00.000Z",
      "postDate": "2026-04-21",
      "postDatetime": "2026-04-21T02:00:00.000Z",
      "valueDate": "2026-04-21",
      "valueDatetime": "2026-04-21T02:00:00.000Z",
      "description": "TFR TO EVERYDAY",
      "amount": "-500.00",
      "direction": "debit",
      "category": "TRANSFER_OUT",
      "merchantName": null,
      "merchantCategoryCode": null
    },
    {
      "id": "b7d0c24e5f6a7b8c9d0e1f2a",
      "accountId": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
      "accountName": "Everyday Account",
      "status": "posted",
      "date": "2026-04-18",
      "datetime": "2026-04-17T23:00:00.000Z",
      "postDate": "2026-04-18",
      "postDatetime": "2026-04-18T00:00:00.000Z",
      "valueDate": "2026-04-18",
      "valueDatetime": "2026-04-18T00:00:00.000Z",
      "description": "ACME CORP SALARY",
      "amount": "4250.00",
      "direction": "credit",
      "category": "INCOME",
      "merchantName": null,
      "merchantCategoryCode": null
    },
    {
      "id": "c8e1d35f6a7b8c9d0e1f2a3b",
      "accountId": "c3d4e5f6-a7b8-9012-c3d4-e5f6a7b89012",
      "accountName": "Low Rate Credit Card",
      "status": "posted",
      "date": "2026-04-15",
      "datetime": "2026-04-14T22:45:00.000Z",
      "postDate": "2026-04-16",
      "postDatetime": "2026-04-16T04:00:00.000Z",
      "valueDate": null,
      "valueDatetime": null,
      "description": "Qantas Airways 08129933412",
      "amount": "-412.50",
      "direction": "debit",
      "category": "TRAVEL",
      "merchantName": "Qantas",
      "merchantCategoryCode": "4511"
    },
    {
      "id": "d9f2e46a7b8c9d0e1f2a3b4c",
      "accountId": "c3d4e5f6-a7b8-9012-c3d4-e5f6a7b89012",
      "accountName": "Low Rate Credit Card",
      "status": "posted",
      "date": "2026-04-12",
      "datetime": "2026-04-12T04:15:00.000Z",
      "postDate": "2026-04-13",
      "postDatetime": "2026-04-13T02:00:00.000Z",
      "valueDate": null,
      "valueDatetime": null,
      "description": "Netflix.com",
      "amount": "-22.99",
      "direction": "debit",
      "category": "ENTERTAINMENT",
      "merchantName": "Netflix",
      "merchantCategoryCode": "4899"
    },
    {
      "id": "e0a3f57b8c9d0e1f2a3b4c5d",
      "accountId": "b2c3d4e5-f6a7-8901-b2c3-d4e5f6a78901",
      "accountName": "Savings Account",
      "status": "posted",
      "date": "2026-04-01",
      "datetime": "2026-04-01T00:01:00.000Z",
      "postDate": "2026-04-01",
      "postDatetime": "2026-04-01T00:01:00.000Z",
      "valueDate": "2026-04-01",
      "valueDatetime": "2026-04-01T00:01:00.000Z",
      "description": "INTEREST CREDIT",
      "amount": "62.18",
      "direction": "credit",
      "category": "INCOME",
      "merchantName": null,
      "merchantCategoryCode": null
    }
  ],
  "pagination": {
    "total": 7,
    "limit": 200,
    "offset": 0,
    "hasMore": false
  }
}
```

<Tip>
  The `category` field returns the **raw CDR primary-category code** (uppercase, underscored) exactly as supplied by the banking provider — not a human-readable label. Possible values: `BANK_FEES`, `ENTERTAINMENT`, `FOOD_AND_DRINK`, `GOVERNMENT_AND_NON_PROFIT`, `HOME_IMPROVEMENT`, `INCOME`, `LOAN_PAYMENTS`, `MEDICAL`, `MERCHANDISE`, `PERSONAL_CARE`, `RENT_AND_UTILITIES`, `SERVICES`, `TRANSFER_IN`, `TRANSFER_OUT`, `TRANSPORTATION`, `TRAVEL`. Not all transactions have a category — the field is nullable.
</Tip>

<Tip>
  `amount` is a signed decimal string (negative for debits, positive for credits). `direction` is a convenience field: `"credit"` or `"debit"`. Each transaction can carry three dates: `date`/`datetime` (the transaction/execution date, in your account timezone set in [Settings](https://app.redbark.com/settings) and as a raw ISO 8601 timestamp), `postDate`/`postDatetime` (the posting/booking date that shows on your statement), and `valueDate`/`valueDatetime` (the value date, when funds clear). Key off `postDate` when reconciling against a bank's running balance. `postDate` and `valueDate` are `null` when the provider omits them.
</Tip>

See the [Transactions reference](/api-reference/transactions).

## `GET /v1/holdings?connectionId=...`

Holdings for the Interactive Brokers trading account. Holdings are only available on **brokerage** connections and require a **Professional plan**. Requesting holdings for a banking connection returns `400`.

Request:

```
GET /v1/holdings?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b
```

Response:

```json theme={null}
{
  "data": [
    {
      "id": "abc123def456ghi789jkl012",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "VOO",
      "name": "Vanguard S&P 500 ETF",
      "exchange": "NYSEARCA",
      "currency": "USD",
      "quantity": "40.0000",
      "averagePrice": "412.80",
      "currentPrice": "468.15",
      "marketValue": "18726.00",
      "unrealizedPnl": "2214.00"
    },
    {
      "id": "mno345pqr678stu901vwx234",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "AAPL",
      "name": "Apple Inc.",
      "exchange": "NASDAQ",
      "currency": "USD",
      "quantity": "25.0000",
      "averagePrice": "178.20",
      "currentPrice": "195.40",
      "marketValue": "4885.00",
      "unrealizedPnl": "430.00"
    },
    {
      "id": "yz5678abc901def234ghi567",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "VAS.AX",
      "name": "Vanguard Australian Shares ETF",
      "exchange": "ASX",
      "currency": "AUD",
      "quantity": "150.0000",
      "averagePrice": "85.50",
      "currentPrice": "92.30",
      "marketValue": "13845.00",
      "unrealizedPnl": "1020.00"
    }
  ]
}
```

<Tip>
  `name`, `exchange`, `averagePrice`, `currentPrice`, `marketValue`, and `unrealizedPnl` are all **nullable** — they depend on what the brokerage surfaces. Only `symbol`, `currency`, and `quantity` are guaranteed.
</Tip>

See the [Holdings reference](/api-reference/holdings).

## `GET /v1/trades?connectionId=...`

Trades on the IBKR account. `pagination.total` is `null` when `hasMore` is `true` (the total is only known once every page has been fetched). When `hasMore` is `false`, `total` is the exact count of returned trades.

Request:

```
GET /v1/trades?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b
```

Response:

```json theme={null}
{
  "data": [
    {
      "id": "snap_5e0b9c14a7f2d836e0b1c4a2",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "VOO",
      "name": "Vanguard S&P 500 ETF",
      "type": "buy",
      "quantity": "10",
      "price": "465.2",
      "currency": "USD",
      "totalAmount": "4652",
      "fees": "1",
      "tradeDate": "2026-04-15",
      "settlementDate": "2026-04-17",
      "description": null
    },
    {
      "id": "snap_9d3a1f60c85b47e2a0f1b3c6",
      "accountId": "d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123",
      "accountName": "Trading Account",
      "symbol": "AAPL",
      "name": "Apple Inc.",
      "type": "sell",
      "quantity": "5",
      "price": "192.8",
      "currency": "USD",
      "totalAmount": "964",
      "fees": "1",
      "tradeDate": "2026-03-28",
      "settlementDate": "2026-04-01",
      "description": null
    }
  ],
  "pagination": {
    "total": 2,
    "limit": 200,
    "offset": 0,
    "hasMore": false
  }
}
```

<Tip>
  `type` is one of: `buy`, `sell`, `dividend`, `split`, `transfer`, `fee`, `interest`, `other`. Trade IDs are opaque, `snap_`-prefixed deterministic strings (a hash over core trade attributes, stable across fetches); treat them as opaque. `name`, `fees`, `settlementDate`, and `description` are nullable.
</Tip>

See the [Trades reference](/api-reference/trades).

## Error responses

All errors return the same envelope regardless of endpoint:

```json theme={null}
{
  "error": {
    "message": "Connection not found or does not belong to this user"
  }
}
```

`code` and `details` are optional and omitted entirely when not set — the server never emits `"code": null` or `"details": []`. The server emits a stable set of machine-readable codes (`professional_required`, `invalid_params`, `connection_not_found`, `account_not_found`, `upstream_bad_request`, `upstream_breaker_open`, `client_disconnected`, and others) — see the [Overview](/api-reference/overview#error-format) for the full list. A `400` validation error on transactions includes `details`:

```json theme={null}
{
  "error": {
    "message": "Invalid date parameters",
    "details": [
      "from: Must be a valid ISO 8601 date string (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ssZ)"
    ]
  }
}
```

A `429` rate-limit error is accompanied by a `Retry-After` response header (seconds):

```json theme={null}
{
  "error": {
    "message": "Too many requests"
  }
}
```

See the [Overview](/api-reference/overview#error-format) for the full list of status codes.

## Webhook payload (`transactions.synced`)

If you're building a webhook destination consumer, here's the envelope sent when a bank transaction sync completes. Payload formatting differs significantly from the REST API — notably, **amounts are integers in the smallest currency unit** (e.g. cents), all field names use **snake\_case**, and timestamps in the envelope are **Unix epoch seconds**.

```json theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "object": "event",
  "type": "transactions.synced",
  "api_version": "2026-03-15",
  "created": 1745277600,
  "data": {
    "new": [
      {
        "id": "e4a7f91b2c3d4e5f6a7b8c9d",
        "object": "transaction",
        "amount": -6420,
        "currency": "aud",
        "status": "posted",
        "description": "Woolworths Sydney CBD",
        "direction": "debit",
        "class": "payment",
        "account_id": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
        "account_name": "Everyday Account",
        "account": "Everyday Account",
        "local_date": "2026-04-22",
        "transaction_date": "2026-04-21T23:14:00.000Z",
        "post_date": "2026-04-21T23:14:00.000Z",
        "merchant_name": "Woolworths",
        "category": "FOOD_AND_DRINK",
        "merchant_category_code": "5411",
        "reference": null,
        "extended_description": null
      }
    ],
    "updated": []
  },
  "metadata": {
    "sync_run_id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
    "new_count": 1,
    "updated_count": 0,
    "chunk": 1,
    "total_chunks": 1
  }
}
```

Brokerage syncs produce `trades.synced` events with the same envelope but trade objects in `data.new`; quantities, prices, and fees are decimal strings (not integers) to preserve precision for fractional shares. `metadata.sync_run_id` is a UUID for the sync run that produced the delivery, but is `null` when a delivery is replayed outside a sync run. See the [Webhooks reference](/api-reference/webhooks) for payload fields, signature verification (HMAC-SHA256), chunking behaviour, and retry schedule.

## Next steps

* Validate your parser against every response above.
* Pull the [OpenAPI 3.1 spec](https://api.redbark.com/openapi.json) and generate a typed client, or drive contract tests off it.
* When you're ready, [create an API key](https://app.redbark.com/settings) and swap fixtures for real calls.
