Skip to content

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

FilterTypeDescription
searchStringFull-text search across transaction details
bank_accountIdFilter by Bank Account Id
date_rangeDateRangeFilter by booking date
<start-date>,<end-date>
amount_rangeRangeFilter by transaction amount range
reconciledBooleanFilter by reconciliation status
is_processingBooleanShow 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

FormatExtensionsDescription
CAMT XML.xmlStandard bank statement format (CAMT.053) with complete transaction details
CSV/Excel.csv, .txt, .xls, .xlsxTabular data with AI-powered column mapping

Request parameters

Attribute (* required)TypeDescription
files.* *FileArray 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.csv

Example 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_transaction or supervise invoices permission)

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)TypeDescription
bank_account_id *StringBank Account Id
acc_serv_ref *StringUnique identifier for this transaction
amount *NumericTransaction amount (positive for credits, negative for debits)
entry_acc_serv_refString?Entry account servicer reference
document_dateDate?Document date from the transaction
booking_dateDate?Booking date when transaction was processed
value_dateDate?Value date when funds become available
currencyString?Currency code (max 3 characters, defaults to bank account currency)
referenceString?Payment reference or structured reference
nameString?Transaction counterparty name
textString?Additional transaction description
end_to_end_idString?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: true and will be processed asynchronously
  • AI Optimization: If name is not provided but text is 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_ref must 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)TypeDescription
matches *ArrayNon-empty array of allocation rows.
matches.*.amount *NumericSigned 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_typeString?One of invoice, expense, expense_payment, company. Omit for an account-only row.
matches.*.matchable_idString?Id of the matched record (required when matchable_type is set).
matches.*.account_idString?Accounting account Id for a manual/residual row.
matches.*.vat_rate_idString?VAT rate Id for a manual/residual row.
matches.*.textString?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 Content

Bulk 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

ParameterTypeDescription
itemsarray | stringEither 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: items is 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
    }
}