Create and use virtual accounts

Create a virtual account linked to a customer for deposits and stablecoin/digital asset conversions

Create Virtual Account

Begin by creating a virtual account for your customer, who has already been onboarded as a participant and KYC/KYB approved.

There are two settlement policies offered on virtual accounts. You must select one in the POST /virtual_accounts request:

  • AUTO_CONVERT_AND_WITHDRAW = When a customer's deposit settles, the USD is automatically converted into a stablecoin/digital asset and paid out to an external wallet.
  • HOLD = Customer's balance will be credited USD when the deposit settles. The customer can choose if/when to buy an asset or withdraw fiat to a linked bank account (separate integrations required).

Opening an AUTO_CONVERT_AND_WITHDRAW account

Example request (for an individual) - POST /virtual_accounts

{
  "participant_code": "PART01",
  "settlement_policy": {
    "type": "AUTO_CONVERT_AND_WITHDRAW",
    "asset": "USDC",
    "external_account_id": "7c1e2c3a-4b5d-4e6f-8a9b-0c1d2e3f4a5b"
  }
}

Note: When the platform selects AUTO_CONVERT_AND_WITHDRAW as the settlement policy, they must share the following fields in the account opening request:

  • asset = stablecoin/digital asset that the customer's deposit will automatically be converted into
  • external_account_id = external wallet address where the stablecoin/digital asset will be paid out to

Example response when status = PENDING

Note: status will display PENDING and bank_details will display null

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "participant_code": "PART01",
  "platform_code": "PLAT01",
  "provider_type": "CRB",
  "status": "PENDING",
  "currency": "USD",
  "bank_details": null,
  "status_detail": null,
  "settlement_policy": { "type": "AUTO_CONVERT_AND_WITHDRAW" },
  "created_at": "2026-08-24T14:22:00.000Z",
  "updated_at": "2026-08-24T14:22:00.000Z"
}

Example response when status = ACTIVE

Note: status will display ACTIVE and bank_details will display with customer's unique account number and routing number for the virtual account

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "participant_code": "PART01",
  "platform_code": "PLAT01",
  "provider_type": "CRB",
  "status": "ACTIVE",
  "currency": "USD",
  "bank_details": {
    "bank_account_number": "0000000001",
    "bank_routing_number": "123456789",
    "provider_account_id": "0000000001",
    "bank_name": "Cross River Bank"
  },
  "status_detail": null,
  "settlement_policy": { "type": "AUTO_CONVERT_AND_WITHDRAW" },
  "created_at": "2026-08-24T14:22:00.000Z",
  "updated_at": "2026-08-24T14:35:12.000Z"
}

Notes:

  • You'll receive an virtual_account.created webhook if the request is successful.
  • zerohash will reject any requests where the participant_code is not in an approved state.
  • The id has been created, uniquely identifying the account in the zerohash system. This ID can be used to retrieve account information or to manage a user's virtual account.
  • The bank_account_number and bank_routing_number fields represent the true virtual account that has been created on the back-end for the customer

Deposit and Hold OR Convert and Withdraw

Depending on the settlement policy selected, there will be different webhooks that trigger when USD deposits are received via ACH/RTP/Wire:

Under the settlement policy AUTO_CONVERT_AND_WITHDRAW, when USD arrives into the virtual account, it will not be credited to the customer in USD.

  1. You'll receive a virtual_account.settlement_initiated webhook message, letting you know that the conversion has been initiated.
  2. Next, you'll receive a virtual_account.settlement_completed webhook message, letting you know that the conversion and the payout have been completed.

Did this page help you?