Amounts and currency 💱
Almost every monetary field in the Cardda API is an integer in the minor unit of its own currency. There is no single "cents" rule across the API, because the minor unit is not always a hundredth. (A handful of fields serialize the minor-unit value as a string, and a couple of fields report whole currency units instead — both are listed under Reading amounts back.)
CLP has no subunit — the minor unit IS the peso.To transfer $1.000 CLP you send
1000, not100000. A field named*_centson a CLP amount still holds whole pesos: the suffix is a naming convention inherited from theMoneylibrary, not a statement about the unit.
The rule
For a field holding an amount in currency C, the integer you send (and receive) is:
integer_value = decimal_amount × subunit_to_unit(C)| Currency | Minor unit | subunit_to_unit | 1000 means | To send 1.000 units, send |
|---|---|---|---|---|
| CLP (Chilean peso) | the peso itself | 1 | $1.000 | 1000 |
| USD | cent | 100 | US$10.00 | 100000 |
| MXN (Mexican peso) | centavo | 100 | $10.00 MXN | 100000 |
| PEN (Peruvian sol) | céntimo | 100 | S/ 10.00 | 100000 |
| CLF (UF, Unidad de Fomento) | ten-thousandth | 10000 | 0.1 UF | 10000000 |
CLP and CLF are the two that break the "divide by 100" habit — CLP because it has no subunit at all, CLF (UF) because it carries four decimals.
How to know which currency a field is in
Always read the currency off the record, never off the field name:
| Surface | Currency comes from |
|---|---|
bank_transactions.amount | the sending account's country/provider — CLP for Chilean banks and the Cardda wallet, MXN for STP, PEN for BCP |
purchase_orders.amount_cents | the sibling currency field on the same purchase order (CLP, CLF/UF, or USD) |
vendor_cards.*_cents | the card's limit_currency |
card_transactions.amount_cents | the sibling currency (merchant currency); target_amount_cents uses target_currency |
budgets.*_cents, bills.amount | CLP (v1 is CLP-only) |
Accounting transactions | the sibling currency / target_currency |
Worked examples
# Transfer $1.000 CLP from a Chilean bank account
curl -X POST 'https://api.cardda.com/v1/banking/bank_transactions' \
-H 'company-id: <company_uuid>' -H 'Authorization: <token>' \
-H 'Content-Type: application/json' \
-d '{"sender_id":"<clp_account_uuid>","recipient_id":"<recipient_uuid>",
"amount":1000,"description":"Pago servicios"}'
# amount 1000 == $1.000 CLP. Sending 100000 would transfer $100.000.
# A purchase order for 40 UF
# currency CLF, minor unit = 1/10.000 UF → 40 × 10000
# `UF` is accepted on write too and is normalized to the ISO 4217 code `CLF` on save,
# so `CLF` is what reads back and what filters match.
{"currency": "CLF", "amount_cents": 400000}
# A purchase order for US$ 990
# currency USD, minor unit = cent → 990 × 100
{"currency": "USD", "amount_cents": 99000}Reading amounts back
Response fields follow the same rule, with two exceptions worth knowing:
- Accounting (
/v1/accounting/transactions) serializes monetary values as strings of integer minor units, to preserve precision (Moneyruns withdefault_infinite_precision, so the value is aBigDecimalrendered as a JSON string). - A few card fields are decimal strings in whole currency units, not minor units —
remaining_balanceandpreference_restricted_spendableonvendor_cardsare documented as such on their schema. When a field's description says "as a decimal string in the card currency (not cents)", believe the description over the naming pattern.
Related
- How to filter results — filtering on amount fields uses the same integer values.
- Errors — how validation failures on amounts are reported.
Updated 6 days ago
