Appearance
Bank Transaction
Bank transactions represent financial movements in your bank accounts, typically imported from bank statement files (CAMT.053, etc.). They can be reconciled with invoices, expenses, journal transactions, and other business records for comprehensive financial tracking.
Allowed query parameters
Filters
| Filter | Type | Description |
|---|---|---|
search | String | Full-text search across transaction details |
bank_account | Id | Filter by Bank Account Id |
date_range | DateRange | Filter by booking date<start-date>,<end-date> |
amount_range | Range | Filter by transaction amount range |
reconciled | Boolean | Filter by reconciliation status |
is_processing | Boolean | Show only transactions currently being processed |
Sorting
booking_date, value_date, document_date, amount, name, created_at
Includes
bankAccount, matches.matchable, documentRequestMember.user
Upload and import bank transactions
post
/bank_account/{bankAccountId}/import-transactions
This endpoint allows you to upload and import bank transactions from various file formats. The system supports multiple import methods with automatic data processing and matching capabilities.
Supported file formats
| Format | Extensions | Description |
|---|---|---|
| CAMT XML | .xml | Standard bank statement format (CAMT.053) with complete transaction details |
| CSV/Excel | .csv, .txt, .xls, .xlsx | Tabular data with AI-powered column mapping |
Request parameters
| Attribute (* required) | Type | Description |
|---|---|---|
files.* * | File | Array of files to import (max 5MB each) |
Example request
http
POST /bank_account/AG52olvLXP/import-transactions
Content-Type: multipart/form-data
files[0]=bank_statement.xml
files[1]=transactions.csvExample response
json
// HTTP 200 OK
[
{
"id": "9c3b5e4d-8f2a-4b6c-9d1e-2f3a4b5c6d7e",
"name": "bank_statement.xml",
"totalJobs": 25,
"pendingJobs": 25,
"processedJobs": 0,
"progress": 0,
"finished": false,
"cancelled": false,
"created_at": "2024-01-15T10:30:00.000000Z"
},
{
"id": "8b2a4c3d-7e1f-5a8b-8c2d-1e4f5a8b9c2d",
"name": "transactions.csv",
"totalJobs": 150,
"pendingJobs": 150,
"processedJobs": 0,
"progress": 0,
"finished": false,
"cancelled": false,
"created_at": "2024-01-15T10:30:00.000000Z"
}
]Error handling
Common error scenarios:
- 422 Unprocessable Entity: Could not match CSV columns automatically
- 413 Payload Too Large: File exceeds 5MB limit
- 415 Unsupported Media Type: Invalid file format
- 403 Forbidden: Insufficient permissions (requires
create bank_transactionorsupervise invoicespermission)
Monitoring import progress
The import process runs asynchronously in the background. Use the returned batch IDs to monitor processing status and provide real-time feedback to users.
For detailed information on monitoring batch progress, polling recommendations, and handling batch status updates, see the Background Jobs guide.
Create a bank transaction
post
/bank_transaction
Create a bank transaction manually. The transaction will be automatically processed for AI optimization (if name is missing but text is provided) or matching against existing records.
| Attribute (* required) | Type | Description |
|---|---|---|
bank_account_id * | String | Bank Account Id |
acc_serv_ref * | String | Unique identifier for this transaction |
amount * | Numeric | Transaction amount (positive for credits, negative for debits) |
entry_acc_serv_ref | String? | Entry account servicer reference |
document_date | Date? | Document date from the transaction |
booking_date | Date? | Booking date when transaction was processed |
value_date | Date? | Value date when funds become available |
currency | String? | Currency code (max 3 characters, defaults to bank account currency) |
reference | String? | Payment reference or structured reference |
name | String? | Transaction counterparty name |
text | String? | Additional transaction description |
end_to_end_id | String? | End-to-end identification |
Example response
json
// HTTP 201 Created
{
"id": "v7rnRjBn9o",
"bank_account_id": "AG52olvLXP",
"bank_account": null,
"matches": [],
"acc_serv_ref": "202401150001",
"entry_acc_serv_ref": "202401150001-1",
"end_to_end_id": "NOTPROVIDED",
"document_date": "2024-01-15",
"booking_date": "2024-01-15",
"value_date": "2024-01-15",
"amount": -125.5,
"currency": "CHF",
"reference": "RF18 5390 0754 7034 2",
"name": "ACME Corporation AG",
"text": "Invoice payment 2024-001",
"is_processing": true,
"is_reconciled": false
}Important notes
- Processing: New transactions are automatically set to
is_processing: trueand will be processed asynchronously - AI Optimization: If
nameis not provided buttextis provided, the transaction will be optimized using AI to extract better details - Auto-matching: After creation (or AI optimization), the system automatically attempts to match the transaction with existing records (invoices, expenses, etc.)
- Uniqueness: The
acc_serv_refmust be unique across all bank transactions
Retrieve a bank transaction
get
/bank_transaction/{id}
Example response
json
// HTTP 200 OK
{
"id": "v7rnRjBn9o",
"bank_account_id": "AG52olvLXP",
"acc_serv_ref": "202401150001",
"entry_acc_serv_ref": "202401150001-1",
"end_to_end_id": "NOTPROVIDED",
"document_date": "2024-01-15",
"booking_date": "2024-01-15",
"value_date": "2024-01-15",
"amount": -125.5,
"currency": "CHF",
"reference": "RF18 5390 0754 7034 2",
"name": "ACME Corporation AG",
"text": "Invoice payment 2024-001",
"is_processing": false,
"is_reconciled": false,
"document_requested_at": null,
"document_request_message": null,
"document_request_member": null,
"bank_account": {
"id": "AG52olvLXP",
"name": "Business Account CHF",
"iban": "CH93 0076 2011 6238 5295 7",
"currency": "CHF"
},
"matches": []
}Match a bank transaction manually
post
/bank_transaction/{id}/matches
Replaces the transaction's matches with a manually assembled allocation and immediately reconciles it. Each entry either points at a business record (invoice, expense, expense payment or company) or books to an accounting account (a "manual entry" / residual row).
Request parameters
| Attribute (* required) | Type | Description |
|---|---|---|
matches * | Array | Non-empty array of allocation rows. |
matches.*.amount * | Numeric | Signed allocation amount in the transaction's base (booking) currency. Must not be 0. Negative amounts book against the transaction's direction (e.g. a payment-provider commission on a gross-booked deposit) and are only allowed on account-only rows of a non-zero transaction. |
matches.*.matchable_type | String? | One of invoice, expense, expense_payment, company. Omit for an account-only row. |
matches.*.matchable_id | String? | Id of the matched record (required when matchable_type is set). |
matches.*.account_id | String? | Accounting account Id for a manual/residual row. |
matches.*.vat_rate_id | String? | VAT rate Id for a manual/residual row. |
matches.*.text | String? | Free-text description stored on the match. |
Base-currency amounts and the sum invariant
matches[].amount is always denominated in the transaction's base currency, not the document currency of the matched record. For a foreign-currency document the caller contributes the record's base-currency share and books the FX/rounding difference as a separate account row (a "Kursdifferenz" residual).
For a base-currency transaction the summed allocation contributions must reconcile the full transaction amount (tolerance 0.05); otherwise the request is rejected. Account-only rows contribute their signed amount — a gross fee split like +30.00 revenue and -0.69 commission against a 29.31 deposit passes. Document rows contribute their magnitude, so a credit note (stored with the document's negative total) covers the refund it settles. This invariant is skipped for transactions denominated in a non-base account currency.
Error handling
- 422 Unprocessable Entity: an allocation is
0, a negative allocation targets a document row or a zero-amount transaction, or (base-currency transactions) the signed amounts do not add up to the transaction amount. - 403 Forbidden: Insufficient permissions.
Reconcile a bank transaction
post
/bank_transaction/{id}/reconcile
Reconciles a transaction against the matches already attached to it (e.g. an accepted suggestion). For a base-currency transaction the attached match amounts must add up to the transaction amount (tolerance 0.05); a single FX suggestion that leaves an unbooked residual is rejected with 422, and the residual must instead be added through the manual match endpoint above.
Delete a bank transaction
delete
/bank_transaction/{id}
Deleting a bank transaction will also remove all associated matches and reconciliations.
Example response
json
// HTTP 204 No ContentBulk unreconcile bank transactions
post
/bank_transaction/unreconcile-many
Undoes the reconciliation of many bank transactions at once. Because a single request can target hundreds of transactions, the work is dispatched to a background queue and the endpoint returns a batch object immediately (it no longer returns 204 No Content).
Only reconciled transactions are ever affected — a hard server-side constraint is always applied, regardless of any filter[reconciled] sent by the client.
Request parameters
| Parameter | Type | Description |
|---|---|---|
items | array | string | Either an array of bank transaction IDs to unreconcile, or the string "all" to target every reconciled transaction matching the current query. Required, non-empty. |
When items is "all", the same query parameters as the list endpoint apply (e.g. filter[bank_account], filter[date_range], filter[amount_range], search), so the batch targets exactly the transactions currently in view.
Example request
json
// Target a specific set of transactions
{
"items": ["v7rnRjBn9o", "AG52olvLXP"]
}
// Or target every reconciled transaction matching the query
{
"items": "all"
}Example response
json
// HTTP 200 OK
{
"id": "9c3b5e4d-8f2a-4b6c-9d1e-2f3a4b5c6d7e",
"name": "737 Transaktionen",
"totalJobs": 737,
"pendingJobs": 737,
"processedJobs": 0,
"progress": 0,
"failedJobs": 0,
"options": [],
"createdAt": "2024-01-15T10:30:00.000000Z",
"cancelledAt": null,
"finishedAt": null
}The batch runs asynchronously. Use the returned batch ID to monitor progress — see the Background Jobs guide. Because the batch allows failures, it can finish with failedJobs > 0; inspect that field to detect partial failures.
Error handling
- 422 Unprocessable Entity:
itemsis missing, an empty array, or an invalid value. - 403 Forbidden: Insufficient permissions (requires
edit bank_transaction).
List bank transactions
get
/bank_transaction
Returns a paginated list of bank transactions. The list endpoint accepts the same query parameters as described above and returns an array of bank transaction objects in the data property.
Read more about Pagination, Filtering, Sorting and Includes on the Introduction page.
Example response
json
// HTTP 200 OK
{
"data": [
{
"id": "v7rnRjBn9o",
"bank_account_id": "AG52olvLXP",
"acc_serv_ref": "202401150001",
"entry_acc_serv_ref": "202401150001-1",
"end_to_end_id": "NOTPROVIDED",
"document_date": "2024-01-15",
"booking_date": "2024-01-15",
"value_date": "2024-01-15",
"amount": -125.5,
"currency": "CHF",
"reference": "RF18 5390 0754 7034 2",
"name": "ACME Corporation AG",
"text": "Invoice payment 2024-001",
"is_processing": false,
"is_reconciled": false,
"bank_account": null,
"matches": []
}
// ... more transactions
],
"links": {
"first": "https://api.blond.swiss/bank_transaction?page=1",
"last": "https://api.blond.swiss/bank_transaction?page=10",
"prev": null,
"next": "https://api.blond.swiss/bank_transaction?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 10,
"path": "https://api.blond.swiss/bank_transaction",
"per_page": 50,
"to": 50,
"total": 487
}
}