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

> ## Agent Instructions
> Money amounts are always major-unit decimal strings (e.g. "1000.00"), never floats and never minor units, in every request, response, and webhook payload.
> Authentication is OAuth 2.0 client credentials: exchange the Client ID and Client Secret at the Token URL for a 24-hour JWT and cache it; do not request a token per call.
> Set a unique clientRef on every money-moving request; it is the idempotency key, and retries return the original resource.
> Quotes are single-use, intent-locked, and expire fast: always read expiresAt, consume the quote with the executor matching its intent, and re-quote on expiry instead of retrying.
> Prefer webhooks over polling for payout, order, and deposit status tracking.
> Use the sandbox (api.sandbox.zuba.com) with its deterministic magic values before touching production.

# Create (or return) my standing virtual account

> Issues one durable collection account for the requested currency, owned by your master account — or by the sub-account named in `Zuba-Account-Id`, whose deposits then settle into that sub-account's balance. Idempotent per owner and currency: if a live account already exists it is returned with `201 → 200`. Some accounts are issued asynchronously and return `status: pending`; poll `GET /v1/virtual-accounts` until `active`. Requires the owner's application to be approved.



## OpenAPI

````yaml /openapi.json post /v1/virtual-accounts
openapi: 3.0.0
info:
  contact: {}
  description: >-
    Comprehensive payment platform API supporting fiat and crypto payments,
    currency conversion, and compliance management
  title: Zuba Payment Platform API
  version: '1.0'
servers: []
security: []
tags:
  - description: Manage M2M API keys and credentials
    name: API Keys
  - description: Internal ledger accounts and transactions
    name: Ledger
  - description: Handle incoming payments and deposits
    name: Pay-ins
  - description: Manage payouts, beneficiaries, and SEPA transfers
    name: Payouts
  - description: Manage outbound webhook endpoints and deliveries
    name: Webhooks
paths:
  /v1/virtual-accounts:
    post:
      tags:
        - Virtual Accounts
      summary: Create (or return) my standing virtual account
      description: >-
        Issues one durable collection account for the requested currency, owned
        by your master account — or by the sub-account named in
        `Zuba-Account-Id`, whose deposits then settle into that sub-account's
        balance. Idempotent per owner and currency: if a live account already
        exists it is returned with `201 → 200`. Some accounts are issued
        asynchronously and return `status: pending`; poll `GET
        /v1/virtual-accounts` until `active`. Requires the owner's application
        to be approved.
      operationId: VirtualAccountMerchantController_createMyVirtualAccount
      parameters:
        - description: >-
            Optional. Names an owned sub-account (UUID) to act on. Omit to act
            at the master (tenant) level. Naming an account this key does not
            own returns 403 not_account_owner.
          in: header
          name: Zuba-Account-Id
          required: false
          schema:
            format: uuid
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMyVirtualAccountDto'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccountResponseDto'
          description: A live account already existed for this owner + currency
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccountResponseDto'
          description: Standing virtual account issued (may be pending)
        '401':
          description: Unauthorized
        '403':
          description: >-
            Insufficient role, API key missing the create:virtual-accounts
            scope, not_account_owner (Zuba-Account-Id does not name an account
            you own), or METHOD_NOT_ENTITLED (virtual accounts in this currency
            are not enabled for you).
        '409':
          description: >-
            KYB_REQUIRED / KYB_INCOMPLETE (the owner has no approved or complete
            application), or a concurrent issuance won the slot, or
            ACCOUNT_NOT_ACTIVE (the sub-account cannot receive funds yet).
        '422':
          description: >-
            VIRTUAL_ACCOUNT_CURRENCY_NOT_SUPPORTED,
            VIRTUAL_ACCOUNT_SELF_SERVE_UNSUPPORTED, or COUNTRY_REQUIRED (the
            currency is collected in more than one country — pass "country").
        '502':
          description: Provider request failed
      security:
        - bearer: []
components:
  schemas:
    CreateMyVirtualAccountDto:
      properties:
        country:
          description: >-
            ISO 3166-1 alpha-2 country the money is collected in. Required for
            currencies collected in more than one country (e.g. XOF); ignored
            otherwise.
          example: SN
          type: string
        currency:
          description: >-
            ISO-4217 currency of the standing account. One live account per
            owner and currency; repeating a request returns the existing
            account.
          example: EUR
          type: string
      required:
        - currency
      type: object
    VirtualAccountResponseDto:
      properties:
        accountId:
          description: Owning sub-account; null for the client master account.
          format: uuid
          nullable: true
          type: string
        accountName:
          description: 'Account name (format: "Zuba {Merchant Name}")'
          example: Zuba John Doe
          nullable: true
          type: string
        accountNumber:
          description: Virtual account number
          example: '8012345678'
          nullable: true
          type: string
        accountType:
          description: Account type
          example: fixed_va
          type: string
        bankAddress:
          description: Institution or branch address supplied by the provider.
          nullable: true
          type: string
        bankName:
          description: Bank name where the virtual account is held
          example: Wema Bank
          nullable: true
          type: string
        clientId:
          description: Client ID this virtual account belongs to
          example: 456e7890-e89b-12d3-a456-426614174000
          format: uuid
          type: string
        country:
          description: ISO 3166-1 alpha-2 country of the receiving account.
          nullable: true
          type: string
        createdAt:
          description: Creation timestamp
          example: '2024-01-15T10:30:00.000Z'
          format: date-time
          type: string
        currency:
          description: Currency of the virtual account
          example: NGN
          type: string
        displayName:
          description: Operator-facing label sent to the provider.
          nullable: true
          type: string
        enabled:
          description: >-
            Routing eligibility. False for failed or incomplete provider
            workflows.
          type: boolean
        iban:
          description: >-
            IBAN for the account — the GB IBAN for a GBP SCAN account (whose
            accountNumber is the SCAN number), or the primary IBAN for EUR. Null
            when the account exposes no IBAN.
          example: GB50IKMA24711059277481
          nullable: true
          type: string
        id:
          description: Unique identifier for the virtual account
          example: 123e4567-e89b-12d3-a456-426614174000
          format: uuid
          type: string
        providerStatus:
          description: Raw provider account status when supplied.
          nullable: true
          type: string
        provisioningStatus:
          description: Asynchronous provisioning workflow status when supplied.
          nullable: true
          type: string
        routingNumber:
          description: >-
            Routing number for USD wire accounts (US ABA). Null for accounts
            without one (e.g. EUR/GBP).
          example: '138344690'
          nullable: true
          type: string
        sortCode:
          description: >-
            Sort code for GBP SCAN accounts (UK Faster Payments). Null for
            accounts without one (e.g. EUR/IBAN accounts).
          example: '247110'
          nullable: true
          type: string
        status:
          description: Current status of the virtual account
          enum:
            - pending
            - active
            - inactive
          example: active
          type: string
        updatedAt:
          description: Last update timestamp
          format: date-time
          type: string
        updatedBy:
          nullable: true
          type: string
      required:
        - id
        - clientId
        - currency
        - accountNumber
        - accountName
        - bankName
        - accountType
        - status
        - enabled
        - createdAt
        - updatedAt
      type: object
  securitySchemes:
    bearer:
      bearerFormat: JWT
      description: Enter Auth0 JWT token
      scheme: bearer
      type: http

````