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

# Create Virtual Account V3 (Coming soon)

> Create a virtual bank account for a specific customer to convert fiat deposits to crypto. The `customer_id` path parameter identifies the customer for whom the virtual account is being created. V3 adds `source.bank` so you can choose the banking partner that issues the account, and returns the destination and banking partner on the create response.

<Warning>
  This endpoint is not available in production yet. It is documented so you can plan your
  integration ahead of release. Contact support for availability.
</Warning>

<Note>
  * Check all the supported fiat and crypto rails and currencies, along with the valid combinations, in [Supported rails and currencies](https://developer.fin.com/guides/others/supported-rails-and-currencies).
  * The available rails and currencies depend on the configuration set up for you. Contact support to know more.
</Note>

## What changed from V2

| Change              | Detail                                                                                                                          |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------ |
| `source.bank` added | Required. Selects the banking partner that issues the account.                                                                  |
| Response body       | Now returns `deposit_instructions`, `destination`, and `bank`. `customer_id` and `created_at` are no longer returned on create. |

[Create Virtual Account V2](https://developer.fin.com/api-reference/virtual-accounts/create-virtual-account-v2) continues to work and is unchanged. Use V3 for new integrations once it is available.

## Choosing a banking partner

`source.bank` selects the banking partner that issues the virtual account and receives the customer's fiat deposit. The accepted values are `SSB` and `PORTAGE`.

## Duplicate accounts

A customer can hold only one virtual account per source currency and rail. Requesting one that already exists returns `422` with the colliding `customer_id` and `source` in `errors`, along with the `virtual_account_id` of the existing account. Use that account instead of retrying the create call.


## OpenAPI

````yaml POST /v3/customers/{customer_id}/virtual-accounts
openapi: 3.1.0
info:
  title: Fin.com API
  version: 1.0.0
  description: >-
    A simple API specification for Fin.com, a financial services platform that
    provides a range of banking and payment solutions for businesses and
    individuals. This API allows developers to integrate Fin.com's services into
    their applications, enabling functionalities such as customer management,
    transaction processing, and access to financial data.
servers:
  - url: https://sandbox.api.fin.com
    description: Sandbox server
  - url: https://api.fin.com
    description: Production server
security: []
tags:
  - name: Authentication
    description: A modified OAuth 2.0 Client Credential Flow
  - name: Customers
    description: Customer management and document upload operations
  - name: Balances
    description: Retrieve wallet balance information
  - name: Catalogue
    description: |
      A set of endpoints to retrieve contextual data to assemble requests
      to fin.com's API
  - name: Beneficiaries
    description: Manage beneficiary accounts for payments and transfers
  - name: Transactions
    description: Transaction history and management for beneficiaries
  - name: Virtual Accounts
    description: Create and manage virtual accounts for USD to USDC conversions
  - name: Fees & FX Rates
    description: Retrieve fees and foreign exchange rates
paths:
  /v3/customers/{customer_id}/virtual-accounts:
    post:
      tags:
        - Virtual Accounts
      summary: Create Virtual Account V3 (Coming soon)
      description: >-
        Create a virtual bank account for a specific customer to convert fiat
        deposits to crypto. The `customer_id` path parameter identifies the
        customer for whom the virtual account is being created. V3 adds
        `source.bank` so you can choose the banking partner that issues the
        account, and returns the destination and banking partner on the create
        response.
      operationId: createVirtualAccountV3
      parameters:
        - name: customer_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: Unique identifier of the customer to create the virtual account for.
          example: ed54db74-7dbe-47d2-8ea0-c2bf2a9dda06
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - destination
                - source
                - developer_fee
              properties:
                destination:
                  type: object
                  required:
                    - wallet
                    - currency
                    - rail
                  properties:
                    wallet:
                      type: string
                      description: >-
                        Destination wallet address. The address format depends
                        on the rail. Ethereum, Base, and Polygon use hexadecimal
                        (0x...), and Solana uses base58.
                      example: '0x7A3f5C21b9E04d8a6C15fB3e920D74Ac815b6E39'
                    currency:
                      type: string
                      enum:
                        - USDC
                        - USDT
                        - EURC
                      description: >-
                        Token delivered to the destination wallet. Availability
                        depends on both the rail and the source rail. See
                        [Supported rails and
                        currencies](https://developer.fin.com/guides/others/supported-rails-and-currencies)
                        for valid combinations.
                      example: USDC
                    rail:
                      type: string
                      enum:
                        - POLYGON
                        - ETHEREUM
                        - SOLANA
                        - BASE
                      description: >-
                        Blockchain network for the destination wallet. Not every
                        token is issued on every network. See [Supported rails
                        and
                        currencies](https://developer.fin.com/guides/others/supported-rails-and-currencies)
                        for valid combinations.
                      example: ETHEREUM
                source:
                  type: object
                  required:
                    - currency
                    - rail
                    - bank
                  properties:
                    currency:
                      type: string
                      enum:
                        - USD
                        - EUR
                        - MXN
                      description: >-
                        Fiat currency of the incoming deposit. Each source rail
                        settles in a single currency.
                      example: USD
                    rail:
                      type: string
                      enum:
                        - ACH
                        - SWIFT
                        - FEDWIRE
                        - FEDNOW
                        - SEPA
                        - SPEI
                      description: >-
                        Fiat payment rail used to fund the virtual account. ACH,
                        Fedwire, and FedNow settle USD domestically, SWIFT
                        settles USD internationally, SEPA settles EUR, and SPEI
                        settles MXN.
                      example: FEDWIRE
                    bank:
                      type: string
                      enum:
                        - SSB
                        - PORTAGE
                      description: >-
                        Banking partner that issues the virtual account and
                        receives the fiat deposit. The banks available to you
                        depend on your configuration, and not every bank
                        supports every source rail. Contact support to find out
                        which banks are enabled for your account.
                      example: SSB
                developer_fee:
                  type: object
                  required:
                    - percentage
                    - fixed
                  properties:
                    fixed:
                      type: number
                      example: 0
                    percentage:
                      type: number
                      example: 0
            example:
              destination:
                wallet: '0x7A3f5C21b9E04d8a6C15fB3e920D74Ac815b6E39'
                currency: USDC
                rail: ETHEREUM
              source:
                currency: USD
                rail: FEDWIRE
                bank: SSB
              developer_fee:
                fixed: 0
                percentage: 0
      responses:
        '200':
          description: Virtual account created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        description: Unique identifier of the virtual account.
                        example: 9d2b7f41-6c8a-45e3-b071-2fa93c5e8d16
                      status:
                        type: string
                        enum:
                          - PROCESSING
                          - IN_COMPLIANCE
                          - REQUEST_FOR_INFORMATION
                          - ACTIVE
                          - INACTIVE
                          - DECLINED
                        description: >-
                          Current state of the virtual account. A newly created
                          account is always returned as `PROCESSING`, and
                          `deposit_instructions` stays null, until the banking
                          partner issues the account. Once the bank issues it,
                          the status moves to `ACTIVE` and the deposit
                          instructions are populated. Poll [List Virtual
                          Accounts](https://developer.fin.com/api-reference/virtual-accounts/list-virtual-accounts-v2)
                          or listen for the virtual account webhooks to pick up
                          the change.
                        example: PROCESSING
                      deposit_instructions:
                        type: object
                        nullable: true
                        description: >-
                          Bank details the customer deposits into. Null until
                          the account becomes `ACTIVE`, so it is always null on
                          the create response.
                        properties:
                          currency:
                            type: string
                            example: USD
                          bank_name:
                            type: string
                            example: Bank of Nowhere
                          bank_address:
                            type: string
                            example: 1800 North Pole St., Orlando, FL 32801
                          bank_routing_number:
                            type: string
                            example: '101019644'
                          bank_account_number:
                            type: string
                            example: '2611508020'
                          payment_rails:
                            type: array
                            items:
                              type: string
                            example:
                              - ACH
                              - FEDWIRE
                          bank_country:
                            type: string
                            nullable: true
                            example: null
                          account_type:
                            type: string
                            nullable: true
                            example: null
                          bank_code:
                            type: string
                            nullable: true
                            example: null
                      destination:
                        type: object
                        description: >-
                          Crypto destination the deposits settle to, echoed back
                          from the request.
                        properties:
                          currency:
                            type: string
                            enum:
                              - USDC
                              - USDT
                              - EURC
                            example: USDC
                          destination_chain:
                            type: string
                            enum:
                              - POLYGON
                              - ETHEREUM
                              - SOLANA
                              - BASE
                            example: ETHEREUM
                          address:
                            type: string
                            example: '0x4E91c07aB35d2F6810b94Ce7d13A5f826c0D4b7E'
                      bank:
                        type: string
                        enum:
                          - SSB
                          - PORTAGE
                        description: >-
                          Banking partner that issues the virtual account,
                          echoed back from the request.
                        example: SSB
                      rfi:
                        type: object
                        nullable: true
                        description: >-
                          Populated only when the status is
                          `REQUEST_FOR_INFORMATION`.
                        example: null
              examples:
                OK:
                  summary: OK
                  value:
                    data:
                      id: 9d2b7f41-6c8a-45e3-b071-2fa93c5e8d16
                      status: PROCESSING
                      deposit_instructions: null
                      destination:
                        currency: USDC
                        destination_chain: ETHEREUM
                        address: '0x4E91c07aB35d2F6810b94Ce7d13A5f826c0D4b7E'
                      bank: SSB
                      rfi: null
        '401':
          $ref: '#/components/responses/AuthenticationError'
        '422':
          description: >-
            The request failed validation. This includes the case where a
            virtual account already exists for the same customer and source
            combination.
          content:
            application/json:
              schema:
                type: object
                required:
                  - message
                properties:
                  errors:
                    type: array
                    description: >-
                      Context for the failure. When a virtual account already
                      exists, this holds the customer and source that collided,
                      followed by the identifier of the account that already
                      covers them.
                    items:
                      type: object
                      properties:
                        customer_id:
                          type: string
                          format: uuid
                          description: Customer the request was made for.
                          example: c1f4a8e2-3b57-4d09-9a61-7e2b5c8d4f30
                        source:
                          type: object
                          description: >-
                            Source currency and rail that already has a virtual
                            account.
                          properties:
                            currency:
                              type: string
                              example: USD
                            rail:
                              type: string
                              example: FEDWIRE
                        virtual_account_id:
                          type: string
                          format: uuid
                          description: >-
                            Identifier of the virtual account that already
                            exists. Use this account rather than creating
                            another one.
                          example: 9d2b7f41-6c8a-45e3-b071-2fa93c5e8d16
                  message:
                    type: string
                    description: Summary of why the request failed.
                    example: Virtual account already exists for the given parameters.
              examples:
                DuplicateVirtualAccount:
                  summary: Virtual account already exists
                  value:
                    errors:
                      - customer_id: c1f4a8e2-3b57-4d09-9a61-7e2b5c8d4f30
                        source:
                          currency: USD
                          rail: FEDWIRE
                      - virtual_account_id: 9d2b7f41-6c8a-45e3-b071-2fa93c5e8d16
                    message: Virtual account already exists for the given parameters.
      security:
        - bearerAuth: []
components:
  responses:
    AuthenticationError:
      description: Authentication failed due to invalid credentials
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                example: Authentication failed
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Bearer token authentication. Obtain token from [Issue a
        Token](https://developer.fin.com/api-reference/authentication/issue-a-token)
        endpoint

````