Skip to main content
Use an existing customer identity for fiat withdrawals, fiat payment orders, and virtual accounts. The customer must be active and belong to the authenticated business. Omitting customerId keeps the business-owned flow; customer onboarding does not unlock a missing business integration.

Customer identity and sessions

Start withdrawals with customerId on rates, and deposits with customerId on the quote. Carry sessionId through later requests; the server inherits the customer. A repeated customerId must match. Changing the customer, route, network or routing inputs requires a new session. Assets, currencies and deposit-rail discovery do not accept customerId.

Withdraw fiat

Rates, payment methods, requirements, resolution, quote and execute accept optional customerId. The child-address quote and execute operations accept it too. Legacy v1 withdrawal requests also accept customerId where their DTO includes customer context. Supported customer adapters currently include Noah and Infinia; the API never silently substitutes the business identity.

Payment-method resolution

When resolution returns status: requires_action, render nextStep.schema and submit continuation with resolutionId, stepId and data to the same operation. Preserve the original paymentMethodData. Continue until resolved, then send the completed response as resolvedPaymentMethod to quote and execute. Legacy responses without status or nextStep are resolved.

Onboarding recovery

Customer eligibility failures are HTTP errors, not successful data envelopes. Inspect details.code, details.customerId, details.provider and details.onboarding.action. Follow the returned method, path and body. For create_case use the existing customer; for resume_case fetch the case; for wait keep waiting; for contact_support contact support. Never create another customer or automatically create a new case for a pending/rejected case.

Deposit fiat

Quote, requirement resolution and payment-order creation accept customerId. With sessionId, assetId, currency, amount and rail are inherited; without a session they are required. customer contains optional payer contact details and is not a substitute for customerId. For inline KYC, use additionalDataRequirements.data as defaults and validate against the current schema before sending additionalData. Completed hosted onboarding is checked separately.

Virtual accounts

V2 requirements, creation and regeneration already accept customerId, including child-address creation and regeneration. Requirements validate customer ownership and provider eligibility. Follow the returned additionalDataSchema; do not reuse payment-order schemas. Creation returns 201 with created: true for a new account, or 200 with created: false when reusing an existing account.

Quote amounts and fees

debitAmount is the authoritative total source-asset debit. amountFiat is the payout in the selected fiat currency before deductions; subtract deductions once to obtain the beneficiary payout. transactionFee is in the source crypto asset and can contain additional standalone collection plus the total configured method fee and processing charges. It is not always the entire customer fee: provider-collected costs can already be in funding, and spread is embedded in the rate. Do not add displayed fees to debitAmount. There is no transactionFeeCurrency field.

See also

Customer onboarding webhooks Refresh onboarding — Request new withdrawal rates or a new deposit quote to create a fresh fiat session. Do not reuse a session created before approval. Customer onboarding state changes can also emit customer.onboarding.* webhooks; a refresh does not guarantee a new event for an unchanged case.

Customer operations

Customer and case IDs are both required. The refreshed case is returned in data.case.