Tutorial: Create and manage bank recipients
A bank_recipient is an external bank account that you can pay from one of your bank_accounts. Before sending money to anyone you need a recipient, and (usually) that recipient needs to be enrolled at your bank.
This tutorial covers:
- Creating a recipient.
- Listing and updating recipients.
- Enrolling a recipient at the bank (and the trigger-code flow when the bank requires SMS confirmation).
- Common queries.
1. Create
curl -X POST 'https://api.cardda.com/v1/banking/bank_recipients' \
-H "Authorization: Bearer $API_KEY" \
-H "company-id: $COMPANY_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Vendor",
"rut": "76543210-K",
"bank_id": "BANK_ID",
"account_type": "checking",
"account_number": "0012345678",
"email": "[email protected]",
"alias": "ACME-MAIN"
}'Important fields:
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | Legal name of the recipient. |
rut | string | yes (CL) | Tax id. Format XXXXXXXX-Y. For other countries see the country-specific schema. |
bank_id | uuid | yes | Get the catalog from GET /v1/banking/banks (no company-id needed; reference data). |
account_type | enum | yes | checking, savings, vista, rut, credit_line. |
account_number | string | yes | Bank account number. No formatting characters. |
email | string | no | Where the bank sends payment receipts. |
alias | string | no | Free-form label used in your dashboard. |
Successful response:
{
"id": "11111111-1111-1111-1111-111111111111",
"status": "approved",
"enrollment_status": "not_enrolled",
"name": "Acme Vendor",
"rut": "76543210-K",
"bank": { "id": "...", "name": "Banco de Chile" },
"account_type": "checking",
"account_number": "0012345678",
"created_at": "2026-04-29T18:00:00Z"
}
Thestatusfield reflects Cardda-side validation (mostly RUT + duplicate detection). Theenrollment_statusfield reflects bank-side enrollment (next section).
2. List, update, delete
# List with filters — recipients of a specific bank, alphabetically
curl 'https://api.cardda.com/v1/banking/bank_recipients?bank_id=BANK_ID&_order=asc&_field=name' \
-H "Authorization: Bearer $API_KEY" -H "company-id: $COMPANY_ID"
# Update
curl -X PATCH 'https://api.cardda.com/v1/banking/bank_recipients/RECIPIENT_ID' \
-H "Authorization: Bearer $API_KEY" -H "company-id: $COMPANY_ID" \
-H "Content-Type: application/json" \
-d '{ "alias": "ACME-PRIMARY", "email": "[email protected]" }'
# Delete (soft-delete; hides it from the dashboard, keeps history)
curl -X DELETE 'https://api.cardda.com/v1/banking/bank_recipients/RECIPIENT_ID' \
-H "Authorization: Bearer $API_KEY" -H "company-id: $COMPANY_ID"3. Enroll at the bank
Most banks require you to "enroll" a recipient before sending money. The flow has two shapes — your bank decides which one applies.
3a. Direct enrollment
Some banks (typically business segments) accept enrollment with just the bank credentials. One call:
curl -X POST 'https://api.cardda.com/v1/banking/bank_recipients/RECIPIENT_ID/enroll' \
-H "Authorization: Bearer $API_KEY" -H "company-id: $COMPANY_ID" \
-H "Content-Type: application/json" \
-d '{ "bank_account_id": "BANK_ACCOUNT_ID" }'After ~30 seconds, enrollment_status flips from enrolling to enrolled.
3b. SMS / coordinate-card flow
Other banks require a one-time challenge (SMS code, coordinate card, mobile-app TOTP). Three calls:
# 1. Request the code (bank sends SMS / shows challenge)
curl -X POST 'https://api.cardda.com/v1/banking/bank_recipients/RECIPIENT_ID/trigger_code' \
-H "Authorization: Bearer $API_KEY" -H "company-id: $COMPANY_ID" \
-H "Content-Type: application/json" \
-d '{ "bank_account_id": "BANK_ACCOUNT_ID" }'
# 2. The user receives the code; you collect it from your UI
# 3. Submit it
curl -X POST 'https://api.cardda.com/v1/banking/bank_recipients/RECIPIENT_ID/authorize' \
-H "Authorization: Bearer $API_KEY" -H "company-id: $COMPANY_ID" \
-H "Content-Type: application/json" \
-d '{ "bank_account_id": "BANK_ACCOUNT_ID", "code": "847239" }'If you receive SMS codes via webhook (PLH issuer), see Verification Codes via Webhook — you can fully automate step 2.
4. Useful queries
# All recipients pending enrollment
curl 'https://api.cardda.com/v1/banking/bank_recipients?enrollment_status=not_enrolled' ...
# Search by name (regex)
curl 'https://api.cardda.com/v1/banking/bank_recipients?name={"$regex":"acme"}' ...
# Recipients of any of two banks
curl 'https://api.cardda.com/v1/banking/bank_recipients?bank_id={"$in":["BANK_A","BANK_B"]}' ...See Filters for the full operator reference.
Common pitfalls
- Duplicate detection. Cardda treats
(rut, bank_id, account_number)as unique. Recreating the same triplet returns the existing recipient withstatus: approved. - Wrong
account_type. Banks reject the enrollment silently (status flips toenrollment_failed). Check the recipient'sfailure_reason. bank_idmismatch. The recipient bank must be the same as the destination on the transaction. You cannot pay anACMErecipient at Banco de Chile from a Santander source account if the recipient was registered against Itau.
Related
- Tutorial: Emit a payroll and reconcile it
- Verification Codes via Webhook — automate enrollment SMS handling.
- Errors
Updated 1 day ago
