# Tablewealth API docs

Source page: https://tablewealth.com/docs/api

Use this markdown as a portable copy of the Tablewealth API docs for LLMs and coding agents. It includes the human docs URL, agent-readable URLs, API base URL, OpenAPI schema URL, endpoints, scopes, parameters, response fields, conventions, and implementation guidance.

## Important URLs

- Canonical docs page: https://tablewealth.com/docs/api
- Agent guide: https://tablewealth.com/docs/api/agents.txt
- LLM guide: https://tablewealth.com/docs/api/llms.txt
- OpenAPI schema: https://api.tablewealth.com/openapi.json
- Base URL: https://api.tablewealth.com

## API purpose

The Tablewealth API is a read-only, organization-scoped financial data API for accounts, transactions, holdings, and organization metadata. It is intended for custom dashboards, spreadsheet workflows, internal tools, and AI-assisted code generation.

## Overview

Build read-only integrations against organization-scoped financial data. The API exposes discoverable capabilities, normalized accounts, transactions, holdings, and organization details through API-key authenticated GET endpoints.

Info:

- Base URL: https://api.tablewealth.com
- Version: v1
- Authentication header: X-API-Key

## Quickstart

Create an API key in the dashboard, inspect its capabilities, then call only the operations returned for that key.

1. Scope the key: grant the smallest useful set of scopes and, when needed, limit the key to selected accounts.
2. Discover access: call `GET /v1/api-key` to read scopes, rate limits, account access, and available operations.
3. Page through data: use `pageSize` and `pageToken` on list endpoints. The maximum page size is 100.

## Authentication

Send the API key in the `X-API-Key` header on every request.

```bash
curl "https://api.tablewealth.com/v1/api-key" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

Do not ask users for an organization id or user id. The API key determines the organization, scopes, account access, and rate limits.

Security model:

- Every response is constrained by the key's organization.
- Every endpoint is constrained by granted scopes.
- Account and derived data are constrained by the key's account access policy.
- A `CUSTOM_ACCOUNTS` key can only see the selected account ids returned by discovery.

## First request

Always call `GET /v1/api-key` first. It returns:

- `scopes`
- `accountScope`
- `selectedAccountIds`
- `rateLimits`
- `availableOperations`
- `discovery.openapiUrl`
- `discovery.agentGuideUrl`
- `conventions`

Use `availableOperations` as the source of truth for what the current key can call.

## Scopes

- `organization:read` unlocks `GET /v1/organization`
- `accounts:read` unlocks `GET /v1/accounts` and `GET /v1/accounts/{accountId}`
- `transactions:read` unlocks transaction list endpoints
- `holdings:read` unlocks holding list endpoints

## Endpoints

| Method | Path | Scope | Purpose |
| --- | --- | --- | --- |
| GET | `/v1/api-key` | Valid key | Inspect scopes, account access, rate limits, and available operations |
| GET | `/v1/organization` | `organization:read` | Get organization profile fields |
| GET | `/v1/accounts` | `accounts:read` | List accessible financial accounts |
| GET | `/v1/accounts/{accountId}` | `accounts:read` | Get one accessible account |
| GET | `/v1/transactions` | `transactions:read` | List transactions across accessible accounts |
| GET | `/v1/accounts/{accountId}/transactions` | `transactions:read` | List transactions for one accessible account |
| GET | `/v1/holdings` | `holdings:read` | List holdings across accessible accounts |
| GET | `/v1/accounts/{accountId}/holdings` | `holdings:read` | List holdings for one accessible account |

## Endpoint details

### GET /v1/api-key

Inspect the current API key capabilities.

- Scope: any valid key
- Parameters: none
- Key response fields: `scopes`, `accountScope`, `selectedAccountIds`, `rateLimits`, `availableOperations`, `discovery`

```bash
curl "https://api.tablewealth.com/v1/api-key" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/organization

Get organization details.

- Scope: `organization:read`
- Parameters: none
- Key response fields: `name`, `address`, `phone`, `email`, `website`, `baseCurrencyCode`

```bash
curl "https://api.tablewealth.com/v1/organization" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/accounts

List accessible financial accounts. Account visibility is always constrained by the API key account scope.

- Scope: `accounts:read`
- Parameters: `status`, `category`, `sourceType`, `supportsTransactions`, `supportsHoldings`, `pageSize`, `pageToken`
- Key response fields: `id`, `sourceType`, `provider`, `status`, `category`, `name`, `institutionName`, `balances`, `supportsTransactions`, `supportsHoldings`

```bash
curl "https://api.tablewealth.com/v1/accounts?category=investment&pageSize=25" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/accounts/{accountId}

Get one accessible financial account.

- Scope: `accounts:read`
- Parameters: `accountId`
- Key response fields: `id`, `connectionId`, `name`, `officialName`, `institutionId`, `connectionStatus`, `ownershipPercentage`, `createdAt`

```bash
curl "https://api.tablewealth.com/v1/accounts/{accountId}" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/transactions

List accessible financial transactions across accounts.

- Scope: `transactions:read`
- Parameters: `accountId`, `dateFrom`, `dateTo`, `pending`, `visibility`, `category`, `pageSize`, `pageToken`
- Key response fields: `id`, `accountId`, `transactionDate`, `authorizedDate`, `name`, `merchantName`, `amount`, `displayAmount`, `currencyCode`, `pending`, `isIgnored`

```bash
curl "https://api.tablewealth.com/v1/transactions?dateFrom=2026-01-01&dateTo=2026-01-31&pageSize=50" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/accounts/{accountId}/transactions

List transactions for one accessible account.

