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 list of current holdings for a brokerage connection. Holdings 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
| Header | Required | Description |
|---|
Authorization | Yes | Bearer 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.
| Header | Description |
|---|
X-Cache | HIT, MISS, or BYPASS. Set unconditionally by the cache layer; useful for debugging stale data and tuning poll frequency. |
Query parameters
| Parameter | Type | Required | Description |
|---|
connectionId | string | Yes | Brokerage connection to fetch holdings from |
accountId | string | No | Filter to a specific brokerage account. Defaults to all accounts on the connection. |
accountIds | string | No | 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. |
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
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": "abc123def456ghi789jkl012",
"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"
},
{
"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"
}
]
}
Holding object
| Field | Type | Description |
|---|
id | string | Opaque holding identifier from the brokerage provider |
accountId | string | UUID of the brokerage account this holding belongs to |
accountName | string | Account display name |
symbol | string | Ticker symbol (e.g. AAPL, VAS.AX) |
name | string | null | Security name |
exchange | string | null | Exchange the security is listed on (e.g. ASX, NASDAQ) |
currency | string | Currency code (e.g. AUD, USD) |
quantity | string | Number of units held (decimal string; supports fractional shares) |
averagePrice | string | null | Average cost basis per unit |
currentPrice | string | null | Latest market price per unit |
marketValue | string | null | Current total value of the position |
unrealizedPnl | string | null | Unrealised gain or loss since purchase |
All monetary and quantity fields are strings to preserve decimal precision. Parse them as decimals in your application.
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 | wrong_endpoint_for_category | Holdings are only available for brokerage connections (passed a banking connection) |
403 | (none) | API access requires a Developer or Professional plan (Saver-plan keys) |
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:
{
"error": {
"message": "Brokerage endpoints require a Professional plan",
"code": "professional_required"
}
}
Examples
All holdings for a brokerage connection
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.redbark.co/v1/holdings?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b"
Filter to a specific account
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.redbark.co/v1/holdings?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b&accountId=d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123"
Filter to a subset of accounts
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.redbark.co/v1/holdings?connectionId=e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b&accountIds=d4e5f6a7-b8c9-0123-d4e5-f6a7b8c90123,a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890"
Python
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://api.redbark.co"
resp = requests.get(
f"{BASE}/v1/holdings",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"connectionId": "e8f1a2b3-7c4d-5e6f-8a9b-0c1d2e3f4a5b"},
)
holdings = resp.json()["data"]
for h in holdings:
print(f"{h['symbol']}: {h['quantity']} @ {h['currentPrice']} ({h['currency']})")
JavaScript
const API_KEY = "YOUR_API_KEY";
const BASE = "https://api.redbark.co";
const params = new URLSearchParams({
connectionId: "conn_abc123",
});
const resp = await fetch(`${BASE}/v1/holdings?${params}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { data: holdings } = await resp.json();
for (const h of holdings) {
console.log(`${h.symbol}: ${h.quantity} @ ${h.currentPrice} (${h.currency})`);
}