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. Endpoints, request formats, and response shapes may change. Pin your integration to a specific API version once versioning is available.
The Redbark REST API provides programmatic access to accounts, balances, transactions, connections, and brokerage data. Use it to build integrations, dashboards, or workflows on top of your banking and investment data.

Base URL

https://api.redbark.co

Authentication

All API requests require a Bearer token. Create an API key in the dashboard and include it in the Authorization header:
Authorization: Bearer YOUR_API_KEY
API access requires an active Developer or Professional plan. Trial subscriptions (status: trialing), legacy accounts within their 14-day grace period, and grandfathered accounts also retain API access. You can revoke keys from the dashboard at any time.
Want to connect an AI agent instead? See the MCP Server documentation.
Want to test your parsing code before creating a trial account? See Sample Responses for a coherent set of example JSON payloads covering every endpoint.

Rate limits

Limits are tiered by endpoint cost and applied per API key. Unauthenticated or failed-auth requests are limited to 60 per minute, bucketed by (client IP, first 16 chars of the supplied bearer token) — so probes with different partial keys from the same IP each get their own bucket, but a single probing key+IP combination is throttled before any DB lookup.
TierEndpointsLimit
Cheap/v1/connections, /v1/accounts, /v1/categories60 / minute
Mid/v1/balances30 / minute
Heavy/v1/transactions, /v1/holdings, /v1/trades30 / minute
In addition, heavy endpoints have a per-key concurrency cap of 4 in-flight requests. Calls that arrive while four heavy requests are already in progress on the same key return 429. Issue heavy requests sequentially, or fan them out across multiple keys, to stay under the cap. First-party sync clients identified by user agent (redbark-sure-sync, redbark-actual-sync) use a separate 300 / minute pre-auth bucket keyed only by IP. This is not relevant for third-party integrations but explains why two distinct pre-auth limits exist. Every response includes rate limit headers:
HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetEpoch seconds when the current bucket resets. Emitted on every response so well-behaved clients can pace themselves before hitting 429.
Retry-AfterSeconds until the next request is allowed. Set on 429 responses, and on 503 responses when the per-connection upstream breaker is open.

Truncation and deprecation headers

Some endpoints set additional response headers to signal operational state:
HeaderWhenMeaning
X-Redbark-Truncated: true/v1/transactions, /v1/trades when the service stops paging upstream before exhausting the result setFires for transactions when any of: ~5,000 rows accumulated, or the per-request page cap is hit (50 pages when accountId is omitted, ceil((offset + limit) / 1000) + 1 pages when scoped). Combine with pagination.hasMore and continue paginating with offset + limit.
X-Cache: HIT | MISS | BYPASSEvery response from a cached endpointHIT served from Redis, MISS recomputed and written to Redis, BYPASS cache skipped (non-GET, Redis unavailable, or payload over the cache size limit).
Deprecation: true + Sunset: <date> + Link: <docs-url>; rel="deprecation"A request uses a parameter shape that’s scheduled for removalMigrate before the Sunset date. Currently set on /v1/transactions calls that omit accountId.

Error format

All errors return a JSON envelope:
{
  "error": {
    "message": "Connection not found or does not belong to this user"
  }
}
A 400 validation error includes a details array. Date-validation errors raised by the service layer carry their own message; schema-layer validation failures use the generic "Invalid request parameters" message:
{
  "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)"
    ]
  }
}
{
  "error": {
    "message": "Invalid request parameters",
    "code": "invalid_params",
    "details": [
      "limit: Number must be greater than or equal to 1"
    ]
  }
}
FieldTypeDescription
messagestringError description. Always present.
codestringMachine-readable error code. Omitted when not set.
detailsstring[]Validation details. Omitted when empty.
Stable code values currently emitted:
CodeStatusWhen
invalid_params400Schema validation failure (bad query/body shape)
invalid_date_range400from is after to
from_too_old400from is more than ~7 years ago
wrong_endpoint_for_category400Transactions requested for a brokerage connection, or trades/holdings requested for a banking connection
upstream_bad_request400Banking provider rejected the request with a 4xx (date format, missing scope, etc.); the upstream detail is appended to message
body_too_large413Request body exceeded the 16 KiB limit
missing_authorization401Authorization header is missing
invalid_token401API key or OAuth access token is invalid or expired
professional_required403Brokerage endpoint called by a Developer-plan customer
insufficient_scope403OAuth access token lacks the required scope (e.g. mcp:read)
not_found404Unknown path or method-not-allowed on a known path
connection_not_found404Connection ID does not exist or does not belong to the caller
account_not_found404Account ID does not exist or does not belong to the connection
client_disconnected499Client aborted the request before the response was sent
upstream_breaker_open503Per-connection upstream circuit breaker is open; Retry-After indicates cooldown

