Skip to main content
The contact book kills repeated typing: every send (internal transfer, fiat payout or crypto withdrawal) saves the destination as a contact automatically, you can import the phone’s address book to discover which of your contacts have CBPay, and transfers accept a phone number or a contact_id directly as destination.

Contacts create themselves

Every send saves its destination in your book (deduplicated: repeating the same destination never creates duplicates, it only marks it as used): Don’t want to save a one-off destination? Add "save_contact": false to the send body. Auto-save never affects the send: if anything fails, the send goes through anyway.

Import the phone address book

Upload the phone’s contacts (up to 1,000 per request; paginate beyond that) and CBPay tells you who already has an account — matching is by phone number, and only against accounts of the same operator:
200 response:
  • Numbers are normalized to E.164 automatically: accepts +…, 00… and local numbers (your account’s country code is prepended). Invalid ones are skipped.
  • Re-importing is safe: existing contacts are never duplicated.
  • has_cbpay: true means that phone belongs to an active account of the same operator — you can transfer to it instantly.

Send money by phone number

Internal transfers accept to_phone (besides to_account_id, to_email and to_contact_id):
For safety, to_phone only resolves accounts with an OTP-verified phone (we never guess a money destination from an unverified number). If the number is not verified: 404 recipient_not_found; if more than one account shares it: 422 recipient_ambiguous (use to_account_id or to_email).

Send to a contact

Every send accepts the contact directly:
  • Payouts: uses the contact’s most recent saved beneficiary for that country (and method when sent; otherwise the saved destination’s method applies). An explicit beneficiary in the body always wins. No saved destination for that corridor: 422 no_saved_destination.
  • Crypto: uses the saved address for that chain; an explicit to_address wins.
  • Transfers: uses the contact’s linked CBPay account; if the contact only has a phone, its (verified) number is tried. Neither: 422 contact_not_linked.

Manage the book

Contact detail (200):
You can also add destinations manually (POST /v1/contacts/{id}/destinations with type: payout|crypto|cbpay and its fields) and delete them (DELETE .../destinations/{destination_id}).

Errors

FAQ

No. The book is private to your account: importing your address book or saving contacts never notifies anyone or shares your data. Only you see your book.
Matching is by exact phone number (E.164) against accounts of the same operator. If that person registered a different number (or none) on their account, there is no match. Once they register and verify that phone, a re-import picks it up.
Not via internal transfer (there is no account to credit). But you can send a fiat payout to their bank account or a crypto send to their wallet — and those destinations get saved on the contact too.
Sending by phone fails explicitly with 422 recipient_ambiguous — we never guess a money destination. Use to_account_id or to_email in that case.
Matching is only against accounts of your same operator, with a cap of 1,000 contacts per request under the API’s global rate limit. It exposes nothing about the matched account beyond its existence (needed to be able to transfer to it).
Last modified on July 10, 2026