API v1
API overview
All v1 endpoints at a glance.
The BennyBooks API v1 is RESTful, JSON-only, and org-scoped. All paths are relative to /api/v1.
Read endpoints
/api/v1/transactionsreadlist_transactions
List ledger transactions for the token's organization. Results are ordered by date descending. Agents should keep limit≤50 unless exporting.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | uncategorized, matched, receipt_missing, agent_suggested, reconciled |
| source | enum | nordea, stripe, manual_csv |
| date | date | Exact date (YYYY-MM-DD) |
| dateFrom | date | Inclusive start date |
| dateTo | date | Inclusive end date |
| category | string | Exact category name, or __uncategorized__ |
| description | string | Case-insensitive substring on description |
| limit | integer | Default 50 (agent-lean), max 500 |
| offset | integer | Default 0 |
Response
{
"data": [ { "id": "…", "date": "2026-08-28", "amount": -842, "currency": "EUR", … } ],
"meta": { "totalCount": 42, "limit": 50, "offset": 0 }
}/api/v1/transactions/{id}readget_transaction
Full transaction with linked notes and receipts. Prefer this over list_notes for investigation.
Parameters
| Name | Type | Description |
|---|---|---|
| id* | uuid | Transaction ID |
Response
{
"data": {
"transaction": { … },
"notes": [ { "id": "…", "content": "…", "createdAt": "…" } ],
"receipts": [ { "id": "…", "fileName": "invoice.pdf", … } ]
}
}/api/v1/categoriesreadlist_categories
Chart of accounts with stable codes, synonyms, and parent links. Call before proposing categorizations. Prefer categoryCode over display names.
Response
{
"data": [
{
"code": "5100",
"name": "Software & tools",
"type": "expense",
"parentCode": "5000",
"synonyms": ["Software", "SaaS", "Subscriptions"],
"inUse": true
}
]
}/api/v1/connectorsreadlist_connectors
Bank and payment connector sync status for the organization.
Response
{
"data": [
{ "id": "…", "name": "Stripe", "provider": "stripe", "syncStatus": "ok", "lastSyncAt": "…" }
]
}/api/v1/dashboard/summaryreadget_dashboard_summary
Revenue, expenses, cash position, workload counts, monthly trend, and notifications.
Response
{
"data": {
"currency": "EUR",
"revenue": 26500,
"expenses": 8420,
"cashPosition": 18080,
"uncategorized": 4,
"missingReceipts": 2,
"agentSuggested": 2,
"pendingReview": 3,
"recentTransactions": [ … ],
"monthlyTrend": [ … ],
"notifications": [ … ]
}
}/api/v1/proposalsreadlist_pending_proposals
Pending agent proposals awaiting human approval.
Response
{
"data": [ { "id": "…", "type": "categorization", "status": "pending", … } ],
"meta": { "count": 2 }
}/api/v1/proposals/{id}readget_proposal
Single proposal by ID.
Parameters
| Name | Type | Description |
|---|---|---|
| id* | uuid | Proposal ID |
Response
{ "data": { "id": "…", "type": "categorization", "status": "pending", … } }/api/v1/notesreadlist_notes
Notes attached to a transaction.
Parameters
| Name | Type | Description |
|---|---|---|
| transactionId* | uuid | Transaction ID |
Response
{ "data": [ { "id": "…", "content": "…", "createdAt": "…" } ] }/api/v1/receipts/searchreadsearch_receipts
Search receipts by file name or OCR text. Returns up to 50 results.
Parameters
| Name | Type | Description |
|---|---|---|
| q* | string | Search query |
Response
{ "data": [ … ], "meta": { "count": 3, "limit": 50 } }/api/v1/receipts/{id}readget_receipt
Receipt metadata (not file bytes). Use session API to download files.
Parameters
| Name | Type | Description |
|---|---|---|
| id* | uuid | Receipt ID |
Response
{ "data": { "id": "…", "fileName": "invoice.pdf", "transactionId": null, … } }Write endpoints
All writes require propose-write scope. Most writes create proposals — nothing commits until a human approves.
/api/v1/proposals/categorizationpropose-writepropose_categorization
Suggest a category for a transaction. Prefer categoryCode. Creates a pending proposal — the ledger is not updated until a human approves in Ledger → Approvals.
Request body
{
"transactionId": "uuid",
"categoryCode": "5300",
"confidence": 0.91,
"reason": "Description matches counterparty AWS",
"evidence": [
{ "type": "counterparty_match", "value": "aws" }
]
}Response
{ "data": { "id": "…", "status": "pending", "type": "categorization", … } }/api/v1/proposals/journal-entrypropose-writepropose_journal_entry
Propose a new manual ledger entry. Creates a pending proposal — a transaction is created only after human approval.
Request body
{
"date": "2026-08-28",
"description": "Office supplies",
"amount": -42.50,
"currency": "EUR",
"categoryCode": "5200",
"source": "manual_csv",
"confidence": 0.88,
"reason": "One-off office purchase"
}Response
{ "data": { "id": "…", "status": "pending", "type": "journal_entry", … } }/api/v1/proposals/receipt-linkpropose-writepropose_receipt_link
Suggest linking a receipt to a transaction. Approval required.
Request body
{
"transactionId": "uuid",
"receiptId": "uuid",
"confidence": 0.85,
"reason": "Amount and date match"
}Response
{ "data": { "id": "…", "status": "pending", "type": "receipt_link", … } }/api/v1/notespropose-writeattach_note
Create a proposal to attach a note. Approval required.
Request body
{ "transactionId": "uuid", "content": "Client project: ACME-42" }Response
{ "data": { "id": "…", "status": "pending", "type": "note", … } }/api/v1/notespropose-writecreate_note
Directly create a note without approval. For trusted automation only.
Request body
{ "transactionId": "uuid", "content": "Client project: ACME-42" }Response
{ "data": { "id": "…", "content": "…", "createdAt": "…" } }