At a glance
1. Payins (USD to stablecoins)
Create the customer
POST /cms/api/v1/customer/create
dob (YYYY-MM-DD). Save the returned id as customer_id.Verify identity
POST /cms/api/v1/kyc/generate-link
url, then wait for the CUSTOMER webhook with VERIFIED. See KYC SDK.Link a bank account (ACH_PULL only)
ACH_PULL debits the customer’s own bank account, so the customer links it first:POST /cms/api/v1/bank/generate-link
widget_url. The customer signs in to their bank, picks the account and returns to redirect_url. Poll GET /cms/api/v1/bank/list/{customer_id} until the account under accounts is VERIFIED; no BANK webhook is sent. Save its id: an ACH_PULL quotation needs it as bank_id.In sandbox, call Mock Bank Verification with the
customer_id, bank_status: "VERIFIED" and no bank_id. It creates a linked test account.Create a quotation
POST /pis/api/v1/payin/quotation
payment_method is ACH_PULL, WIRE or RTP. For ACH_PULL, also send bank_id: the linked account from the previous step. For every method except ACH_PULL, the response has deposit_instructions: account_number, routing_number, bank_name, bank_address, account_holder_name and a narrative to include with the transfer.Collect the USD
The user pays the exact
sending_amount from a bank account in their own name, before expiry_time. ACH_PULL debits the bank account the customer linked in the previous step, so the user doesn’t make a transfer.Initiate the payin
POST /pis/api/v1/payin/initiate
transaction_reference_id is optional. Add it if the user has the bank’s transfer reference.Credit on SUCCESS
The
PAYIN webhook moves to SUCCESS with the transaction_hash. Credit the user only then. See Payins for every status.2. Payouts (stablecoins to USD)
US beneficiaries skip full KYC. Onboard them with payout-only onboarding, which must be enabled for your organization.Create the beneficiary
POST /cms/api/v1/customer/payout/create
id as customer_id.Create the KYC profile
POST /cms/api/v1/kyc/payout/add-kyc-data
Add the address
POST /cms/api/v1/kyc/payout/add-sender-kyc-data
street.Add the bank account
POST /cms/api/v1/bank/payout/create
id as bank_id. The table below lists the fields for each rail.Quote, fund and initiate
Create a payout quotation with
customer_id, bank_id, fiat: "usd" and the payment_method that GET /payout/configuration lists for USD. Send the crypto to wallet_address, then initiate with the transaction_hash. Paying from a balance instead? See Prefunded payouts.3. Cross-border payments
A cross-border payment to the US is a standard payout, funded with USDC you onramped elsewhere or already hold. When you add the bank account, send atransfer_purpose, such as FAMILY_MAINTENANCE, and is_self_transfer: false. Without them, the payout defaults to TRANSFER_TO_OWN_ACCOUNT. See Cross-border payments.
4. Test in sandbox
Payins
Quotation, deposit instructions and every payin status.
Payout-only onboarding
The fields and rules for every payout market.