Create bank transaction

Creates a bank transaction that transfers money from one of your accounts to a recipient
enrolled in it.

Workflow

  • Individual transfer (no bank_payroll_id): created with status draft and
    transition enqueue, automatically enqueued for processing at the bank, which approves
    or declines it. Email notifications are sent based on company settings.
  • Payroll transfer (bank_payroll_id set): created as draft with no transition,
    dispatched only when the whole payroll is authorized — never individually.
  • transition: null creates a draft that stays put (see the transition field).

Prerequisites

  1. sender_id — an account reachable through a bank key, with sufficient funds
    (GET /v1/banking/bank_accounts).
  2. recipient_id — a recipient enrolled in the sending account
    (recipient.owner_id == sender_id): GET /v1/banking/bank_recipients?owner_id={sender_id}.
  3. bank_key_id (optional) — defaults to the account's highest-priority approved
    key (GET /v1/banking/bank_keys).

Every validation rule is documented on its request-body field — read amount (minor unit
per currency, per-bank interbank ceilings), description (base character set, per-bank
caps) and recipient_id (status requirements) before building the payload. CLP has no
subunit — send 1000 for $1.000
. See
Amounts and currency.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Body Params

Transaction details including sender, recipient, amount, and optional parameters

uuid
required

The source bank account for the transfer. Must be an account you have access to through
a bank key. Find available accounts: GET /v1/banking/bank_accounts

uuid
required

The bank recipient who will receive the transfer. Must be enrolled in the sending
account
recipient.owner_id == sender_id. Recipients belong to a bank account,
not to the company: the same person enrolled in another of your accounts is a different
recipient with a different id, rejected with
422 "Recipient must belong to same account as transaction". Find recipients of the
sending account: GET /v1/banking/bank_recipients?owner_id={sender_id}.

A transfer that enqueues (the default) needs the recipient in approved; a payroll
transfer (bank_payroll_id) and a transition: null draft accept any status. A
deleted recipient is always rejected. See
Tutorial: Create and manage bank recipients.

integer
required
≥ 1

Transfer amount in the minor unit of the sending account's currency.
CLP has no subunit: the minor unit IS the peso — to transfer $1.000 send 1000,
not 100000. MXN (STP) and PEN (BCP) do take the hundredth. See
Amounts and currency.

Must be greater than 0. Interbank transfers (sender and recipient at different
banks) are additionally capped per bank — 7.000.000 CLP at most Chilean banks,
5.000.000 CLP at Banco de Chile; same-bank transfers are not capped. Only two things
lift the ceiling ("being in a payroll" is not by itself one): lbtr: true where
supported (Banco de Chile and Santander), or a deferred payroll (online: false) —
at Banco de Chile and BICE an online payroll keeps the ceiling, while at BCI any
payroll lifts it (BCI payrolls are deferred by construction).

Banco BCP (PEN) is the exception to the CLP numbers: minimum 100 (S/ 1,00) and
maximum 99999999 (S/ 999.999,99).

string
required
length ≥ 1
^[A-zÀ-ú0-9 ]+$

Description shown in bank statements and notification emails, as the reference for both
sender and recipient.

