> ## Documentation Index
> Fetch the complete documentation index at: https://align.tolbel.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Virtual Account

> Create a virtual bank account for seamless fiat deposits

<Info>
  Virtual accounts require the customer to have completed KYC verification. See
  [Create KYC Session](/docs/api/customers/create-kyc-session).
</Info>

## Method Signature

```typescript theme={null}
align.virtualAccounts.create(
  customerId: string,
  data: CreateVirtualAccountRequest
): Promise<VirtualAccount>
```

## Parameters

<ParamField path="customerId" type="string" required>
  The unique customer identifier (UUID format)
</ParamField>

<ParamField body="source_currency" type="'usd' | 'eur' | 'aed'" required>
  Fiat currency for deposits
</ParamField>

<ParamField body="source_rails" type="'swift'">
  Optional payment rails. Currently only `swift` is supported (for USD).
</ParamField>

<ParamField body="destination_token" type="'usdc' | 'usdt'" required>
  Cryptocurrency token to receive
</ParamField>

<ParamField body="destination_network" type="string" required>
  Blockchain network: `polygon`, `ethereum`, `solana`, `base`, `arbitrum`,
  `tron`
</ParamField>

<ParamField body="destination_address" type="string" required>
  Wallet address to receive converted crypto.
</ParamField>

## Returns

<ResponseField name="id" type="string">
  Unique identifier for the virtual account
</ResponseField>

<ResponseField name="status" type="string">
  Account status: `active`
</ResponseField>

<ResponseField name="deposit_instructions" type="object">
  Bank account details for depositing funds. Structure varies by currency/type.
</ResponseField>

## Examples

### Create USD Virtual Account

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    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}`);
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    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);
    }
    ```
  </Tab>
</Tabs>

### Create EUR Virtual Account (SEPA/IBAN)

```typescript theme={null}
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)

```typescript theme={null}
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}`
  );
}
```

<Tip>
  **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.
</Tip>

## Deposit Instructions

The `deposit_instructions` field contains the banking details. It is a union type:

### US Account (ACH/Wire)

```json theme={null}
{
  "currency": "usd",
  "bank_name": "Example Bank",
  "us": {
    "account_number": "123456789",
    "routing_number": "021000021"
  }
}
```

### IBAN Account (SEPA)

```json theme={null}
{
  "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

```typescript theme={null}
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");
    }
  }
}
```

<Warning>
  Creating a virtual account will fail with a 403 error if the customer hasn't
  completed KYC verification.
</Warning>

## Related Methods

<CardGroup cols={2}>
  <Card title="Get Virtual Account" icon="eye" href="/docs/api/virtual-accounts/get">
    Retrieve account details
  </Card>

  <Card title="List Virtual Accounts" icon="list" href="/docs/api/virtual-accounts/list">
    List all customer accounts
  </Card>

  <Card title="Simulate Deposit" icon="flask" href="/docs/api/virtual-accounts/simulate">
    Test deposits in sandbox
  </Card>
</CardGroup>
