Endpoint Reference
All API key requests must include an Authorization: Bearer <token> header. See API Overview for how to generate a key.
API key access requires a Starter or higher plan. Free tier requests return 403 Forbidden. Each plan includes a monthly call quota.
Accounts
/api/accounts
Returns all accounts for the authenticated user.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| includeArchived | query | boolean | No | Include archived accounts (default: false) |
Response
[
{
"id": "acc_abc123",
"name": "Current Account",
"type": "asset",
"currency": "GBP",
"balance": 2450.00,
"subtypeId": "sub_checking",
"subtype": {
"id": "sub_checking",
"name": "checking",
"builtInId": "checking"
},
"starred": false,
"archivedAt": null,
"closingDay": null,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-03-20T14:22:00.000Z"
}
]
/api/accounts/:id
Returns a single account by ID.
Response
{
"id": "acc_abc123",
"name": "Current Account",
"type": "asset",
"currency": "GBP",
"balance": 2450.00,
"subtypeId": "sub_checking",
"subtype": {
"id": "sub_checking",
"name": "checking",
"builtInId": "checking"
},
"starred": false,
"archivedAt": null,
"closingDay": null,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-03-20T14:22:00.000Z"
}
Transactions
/api/transactions
Returns transactions for the authenticated user. Supports pagination and filtering.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| accountId | query | string | No | Filter by from or to account ID |
| from | query | string | No | Start date (ISO 8601, e.g. 2024-01-01) |
| to | query | string | No | End date (ISO 8601, e.g. 2024-03-31) |
| limit | query | number | No | Max results (default 50, max 200) |
| offset | query | number | No | Pagination offset (default 0) |
Response
{
"transactions": [
{
"id": "txn_abc",
"fromAccountId": "acc_abc123",
"toAccountId": null,
"fromAmount": 45.00,
"fromCurrency": "GBP",
"toAmount": 45.00,
"toCurrency": "GBP",
"fxRate": null,
"description": "Groceries",
"date": "2024-03-15",
"time": null,
"trxOrigin": "api",
"createdAt": "2024-03-15T12:30:00.000Z"
}
],
"total": 142
}
/api/transactions
Creates a new transaction. Use fromAccountId for expenses (money leaving an account) and toAccountId for income (money entering). Set both for transfers between accounts. Supports installment purchases — pass isInstallmentPayment: true to automatically create a rule that handles all remaining monthly payments.
Request body
{
"fromAccountId": "acc_abc123",
"toAccountId": null,
"fromAmount": 45.00,
"fromCurrency": "GBP",
"date": "2024-03-15",
"description": "Groceries"
}
Response
{
"id": "txn_xyz",
"installmentRuleId": null
}
Duplicate detection
Every POST /api/transactions request is checked against existing transactions before inserting. There are two levels:
Hard duplicate → 409 Conflict
If all of the following fields match an existing transaction exactly, the request is rejected and no row is inserted:
fromAccountId, toAccountId, date, time, fromAmount, fromCurrency, toAmount, toCurrency, description
null values are matched exactly — a transaction with no time only conflicts with another transaction that also has no time.
{
"error": "Duplicate transaction",
"existingId": "txn_abc"
} Soft duplicate → 202 Accepted
If only date and fromAmount match an existing transaction (but the full field set does not), the transaction is inserted and flagged for review. It will appear in the Review page under Possible Duplicates, where you can choose to keep or delete it.
{
"id": "txn_xyz",
"installmentRuleId": null,
"possibleDuplicateOf": "txn_abc",
"duplicateLinkId": "dl_123"
} A 202 response means the transaction was saved — it is not an error. Your integration should treat 201 and 202 as both successful.
For installment purchases (e.g. a credit card purchase paid in monthly instalments), include the installment fields:
| Field | Required | Default | Description |
|---|---|---|---|
isInstallmentPayment | No | false | Mark this as an installment purchase |
numberOfInstallments | When isInstallmentPayment: true | — | Total number of monthly payments |
currentInstallment | No | 1 | Which payment this transaction represents. 1 = first payment. Pass 3 to record the 3rd payment of an existing purchase — the system creates a rule starting from payment 4. |
yearlyInterestRate | No | 0 | Annual interest rate as a percentage. 0 = equal split. Uses standard amortization. |
fromAmount must always be the full original purchase price (not the per-installment amount).
When currentInstallment < numberOfInstallments, the response includes an installmentRuleId pointing to the newly created rule that will handle all remaining payments.
{
"fromAccountId": "acc_credit_card",
"toAccountId": "acc_expense",
"fromAmount": 1200.00,
"fromCurrency": "USD",
"date": "2026-04-19",
"description": "Laptop",
"isInstallmentPayment": true,
"numberOfInstallments": 12,
"currentInstallment": 1,
"yearlyInterestRate": 18.5
} Response when an installment rule is created:
{
"id": "txn_xyz",
"installmentRuleId": "rule-abc123"
}
/api/transactions/:id
Deletes a transaction and reverses its effect on account balances.
Response
// Returns 204 No Content on success
Returns 404 Not Found if the transaction does not exist or belongs to another user.
Exchange rates
/api/rates
Returns the exchange rate between two currencies. Rates are updated daily.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| from | query | string | Yes | Source currency code (e.g. USD) |
| to | query | string | Yes | Target currency code (e.g. GBP) |
Response
{ "rate": 0.79143 }