Base rule (all banks): validated against /\A[A-zÀ-ú0-9 ]+\Z/ — letters (accented
included), digits and spaces; read literally, the class also admits a few stray symbols
(_, [, ], ^, `, \, ×, ÷ — exact ranges in the guide linked below).
No length limit. Punctuation (-, #, ., ,, /,
(, ), :, +, &) is rejected:
422 "Validation failed: Description is invalid". Write Pago servicios Factura 1234,
not Payment for services - Invoice #1234.

The sending bank narrows it — the base rule (and the pattern above, which only
mirrors it) is necessary, not sufficient:

Sending bankMax lengthNarrower character set
Banco BICE14letters/digits only: spaces, accents and punctuation are stripped silently, then cut to 14 — BICE rewrites instead of rejecting
BCI30no accents
Banco de Chile, Santander, Scotiabank, Itaú, Cardda wallet70base rule
Banco Security, Banco Internacional, STP, BCPno capbase rule

Over the cap →
422 "Validation failed: Description is too long (maximum is N characters)". BICE never
returns that error (it rewrites), but rejects a description with nothing left after the
strip: 422 "Validation failed: Description only allows alphanumeric characters".

BCI supplier payrolls (category: "suppliers"): must be exactly FACT + space +
1–12 digits (FACT 1234), else
422 "Validation failed: Description must be FACT, followed by a space and 1 to 12 digits".

Banco Security, the BICE Connect path and STP forward only the first 40 characters. Full
detail (exact character ranges, BICE rewrite examples):
Bank transfer description rules.

uuid

Optional selector for the bank key (crawler credential) to use. When omitted, Cardda
picks the sending account's highest-priority approved key for your user (priority
asc, then most recent); passing it explicitly makes the request deterministic when more
than one key reaches the account. Find keys: GET /v1/banking/bank_keys

uuid | null

Optional payroll batch to attach this transaction to. When provided, the transaction is
created as a draft without transition (see transition) and processed when the payroll
is authorized; the recipient may have any status except deleted. Cannot be combined
with budget_id. The payroll itself must be in draft with no transition, else
422 "Validation failed: Payroll status must be draft" /
422 "Validation failed: Payroll transition must be null".
Find payrolls: GET /v1/banking/bank_payrolls?sender_id={account_id}

uuid | null

Optional UUID to safely retry without creating duplicates. Uniqueness is scoped to the
owning account (owner_id), which here always equals sender_id (the database
enforces it for locally initiated transfers). Reusing the pair fails with
422 "Validation failed: Idempotency has already been taken".

metadata
object | null

Optional JSON object for custom data (cost centers, reference numbers). Preserved but
not processed by the banking system.

string | null

Optional internal notes, stored but not sent to the bank — unlike description, any
characters, no length limit.

boolean | null
Defaults to false

Enable LBTR (Liquidación Bruta en Tiempo Real, Chile's RTGS) for high-value
transfers, lifting the per-bank interbank amount cap. Only Banco de Chile
(cl_banco_de_chile) and Santander (cl_banco_santander_chile) support it
(422 "Lbtr is not yet implemented at bank {bank_id}" elsewhere), and it is
interbank only (422 "Lbtr cannot create lbtr transaction if the sender and recipient belong to the same bank").

uuid | null

Optional balance group ("presupuesto") to charge instead of the company's global pool.
Frozen at creation. Only valid on CLP wallet (Cardda) transfers — on a real-bank
transfer: 422 "Validation failed: Budget can only be imputed to CLP wallet transfers".
Must be a well-formed UUID (checked before authorization: malformed is 422, never a
misleading 403) and a budget you may operate for the sending account's company
the sender's holder, not the company-id header. Cannot be combined with
bank_payroll_id. Find budgets: GET /v1/finance/budgets.

string | null
enum
Defaults to enqueue

What to do right after creating. Defaults to enqueue — a plain create is sent to the
bank immediately. enqueue and null are the only usable values: transition: null
creates a draft that stays put (nothing sent, approved-recipient rule not
applied); send it later with POST /v1/banking/bank_transactions/{id}/retry_enqueue.
The rest are rejected — preauthorize/authorize are invalid for a draft
(422 "Transition preauthorize is not valid for status draft"), dequeue needs a
decline_motive this endpoint does not accept (422 "Decline motive can't be blank");
use the dedicated lifecycle endpoints.

With bank_payroll_id, the server silently rewrites enqueue — and only
enqueue — to null: payroll transfers are dispatched when the payroll is authorized.
Other values are rejected as above, not rewritten.

Allowed:
payable_transactions
array of objects | null

Optional array linking this transaction to invoices/payables (requires Pay product):
each item allocates a portion of the amount to a payable for reconciliation.

payable_transactions
uuid | null
deprecated

Deprecated — use sender_id. Not stored; a legacy fallback to resolve the acting
account when sender_id is absent, and that path then fails validation for lack of a
sender.

Headers
uuid
required

UUID of the company on whose behalf the request is made. Send it on banking
requests to identify the acting company. Note that user-scoped list endpoints
(e.g. the recipients/transactions indexes) resolve results across all companies
the authenticated user is a member of, rather than strictly from this header.
See The company-id header for details on how to obtain
a value for this header and the error responses to expect when it is missing or invalid.

Responses

Language
Credentials
Bearer
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json