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 posted transactions for a given connection. Transactions are fetched live from the banking provider. No transaction data is stored on Redbark servers.
Request
| Header | Required | Description |
|---|
Authorization | Yes | Bearer YOUR_API_KEY |
Trialing customers retain full API access (including brokerage endpoints if their trial plan is Professional).
| Header | Description |
|---|
X-Cache | HIT, MISS, or BYPASS. Set unconditionally by the cache layer; useful for debugging stale data and tuning poll frequency. |
X-Redbark-Truncated | true if the row ceiling fired (see Response limits). |
Deprecation / Sunset | Present when accountId is omitted (see Tip above). |
Caching
Responses are cached at the edge for 30 minutes. Cache key is userId + path + sorted query string, so different orderings of query parameters produce different cache entries.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|
connectionId | string | Yes | | Connection to fetch transactions from |
accountId | string | No | All accounts | Filter to a specific account |
from | string | No | 30 days ago | Start date (YYYY-MM-DD or ISO 8601) |
to | string | No | Now | 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 |
connectionId is required. Use the List Connections endpoint to get connection IDs.
Pass accountId whenever you can. It scopes the upstream provider call to a single account, which is faster, cheaper, and keeps you on the supported call shape. Calls that omit accountId currently return Deprecation: true and Sunset: Wed, 01 Sep 2027 00:00:00 GMT response headers — they still work, but plan to migrate before that date.
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 a lower bound rather than the exact count.
- Continue paginating with the next
offset + limit window — the same cap applies per request, not per session.
When accountId is omitted, the service additionally caps at 50 upstream provider pages. Because each page is filtered client-side to the accounts on this connection, this is a different truncation path that can trigger X-Redbark-Truncated: true at modest row counts on connections with many sibling accounts. Pass accountId to avoid it.
Response
{
"data": [
{
"id": "e4a7f91b2c3d4e5f6a7b8c9d",
"accountId": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
"accountName": "Everyday Account",
"status": "posted",
"date": "2026-03-12",
"datetime": "2026-03-11T13:00:00.000Z",
"description": "Woolworths Sydney",
"amount": "-45.50",
"direction": "debit",
"category": "FOOD_AND_DRINK",
"merchantName": "Woolworths",
"merchantCategoryCode": null
},
{
"id": "f5b8a02c3d4e5f6a7b8c9d0e",
"accountId": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
"accountName": "Everyday Account",
"status": "posted",
"date": "2026-03-11",
"datetime": "2026-03-10T13:00:00.000Z",
"description": "Salary Payment",
"amount": "3500.00",
"direction": "credit",
"category": "INCOME",
"merchantName": null,
"merchantCategoryCode": null
}
],
"pagination": {
"total": 87,
"limit": 200,
"offset": 0,
"hasMore": false
}
}
Transaction object
| Field | Type | Description |
|---|
id | string | Opaque transaction identifier from the banking provider. Treat as an arbitrary string. |
accountId | string | UUID of the account this transaction belongs to |
accountName | string | Account display name |
status | string | "posted". The service requests only posted transactions from the provider — pending transactions are not returned by this endpoint. The response schema permits any string up to 64 chars, but "posted" is the only value emitted today. |
date | string | Transaction date in your account’s timezone (YYYY-MM-DD). Defaults to Australia/Sydney if no timezone is set. Change your timezone in Settings. |
datetime | string | null | Raw ISO 8601 timestamp from the banking provider. Use this if you need to handle timezone conversion yourself. |
description | string | Transaction description |
amount | string | Signed decimal string (e.g. "-45.50"). Negative for debits, positive for credits. |
direction | string | "credit" or "debit" (convenience field matching the sign of amount) |
category | string | null | Raw CDR primary-category code (see list below). Not all transactions have a category. |
merchantName | string | null | Merchant name, if available |
merchantCategoryCode | string | null | Merchant category code (MCC), if available |
The amount field is a string to preserve decimal precision. Parse it as a decimal in your application — not a float.
Categories
The category field returns the raw CDR primary-category code (uppercase, underscored) as assigned by the banking provider — not a human-readable label. Not all transactions have a category (the field is nullable).
category value | Human-readable label |
|---|
BANK_FEES | Bank Fees |
ENTERTAINMENT | Entertainment |
FOOD_AND_DRINK | Food & Drink |
GOVERNMENT_AND_NON_PROFIT | Government & Non-Profit |
HOME_IMPROVEMENT | Home Improvement |
INCOME | Income |
LOAN_PAYMENTS | Loan Payments |
MEDICAL | Medical |
MERCHANDISE | Merchandise |
PERSONAL_CARE | Personal Care |
RENT_AND_UTILITIES | Rent & Utilities |
SERVICES | Services |
TRANSFER_IN | Transfer In |
TRANSFER_OUT | Transfer Out |
TRANSPORTATION | Transportation |
TRAVEL | Travel |
Fetch this mapping programmatically from GET /v1/categories.
Categories depend on the banking provider and account type. Some transactions (e.g. direct debits, older transactions) may have a null category.
| Field | Type | Description |
|---|
total | integer | null | Count of posted transactions seen by the service for the filters. When hasMore is true the service may have stopped paging early, so total is a lower bound (and may be null if the count is unknown). When hasMore is false, total is exact. |
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 | invalid_params | Missing connectionId |
400 | (none) | Invalid date format (details[] lists the offending fields) |
400 | invalid_date_range | Invalid date range: frommust be on or beforeto“ |
400 | from_too_old | `from` is too far in the past — banking providers serve at most ~7 years of history |
400 | wrong_endpoint_for_category | Transactions are only available for banking connections — use /v1/trades for brokerage connections |
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) | Banking provider temporarily unavailable. Retry-After: 30. |
503 | upstream_breaker_open | After 3 upstream failures within a 60s window for the same userId+connectionId, subsequent requests fail fast for ~60s. Retry-After reflects the remaining cooldown. |
Example error body:
{
"error": {
"message": "`from` is too far in the past — banking providers serve at most ~7 years of history",
"code": "from_too_old"
}
}
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 transactions for a connection (last 30 days)
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.redbark.co/v1/transactions?connectionId=b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b"
Filter by account and date range
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.redbark.co/v1/transactions?connectionId=b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b&accountId=a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890&from=2026-01-01&to=2026-03-01"
Paginate
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.redbark.co/v1/transactions?connectionId=b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b&limit=50&offset=50"
Python: fetch all pages
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://api.redbark.co"
all_transactions = []
offset = 0
limit = 200
while True:
resp = requests.get(
f"{BASE}/v1/transactions",
headers={"Authorization": f"Bearer {API_KEY}"},
params={
"connectionId": "b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b",
"from": "2026-01-01",
"to": "2026-03-13",
"limit": limit,
"offset": offset,
},
)
data = resp.json()
all_transactions.extend(data["data"])
if not data["pagination"]["hasMore"]:
break
offset += limit
print(f"Fetched {len(all_transactions)} transactions")
JavaScript: fetch all pages
const API_KEY = "YOUR_API_KEY";
const BASE = "https://api.redbark.co";
const allTransactions = [];
let offset = 0;
const limit = 200;
while (true) {
const params = new URLSearchParams({
connectionId: "conn_abc123",
from: "2026-01-01",
to: "2026-03-13",
limit: String(limit),
offset: String(offset),
});
const resp = await fetch(`${BASE}/v1/transactions?${params}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { data, pagination } = await resp.json();
allTransactions.push(...data);
if (!pagination.hasMore) break;
offset += limit;
}
console.log(`Fetched ${allTransactions.length} transactions`);