- Scope: `transactions:read`
- Parameters: `accountId`, `dateFrom`, `dateTo`, `pending`, `visibility`, `category`, `pageSize`, `pageToken`
- Key response fields: `id`, `accountName`, `institutionName`, `sourcePrimaryCategory`, `sourceDetailedCategory`, `organizationTransactionCategoryName`

```bash
curl "https://api.tablewealth.com/v1/accounts/{accountId}/transactions?visibility=active" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/holdings

List accessible financial holdings across accounts.

- Scope: `holdings:read`
- Parameters: `accountId`, `tickerSymbol`, `isCashEquivalent`, `pageSize`, `pageToken`
- Key response fields: `id`, `accountId`, `assetName`, `tickerSymbol`, `quantity`, `currentPrice`, `marketValue`, `costBasis`, `isCashEquivalent`

```bash
curl "https://api.tablewealth.com/v1/holdings?tickerSymbol=VTI" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

### GET /v1/accounts/{accountId}/holdings

List holdings for one accessible account.

- Scope: `holdings:read`
- Parameters: `accountId`, `tickerSymbol`, `isCashEquivalent`, `pageSize`, `pageToken`
- Key response fields: `id`, `accountName`, `institutionName`, `securityId`, `type`, `subtype`, `sector`, `industry`

```bash
curl "https://api.tablewealth.com/v1/accounts/{accountId}/holdings?isCashEquivalent=false" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

## Query parameters

### Accounts

- `status`: `ACTIVE`, `INACTIVE`, or `REMOVED`
- `category`: `bank`, `investment`, `real_estate`, `retirement`, `debt`, or `other`
- `sourceType`: `PROVIDER`, `MANUAL`, or `IMPORT`
- `supportsTransactions`: `true` or `false`
- `supportsHoldings`: `true` or `false`
- `pageSize`: 1 to 100
- `pageToken`: token from the previous response

### Transactions

- `accountId`: Tablewealth account id
- `dateFrom`: `YYYY-MM-DD`
- `dateTo`: `YYYY-MM-DD`
- `pending`: `true` or `false`
- `visibility`: `active`, `ignored`, or `all`
- `category`: source, guessed, manual, or organization category name
- `pageSize`: 1 to 100
- `pageToken`: token from the previous response

### Holdings

- `accountId`: Tablewealth account id
- `tickerSymbol`: case-insensitive exact ticker match
- `isCashEquivalent`: `true` or `false`
- `pageSize`: 1 to 100
- `pageToken`: token from the previous response

## Pagination

List endpoints return:

```json
{
  "data": [],
  "pagination": {
    "pageSize": 50,
    "nextPageToken": "..."
  }
}
```

If `pagination.nextPageToken` exists, pass it as `pageToken` on the next request. The maximum `pageSize` is 100.

## Response envelope

Successful responses use:

```json
{
  "data": {},
  "pagination": {},
  "meta": {}
}
```

Error responses use:

```json
{
  "error": {
    "code": "forbidden_scope",
    "message": "The API key lacks the required scope.",
    "requestId": "req_..."
  }
}
```

Possible error codes include `unauthorized`, `forbidden_scope`, `invalid_query`, `not_found`, `rate_limited`, and `internal_error`.

## Schemas

These are the highest-signal response fields for the core resources.

### Account

- `id`
- `sourceType`
- `provider`
- `status`
- `category`
- `name`
- `institutionName`
- `balances`
- `supportsTransactions`
- `supportsHoldings`

### Transaction

- `id`
- `accountId`
- `transactionDate`
- `name`
- `merchantName`
- `amount`
- `displayAmount`
- `currencyCode`
- `pending`
- `isIgnored`

### Holding

- `id`
- `accountId`
- `assetName`
- `tickerSymbol`
- `quantity`
- `currentPrice`
- `marketValue`
- `costBasis`
- `isCashEquivalent`

## OpenAPI JSON

Use the machine-readable schema when generating typed clients, validating responses, or giving an agent the exact API contract.

- OpenAPI schema: https://api.tablewealth.com/openapi.json

## Rate limits

Responses can include:

- `RateLimit-Limit`
- `RateLimit-Remaining`
- `RateLimit-Reset`
- `Retry-After` on 429 responses

List responses can also include `X-TableWealth-Item-Count`.

## Financial semantics

- All ids are Tablewealth ids unless a field is explicitly named external/provider.
- `sourceType` can be `PROVIDER`, `MANUAL`, or `IMPORT`.
- `provider` is only present for provider-backed records.
- Transaction `amount` is the stored source-normalized amount.
- Transaction `displayAmount` is user-facing and currently equals `amount * -1`.
- Dates use `YYYY-MM-DD` for date-only fields.
- Empty lists can mean restricted key account access, not necessarily no organization data.
- API data is not financial, investment, legal, or tax advice.

## Useful examples

```bash
curl "https://api.tablewealth.com/v1/accounts?category=investment&pageSize=25" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

```bash
curl "https://api.tablewealth.com/v1/transactions?dateFrom=2026-01-01&dateTo=2026-01-31&pageSize=100" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

```bash
curl "https://api.tablewealth.com/v1/holdings?tickerSymbol=VTI" \
  -H "X-API-Key: $TABLEWEALTH_API_KEY"
```

## Agent instructions

When helping a user with the Tablewealth API:

1. Reference the canonical docs page when useful: https://tablewealth.com/docs/api.
2. Ask for the API base URL only if it differs from https://api.tablewealth.com.
2. Never ask the user to paste an API key into chat unless they explicitly choose to. Prefer environment variables such as `TABLEWEALTH_API_KEY`.
3. Generate code that calls `GET /v1/api-key` first and branches from `availableOperations`.
4. Respect scopes and account access. Do not invent endpoints.
5. Use the OpenAPI schema at https://api.tablewealth.com/openapi.json for exact machine-readable contracts.
