- Entity Owned FIAT Deposit Destinations: for accounts owned directly by your entity, available on Fedwire or J.P. Morgan’s Kinexys Digital Payments network.
- Customer Owned FIAT Deposit Destinations: for accounts owned by a KYC’d customer, available on ACH and Fedwire for US customers.
Prerequisites
CDP CLI
CDP CLI
Install the CDP CLI (requires Node.js 22+):Configure a Sandbox environment using your CDP Secret API Key JSON file from the CDP Portal. Point it at the Sandbox host so both the
/platform/v2 APIs and the Sandbox-only simulation helper resolve:Entity Owned FIAT Deposit Destinations
Entity owned accounts can issue a fiat deposit destination on the Fedwire rail or the Kinexys rail (J.P. Morgan’s Kinexys Digital Payments network). Fedwire deposit destinations are ABA-routed, using a bank routing number and account number. Kinexys deposit destinations are BIC-routed instead: a Bank Identifier Code (BIC) addresses the account rather than an ABA routing number. Both rails also return areferenceCode that must be included in the payment memo to attribute the deposit to your account.
1. Create the entity-owned account
Create account without anowner. When owner is omitted, the account is owned by the entity making the request:
Entity owned accounts skip customer onboarding entirely: there’s no KYC’d customer, no capability requests, and no
compliance.requesterIpAddress requirement, since these calls aren’t made on a customer’s behalf.2. Issue the fiat deposit destination
Create deposit destination with typefiat and paymentRail set to fedwire or kinexys. Entity owned accounts only support these two rails:
- Fedwire
- Kinexys
Example response
Example response
Unlike the customer owned ACH flow, both entity owned rails activate immediately:
status is active in the create response itself, there’s no pending provisioning step to poll for.3. Share the deposit instructions
Once active, thefiat object holds the coordinates the depositor uses to send USD:
- Fedwire
- Kinexys
4. Simulate an inbound deposit
paymentRail is required when simulating a deposit to a fiat destination, matching whichever rail you created the destination on:
- Fedwire
- Kinexys
Example response
Example response
- Webhook events fire:
payments.transfers.processingthenpayments.transfers.completed - Transfer record is created: visible via List transfers
- Balance is credited: this deposit destination has no
targetset, so funds land directly in the same account and currency (usd) rather than converting to another asset
5. Inspect the transfer and webhook
Get transfer to confirm settlement:source shape depends on the rail.
Kinexys’s source reflects the BIC-routed rail: since Kinexys carries no sender name, source identifies the sending bank (for example JPMorgan Chase Bank, N.A.) rather than an individual or company name the way the ACH source object does (Step 8 of the customer owned flow, below).
Fedwire’s source isn’t shown here. An entity owned Fedwire deposit is attributed by matching the incoming wire’s beneficiary against your entity’s legal name (the beneficiaryName from Step 3) rather than by capturing the sender’s identity, so there’s no sender detail to expose.
The same payments.transfers.completed webhook fires for either rail.
6. Verify the balance update
List balances for account:7. Withdraw to a linked payment method
Entity owned accounts settle outbound Fedwire and Kinexys payments through a payment method rather than a bank-detail target. List payment methods to find the linked one, filtering by rail:- Fedwire
- Kinexys
execute: true to settle in one call:Example response
Example response
payment_code in metadata, a settlement reference for the outbound wire. To validate a withdrawal without moving funds, set execute: false and validateOnly: true; this returns a quoted status without creating a transfer. See the Transfers Quickstart for the full payment method withdrawal walkthrough and the Transfers overview for fee quotes and travel rule requirements.
Customer Owned FIAT Deposit Destinations
Customer owned accounts can issue fiat deposit destinations on the ACH and Fedwire rail. With FIAT deposit destinations for customer owned accounts, you can provision a Virtual Account for your end users, powered by Coinbase and Citi.1. Onboard a KYC’d customer
Create a customer with typeindividual, requesting the capabilities this flow needs:
See the full capability set for every capability CDP supports.
In Sandbox, the
fullSsn value 000-00-0000 is a magic value that forces a deterministic approval, so the requested capabilities verify and become active without real PII.
2. Confirm the custodyFiat capability is active
Creating a fiat deposit destination requires the customer’s custodyFiat capability to be active. Verification is asynchronous; with the approval magic value it settles quickly. Poll with Get a customer:
In production, subscribe to the
customers.capability.changed webhook rather than polling. If custodyFiat is not active, the create call in Step 4 returns 403 customer_not_authorized.3. Create the customer’s account
Create account with the customer as owner. This is where deposited funds will land as USDC. Passing the customer ID asowner makes it customer-owned; customer-facing operations require the end-user’s IP on compliance.requesterIpAddress.
4. Issue the fiat deposit destination
Create deposit destination with typefiat for the account. For customer-owned accounts, this provisions a virtual bank account at Citi. This is a customer-facing operation, so it also requires the end-user’s IP on compliance.requesterIpAddress.
Choose a target for the incoming funds: credit a CDP account, or route straight out on-chain to an external address as each deposit settles (useful for automated sweeps to a non-custodial address):
- Credit an account
- Onchain address
Set
target.asset to usdc so incoming USD is converted and credited as USDC:Example response
Example response
active, without a separate transfer.
If
custodyFiat is not active, this returns 403 with errorType: customer_not_authorized and the missing capability under unauthorizedCapabilities. Resolve it (Step 2) and retry.status is pending: the banking partner (Citi in production) is still provisioning the account.
5. Wait for activation
Poll Get deposit destination until the fiat deposit destination isactive. In production, the destination activates once Citi completes provisioning; Sandbox activates it without any bank interaction. Only then can it receive deposits.
6. Share the deposit instructions
Once active, thefiat object holds the bank coordinates the depositor uses to send USD:
ACH and Fedwire are currently the publicly supported rails.
A fiat deposit destination can be funded by the customer themselves (the sender name must match the KYC’d customer).
7. Simulate a deposit
Because Sandbox is not connected to a bank, use the simulation endpoint to trigger an inbound deposit.paymentRail is required when simulating a deposit to a fiat destination (ach or fedwire). For a fiat destination, asset defaults to the destination’s currency (usd).
Example response
Example response
- Webhook events fire:
payments.transfers.processingthenpayments.transfers.completed - Transfer record is created: visible via List transfers
- Balance is credited: the account receives USDC (converted 1:1 from USD)
8. Inspect the webhook payload
When the deposit settles, CDP fires apayments.transfers.completed webhook to your subscribed endpoint. The payload includes the transfer record, a reference back to the fiat deposit destination, and any metadata set on it.
This requires a webhook subscription; CDP has nowhere to deliver the event otherwise. See Create webhook subscription and Transfer Webhooks to set one up.
Example webhook payload
Example webhook payload
payments.transfers.processing event fires earlier when the deposit is first detected. For most integrations, listening for completed is sufficient. If a deposit is returned, a payments.transfers.failed event fires with the reason.
9. Verify the balance update
Confirm the deposit credited to the account as USDC with List balances for account:Move to production
To run either flow for real, switch the Sandbox base URL to the production base URL and use a production API key. In production there are no magic values (customer owned flows require the customer to complete real KYC), and fiat deposit destinations are provisioned at a banking partner.What to read next
Deposit Destinations overview
Crypto and fiat deposit destinations: concepts, rails, lifecycle, and who can send funds
Customers & KYC
Onboard and verify the customer that owns a customer owned fiat deposit destination
Payment Methods
Link and use external bank accounts, including Fedwire and Kinexys, as transfer targets
Transfers
Move funds out of an account to a wallet address, email, or payment method
Webhooks
Subscribe to real-time deposit event notifications
REST API reference
Full Deposit Destinations API reference