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

# API v2 overview

> The writable Redbark API: conventions for ids, lists, errors, idempotency, versions and scopes

<Info>
  v2 is in **beta** and lives under `https://api.redbark.com/v2`. v1 keeps working unchanged; see the [v1 to v2 mapping](/api-reference/v2/migrating-from-v1).
</Info>

Everything you can do in the dashboard you can do with an API key: read accounts and transactions, manage syncs and runs, shape categories, create destinations and keys, and subscribe to events.

## Base URL

```
https://api.redbark.com/v2
```

The OpenAPI 3.1 document is at `https://api.redbark.com/v2/openapi.json`. Every operation carries `x-redbark-scope` (the scope it needs) and `x-redbark-tier` (its rate-limit tier). The endpoint pages in the sidebar are generated from it and have a playground: paste a key and a `Redbark-Version` once and every page can make live requests.

## Required headers

| Header            | Value                                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| `Authorization`   | `Bearer rbk_live_...`                                                                                              |
| `Redbark-Version` | A release, for example `2026-10-01.wattle`. Required on every request; a missing header is `400 version_required`. |
| `Content-Type`    | `application/json` on POST                                                                                         |
| `Idempotency-Key` | Optional on POST and DELETE. See [Idempotency](#idempotency).                                                      |

## Shape

* JSON in, JSON out, `snake_case` everywhere.
* Every resource has `object` (`"sync"`, `"api_key"`) and every list has `"object": "list"`.
* Ids are prefixed and opaque: `sync_`, `conn_`, `acct_`, `cat_`, `dest_`, `run_`, `key_`, `ed_`, `evt_`. Provider-issued ids are tagged: `txn_fk_...` (Fiskil), `txn_ak_...` (Akahu), `txn_st_...` (SnapTrade), and likewise `hold_st_...` and `trd_st_...` for brokerage holdings and trades.
* `created` and `updated` are RFC 3339 UTC strings with milliseconds. Provider moments keep the bank's offset. Local dates are `YYYY-MM-DD`.
* Money is an integer in minor units plus a lowercase ISO 4217 `currency`: `{ "amount": 1250, "currency": "aud" }`.
* Optional fields are present and `null`, never omitted.
* `livemode` is always `true` today.
* `metadata` holds up to 50 string pairs (40 character keys, 500 character values) on connections, categories, destinations, syncs, event destinations and keys. Set a key to `null` in an update to unset it.

## Lists

Lists are newest first and token paginated. `limit` is 1 to 100 (default 20). The response is:

```json theme={null}
{
  "object": "list",
  "data": [],
  "next_page_url": "https://api.redbark.com/v2/syncs?page=eyJ2IjoxLCJvIjoyMCwibCI6MjAsImYiOnt9fQ",
  "previous_page_url": null
}
```

Follow `next_page_url` until it is `null`. The `page` token encodes the filters the walk started with, so changing a filter while paging is `400 page_filters_changed`. Array filters use bracket form: `?status[]=failed&status[]=cancelled`. Lists are eventually consistent; a just-created object is immediately retrievable by id.

## Include

Heavy or secret fields are `null` unless you name them: `?include[]=accounts`, `?include[]=latest_run`. Each endpoint documents what it can include. An unknown value is `400 include_invalid`.

## Errors

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "name: String must contain at least 1 character(s)",
    "param": "name",
    "doc_url": "https://docs.redbark.com/api-reference/v2/errors#parameter_invalid",
    "request_id": "req_6xB3V3zmWkNGSCARJFA1UE"
  }
}
```

| `type`                  | Status             | Meaning                                                                                                                                      |
| ----------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_request_error` | 400, 404, 409, 410 | Bad parameters, unknown id, or state conflict. `param` is set for field errors.                                                              |
| `authentication_error`  | 401                | Missing, revoked or expired key                                                                                                              |
| `permission_error`      | 403                | Key lacks a scope (`insufficient_scope`), plan lacks the feature, or IP not on the allowlist                                                 |
| `rate_limit_error`      | 429                | Per-key tier or concurrency cap; `Retry-After` is set                                                                                        |
| `idempotency_error`     | 409                | Key reused with different parameters, or the first request is still running                                                                  |
| `upstream_error`        | 424, 503           | A bank or destination failed. 424 is definitive; 503 carries `Retry-After`. The body also carries `upstream.provider` and `upstream.status`. |
| `api_error`             | 500                | Our fault. Quote `request_id` to support.                                                                                                    |

Every response carries `Request-Id`. See the [error catalogue](/api-reference/v2/errors).

## Idempotency

Send `Idempotency-Key` (up to 255 characters) on any POST or DELETE. Within 30 days:

* the same key with the same parameters returns the stored response with `Idempotent-Replayed: true`;
* the same key with different parameters is `409 idempotency_key_reused`;
* the same key while the first attempt is still running is `409 idempotency_key_in_use`;
* a failed first attempt is re-executed.

Without the header the server generates one and returns it in the `Idempotency-Key` response header; nothing is stored. GET ignores the header.

## Versioning

Releases are named and dated: `2026-10-01.wattle` is the first. Additions ship under the current name; a breaking change (removing or renaming a field, changing a type or enum, changing pagination) becomes a new name. Send the release you built against in `Redbark-Version`; the response echoes it. Event payloads are unversioned.

## Rate limits

Applied per key, by tier: `cheap` 60/min, `mid` 30/min, `heavy` 30/min with 4 in flight, `mutating` 30/min. Headers are `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` and `Retry-After` on 429.

## Scopes

Every v2 key is restricted. `resource:write` implies `resource:read`. Keys created before scopes existed are **legacy** keys: they hold every `:read` scope and nothing else. Create a new key in the dashboard or via `POST /v2/api_keys` to get write access.

| Scope                         | Covers                                                                           |
| ----------------------------- | -------------------------------------------------------------------------------- |
| `account:read`                | reserved; `/v2/me` is open to every key so it can introspect its own scopes      |
| `connections:read` / `write`  | connections, consents, institutions, link sessions, refresh, reauthorize, delete |
| `data:read`                   | accounts, balances, details, transactions, holdings, trades, provider categories |
| `categories:read` / `write`   | the category taxonomy and source claims                                          |
| `destinations:read` / `write` | destinations, destination links, secrets                                         |
| `syncs:read` / `write`        | syncs, runs, run/resync/cancel, category mappings                                |
| `rules:read` / `write`        | rulesets and rules                                                               |
| `events:read` / `write`       | event destinations, events, redelivery                                           |
| `keys:write`                  | create, rotate, revoke keys (never beyond the caller's own scopes)               |

## Updates and deletes

Updates are `POST /v2/{resource}/{id}` with a partial body (`PATCH` is accepted as an alias). Deletes return `{ "id": "...", "object": "...", "deleted": true }`.
