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:

  1. Creating a recipient.
  2. Listing and updating recipients.
  3. Enrolling a recipient at the bank (and the trigger-code flow when the bank requires SMS confirmation).
  4. 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:

FieldTypeRequiredNotes
namestringyesLegal name of the recipient.
rutstringyes (CL)Tax id. Format XXXXXXXX-Y. For other countries see the country-specific schema.
bank_iduuidyesGet the catalog from GET /v1/banking/banks (no company-id needed; reference data).
account_typeenumyeschecking, savings, vista, rut, credit_line.
account_numberstringyesBank account number. No formatting characters.
emailstringnoWhere the bank sends payment receipts.
aliasstringnoFree-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"
}
📘

The status field reflects Cardda-side validation (mostly RUT + duplicate detection). The enrollment_status field 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 with status: approved.
  • Wrong account_type. Banks reject the enrollment silently (status flips to enrollment_failed). Check the recipient's failure_reason.
  • bank_id mismatch. The recipient bank must be the same as the destination on the transaction. You cannot pay an ACME recipient at Banco de Chile from a Santander source account if the recipient was registered against Itau.

Related