HTTP status codes

StatusMeaning
200Success
400Invalid parameters
401Missing or invalid API key
403Subscription required (API access requires a Developer or Professional plan), or professional_required for brokerage endpoints
404Resource not found, or method not allowed on a known path (Hono collapses both to 404)
405MCP only: GET or DELETE on /mcp. The MCP transport is Streamable HTTP POST-only.
413Request body exceeded the 16 KiB limit (code: body_too_large)
429Rate limited (per-IP, per-key, or per-key concurrency cap)
499Client disconnected before the response was sent (code: client_disconnected)
500Internal server error
501Endpoint not implemented for the connection’s provider (e.g. balances on a provider that doesn’t expose them)
503Banking/brokerage provider temporarily unavailable. Retry later. Carries Retry-After when the per-connection upstream circuit breaker is open (code: upstream_breaker_open).

Pagination

List endpoints support limit and offset query parameters:
ParameterTypeDefaultDescription
limitintegerVaries by endpointMaximum number of items to return. Passed as a query string (e.g. ?limit=50).
offsetinteger0Number of items to skip. Passed as a query string.
Paginated responses include a pagination object:
{
  "data": [...],
  "pagination": {
    "total": 142,
    "limit": 50,
    "offset": 0,
    "hasMore": true
  }
}
FieldTypeDescription
totalnumber | nullExact count of matching rows when known. null when the count is unknown — currently emitted by /v1/trades whenever hasMore is true (the count is only known once every page has been fetched), and may also be null on other paginated endpoints when an internal row ceiling is reached without exhausting the set. Use hasMore for next-page detection, not arithmetic on total.
limitnumberEffective page size (may be clamped from the requested value).
offsetnumberOffset that produced this page.
hasMorebooleantrue when at least one more page is available.

Caching

Successful GET responses are cached in Redis per (userId, path, sorted query string). Cache state is exposed on every response via the X-Cache header:
ValueMeaning
HITServed from Redis.
MISSRecomputed; the fresh payload was written to Redis.
BYPASSCache skipped. Emitted on non-GET requests, when Redis is unavailable, or when the serialised payload exceeds the cache size limit.
Per-endpoint TTLs:
EndpointTTL
/v1/categories60 minutes
/v1/connections60 seconds
/v1/accounts60 seconds
/v1/balances5 minutes
/v1/holdings10 minutes
/v1/trades10 minutes
/v1/transactions30 minutes
The cache is GET-only — non-GET requests fall through to the router’s standard 404 {"error":{"message":"Not found","code":"not_found"}} response and carry X-Cache: BYPASS.

Date validation

from and to accept either YYYY-MM-DD (a bare date) or RFC 3339 with an explicit timezone — Z for UTC or ±HH:MM for an offset. Naive datetimes like 2026-05-09T23:35:19 (no Z, no offset) are rejected with a 400 carrying:
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)
This is enforced locally rather than at the upstream provider so callers see a clean 400 instead of a misleading 503.

Upstream provider errors

When the banking provider rejects a request with a 4xx (validation issue we don’t catch locally), the response is surfaced as a 400 with code: upstream_bad_request and message: "Upstream rejected request: <provider detail>". This avoids collapsing caller-input errors into the generic 503 "provider temporarily unavailable". A per-(provider, userId, connectionId) circuit breaker protects /v1/transactions. After 3 upstream failures within a 60-second rolling window, the breaker opens for 60 seconds and subsequent requests for that connection fail fast with a 503, code: upstream_breaker_open, and a Retry-After header. The breaker is in-process per Railway replica, so one tripped replica does not stop other replicas from attempting the upstream.

OpenAPI specification

A machine-readable OpenAPI 3.1 spec is available at:
https://api.redbark.co/openapi.json
Interactive documentation is available at /doc via Swagger UI.

Quick start

1

Get your API key

Go to Settings > API Keys in the dashboard and create a new key. Copy the key. It is only shown once.
2

List your connections

curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.redbark.co/v1/connections
3

List accounts

curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.redbark.co/v1/accounts
4

Get balances

Use account IDs (UUIDs) from step 3:
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.redbark.co/v1/balances?accountIds=a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890,b2c3d4e5-f6a7-8901-b2c3-d4e5f6a78901"
5

Fetch transactions

Use a connectionId (UUID) from step 2:
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.redbark.co/v1/transactions?connectionId=b7c4a1e2-8d3f-4e9a-9c5b-1f2a3e4d5c6b"

Brokerage endpoints

The Holdings and Trades endpoints provide access to investment portfolio data from brokerage connections. These endpoints require a Professional plan subscription.