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: truemeans that phone belongs to an active account of the same operator — you can transfer to it instantly.
Send money by phone number
Internal transfers acceptto_phone (besides to_account_id, to_email
and to_contact_id):
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
beneficiaryin the body always wins. No saved destination for that corridor:422 no_saved_destination. - Crypto: uses the saved address for that
chain; an explicitto_addresswins. - 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
200):
POST /v1/contacts/{id}/destinations with type: payout|crypto|cbpay and its
fields) and delete them (DELETE .../destinations/{destination_id}).
Errors
FAQ
Does the recipient know I saved them as a contact?
Does the recipient know I saved them as a contact?
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.
Why does a contact I know has CBPay show has_cbpay: false?
Why does a contact I know has CBPay show has_cbpay: false?
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.
Can I transfer to a contact with has_cbpay: false?
Can I transfer to a contact with has_cbpay: false?
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.
Can the import be used to probe whether any number has CBPay?
Can the import be used to probe whether any number has CBPay?
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).