Virtual accounts require the customer to have completed KYC verification. See
Create KYC Session .
Method Signature
align . virtualAccounts . create (
customerId : string ,
data : CreateVirtualAccountRequest
): Promise < VirtualAccount >
Parameters
The unique customer identifier (UUID format)
source_currency
'usd' | 'eur' | 'aed'
required
Fiat currency for deposits
Optional payment rails. Currently only swift is supported (for USD).
Cryptocurrency token to receive
Blockchain network: polygon, ethereum, solana, base, arbitrum,
tron
Wallet address to receive converted crypto.
Returns
Unique identifier for the virtual account
Bank account details for depositing funds. Structure varies by currency/type.
Examples
Create USD Virtual Account
import Align , { isUSAccountDetails } from "@tolbel/align" ;
const align = new Align ({
apiKey: process . env . ALIGN_API_KEY ! ,
environment: "sandbox" ,
});
const virtualAccount = await align . virtualAccounts . create (
"123e4567-e89b-12d3-a456-426614174000" ,
{
source_currency: "usd" ,
source_rails: "swift" , // Optional, strictly for SWIFT
destination_token: "usdc" ,
destination_network: "polygon" ,
destination_address: "0x742d35Cc6634C0532925a3b844Bc9e7595f0aB42"
}
);
console . log ( `Account ID: ${ virtualAccount . id } ` );
// Use type-safe helper functions for narrowing
if ( isUSAccountDetails ( virtualAccount . deposit_instructions )) {
console . log ( `Routing: ${ virtualAccount . deposit_instructions . us . routing_number } ` );
console . log ( `Account: ${ virtualAccount . deposit_instructions . us . account_number } ` );
}
const virtualAccount = await align . virtualAccounts . create (
"123e4567-e89b-12d3-a456-426614174000" ,
{
source_currency: "usd" ,
destination_token: "usdc" ,
destination_network: "polygon" ,
destination_address: "0x742d35Cc6634C0532925a3b844Bc9e7595f0aB42"
}
);
// Access nested properties
const instructions = virtualAccount . deposit_instructions ;
if ( instructions . us ) {
console . log ( "Routing:" , instructions . us . routing_number );
}
Create EUR Virtual Account (SEPA/IBAN)
import { isIBANAccountDetails } from "@tolbel/align" ;
const euroAccount = await align . virtualAccounts . create ( customerId , {
source_currency: "eur" ,
destination_token: "usdc" ,
destination_network: "polygon" ,
destination_address: "0x..." ,
});
if ( isIBANAccountDetails ( euroAccount . deposit_instructions )) {
console . log ( `IBAN: ${ euroAccount . deposit_instructions . iban . iban_number } ` );
console . log ( `BIC: ${ euroAccount . deposit_instructions . iban . bic } ` );
}
Create SWIFT Virtual Account (International Wire)
import { isInternationalWireAccountDetails } from "@tolbel/align" ;
const swiftAccount = await align . virtualAccounts . create ( customerId , {
source_currency: "usd" ,
source_rails: "swift" ,
destination_token: "usdc" ,
destination_network: "polygon" ,
destination_address: "0x..." ,
});
if ( isInternationalWireAccountDetails ( swiftAccount . deposit_instructions )) {
console . log (
`SWIFT/BIC: ${ swiftAccount . deposit_instructions . international_wire . bic } `
);
console . log (
`Account: ${ swiftAccount . deposit_instructions . international_wire . account_number } `
);
}
Type-Safe Instruction Access : Since deposit_instructions is a
discriminated union, we recommend using the SDK’s built-in type guards to
safely narrow the type: - isUSAccountDetails(instr): For USD (ACH/Wire)
accounts. - isIBANAccountDetails(instr): For EUR (SEPA) accounts. -
isInternationalWireAccountDetails(instr): For USD (SWIFT) accounts.
Deposit Instructions
The deposit_instructions field contains the banking details. It is a union type:
US Account (ACH/Wire)
{
"currency" : "usd" ,
"bank_name" : "Example Bank" ,
"us" : {
"account_number" : "123456789" ,
"routing_number" : "021000021"
}
}
IBAN Account (SEPA)
{
"currency" : "eur" ,
"bank_name" : "Commerzbank" ,
"iban" : {
"iban_number" : "DE89370400440532013000" ,
"bic" : "COBADEFFXXX"
}
}
Supported Configurations
Source Currency Destination Token Destination Networks USD USDC, USDT Polygon, Ethereum, Base, Arbitrum, Solana EUR USDC Polygon, Ethereum, Base AED USDC Polygon, Ethereum
Error Handling
import { AlignError , AlignValidationError } from "@tolbel/align" ;
try {
const account = await align . virtualAccounts . create ( customerId , {
source_currency: "usd" ,
destination_token: "usdc" ,
destination_network: "polygon" ,
destination_address: "0x..." ,
});
} catch ( error ) {
if ( error instanceof AlignValidationError ) {
console . error ( "Invalid request:" , error . errors );
} else if ( error instanceof AlignError ) {
if ( error . statusCode === 403 ) {
console . error ( "KYC verification required" );
}
}
}
Creating a virtual account will fail with a 403 error if the customer hasn’t
completed KYC verification.
Get Virtual Account Retrieve account details
List Virtual Accounts List all customer accounts
Simulate Deposit Test deposits in sandbox