VirtuaBroker API (1.0.0)

Download OpenAPI specification:

This API lets you integrate with VirtuaBroker as a partner or B2B client: automate quotes, orders, deposits, balances, withdrawals, and webhooks using stable JSON contracts.

Core concepts

  • Quote — a real-time price lock for a currency pair. No customer identity needed at this step. Quotes expire after a short window.
  • Order — binds a quote to a customer and executes the full flow: receive origin funds → convert at the quoted rate → pay out to the destination address.
  • Deposit — how funds enter the platform. For crypto, the API returns an on-chain address; for fiat, a reference/IBAN. Once the inbound transfer is detected, the user's balance is credited.
  • Withdrawal — a standalone payout from an existing balance to a fiat or crypto destination. For trade-then-pay flows, use an order instead.

Integration surface

  • Quotes and pricing
  • Orders and deposits (create, list, and track status)
  • Balances
  • Payouts — via an order's destination leg or directly from balance with POST /v1/withdrawals
  • KYC/KYB-related endpoints where enabled for your workspace
  • Webhooks (register a callback URL and handle event payloads)

Authentication

Requests use OAuth 2.0. Obtain an access token by POSTing to:

https://auth2.virtuabroker.com/realms/cryptobot/protocol/openid-connect/token

Request Details

  • Content-Type: application/x-www-form-urlencoded
  • Request Body Parameters:
    • client_id: Your client identifier (provided by VirtuaBroker)
    • username: Your account's username (provided by VirtuaBroker)
    • password: Your account's password (provided by VirtuaBroker)
    • grant_type: Use password as the grant type

Upon successful authentication, you will receive an access_token which must be included in the Authorization header as a Bearer token for all subsequent API calls.

Example Code Snippet

Here's a simple example of how to request an access token using Node.js and axios:

import axios from 'axios';
import qs from 'qs';

const authUrl = 'https://auth2.virtuabroker.com/realms/cryptobot/protocol/openid-connect/token';
const clientId = 'your-client-id';
const username = 'your-username';
const password = 'your-password';

const requestToken = async () => {
  const requestBody = qs.stringify({
    client_id: clientId,
    username,
    password,
    grant_type: 'password'
  });

  try {
    const response = await axios.post(authUrl, requestBody, {
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    });
    
    const accessToken = response.data.access_token;
    console.log('Access Token:', accessToken);
    return accessToken;
  } catch (error) {
    console.error('Failed to fetch token', error);
    throw error;
  }
};

Integration testing

In sandbox or stage environments, you can simulate inbound payments using POST /v1/simulate/incoming-transfer. See that endpoint's documentation for full details.

Further Assistance

If you are interested in integrating with the VirtuaBroker platform or need specific credentials for authentication, please contact our support team at integrations@virtuabroker.com. We are here to assist you with any questions or issues you may encounter during the integration process.

Webhooks

Handle webhook events Webhook

Your server receives POST requests with the WebhookRequest schema: type, id, api_version (e.g. 1.0), apiKey, and data. Event types cover deposits, trades, withdrawals, order status, open-banking payment status, and identity verification. Recommended: handle verification_status_updated for KYC and KYB (data.verificationType is KYC or KYB). kyc_completed is deprecated (may still be sent); new integrations should not rely on it. If you receive multiple events for the same outcome, deduplicate using stable fields in data (e.g. entity identifiers) together with type. Return any 2xx response to acknowledge receipt.

Request Body schema: application/json
required
string or string or string or string or string or string or string or string

Webhook event category; determines the shape of data.

id
required
string

ID of the webhook event

api_version
required
string

API version of the webhook event

apiKey
required
string

Provided API key by you so we can authenticate incoming requests coming to your webhook endpoint

required
object or object or object or object or object or object or object or object

Data associated with the webhook event

Responses

Request samples

Content type
application/json
{
  • "type": "verification_status_updated",
  • "id": "evt_123456",
  • "api_version": "1.0",
  • "apiKey": "xxx",
  • "data": {
    }
}

Get webhook configuration

Returns your registered webhook callback URL plus createdAt and updatedAt timestamps for that configuration.

Incoming events: your server should accept POST bodies matching the WebhookRequest schema (see Webhooks → incoming events). For identity verification, handle verification_status_updated first; treat kyc_completed as deprecated but it may still be sent for backward compatibility.

Authorizations:
oauth2

Responses

Response samples

Content type
application/json
{}

Update webhook configuration

Updates your webhook callback URL for this integration. Integration tip: implement a handler for the WebhookRequest shape; for KYC/KYB prefer verification_status_updated. Treat kyc_completed as legacy (see WebhookEventType and WebhookRequest in schemas).

Authorizations:
oauth2
Request Body schema: application/json
url
required
string <uri>

New webhook URL for the client

Responses

Request samples

Content type
application/json

Response samples

Content type
application/json
{}

Pairs

Get available pairs

Returns the list of currency pairs available for quoting in the authenticated workspace (e.g. EUR/USDC, BRL/USDT). Use these pair strings as the originCurrency/destinationCurrency inputs when creating a quote.

Authorizations:
oauth2

Responses

Response samples

Content type
application/json
{
  • "pairs": [
    ]
}

Quotes

Create a quote

Creates a real-time price quote for a currency pair. Quotes are workspace-scoped and user-agnostic — no customer identity is required at this step.

Two-step B2C flow

Step 1 — Create a quote POST /v1/quotes

Provide the currency pair, rails, and either originAmount or destinationAmount. The response includes a quoteId, the locked exchange rate, expected fees, and expiry time.

Step 2 — Create an order POST /v1/orders

Pass the quoteId from step 1 together with the customer's identity in userData.userEmail (and KYC data if required). This is where the end customer is associated with the transaction.

Important

  • Quotes expire after a short window; create the order promptly after receiving the quote.
Authorizations:
oauth2
Request Body schema: application/json
Any of
required
string or string

The currency code of the origin currency

originRail
string
Enum: "BALANCE" "SEPA" "BTC" "ETH" "MATIC" "POLYGON" "CELO" "TRON" "SOLANA" "ARBITRUM" "OPTIMISM" "AVALANCHE" "BSC" "BASE" "XRP" "PIX_BR" "UPI" "IMPS" "TRY_BANK_TRANSFER" "AED_BANK_TRANSFER" "SPEI" "IDR_BANK_TRANSFER" "CREDIT_CARD" "THAI_QR" "VIET_QR" "GCASH" "ARGENTINA_BANK_TRANSFER" "PSE" "BANK_DEPOSIT_COL"

The rail of the origin currency

destinationCurrency
required
string
Enum: "EUR" "BRL" "VES" "USDC" "USDT" "ETH" "BTC" "MATIC" "CELO" "SOL" "TRX" "AVAX" "DOT" "XRP" "POL" "ADA" "ALGO" "PHP" "TRY" "INR" "VND" "THB" "AED" "BRL" "COP" "MXN" "ARS" "CLP" "PEN" "DOP"

The currency code of the destination currency

destinationRail
string
Enum: "SEPA" "ETH" "BTC" "MATIC" "SOL" "TRON" "PIX_BR" "PHONE_DEPOSIT_VEN" "PHONE_DEPOSIT_MX" "PHONE_DEPOSIT_AR" "PHONE_DEPOSIT_IN" "PHONE_DEPOSIT_VN" "PHONE_DEPOSIT_KE" "PHONE_DEPOSIT_NG" "BANK_DEPOSIT_VEN" "BANK_DEPOSIT_BR" "BALANCE" "CELO" "UPI" "IMPS" "THAI_QR" "VIET_QR" "GCASH" "ARGENTINA_BANK_TRANSFER" "PSE" "BANK_DEPOSIT_COL"

The rail of the destination currency

locale
string
Enum: "en" "es" "pt" "it" "fr" "de"

The locale of the user

originAmount
required
number > 0

The amount in the origin currency (use either originAmount or destinationAmount)

Responses

Request samples

Content type
application/json
{
  • "originCurrency": "EUR",
  • "originRail": "BALANCE",
  • "destinationCurrency": "VES",
  • "destinationRail": "SEPA",
  • "locale": "en",
  • "destinationAmount": 85
}

Response samples

Content type
application/json
{
  • "quoteId": "123e4567-e89b-12d3-a456-426614174000",
  • "originCurrency": "EUR",
  • "originNetwork": "MATIC",
  • "originAmount": 100,
  • "destinationCurrency": "BRL",
  • "destinationNetwork": "MATIC",
  • "destinationAmount": 85,
  • "price": 0.85,
  • "conversionRate": 0.85,
  • "pair": "USDC/EUR",
  • "fee": 1.5,
  • "expectedGasFee": 1.5,
  • "feeCurrency": "EUR",
  • "expireAt": 1694291200
}

Balances

Get user balances

This endpoint returns the balances for different currencies associated with a user. The user can optionally filter by a specific currency or email.

Authorizations:
oauth2
query Parameters
string or string
Examples: currency=EUR

Currency code to filter the balances

userEmail
string <email>
Examples: userEmail=user@virtuabroker.com userEmail=john.doe@example.com userEmail=alice@crypto.io

User email to filter the balances

Responses

Response samples

Content type
application/json
{
  • "balances": [
    ]
}

Deposits

Create a deposit

Creates a new deposit request, returning the payment instructions the end user must follow to fund their account.

How deposits work

  1. Call POST /v1/deposits with the currency, amount, and customer data.
  2. The response contains the payment instructions:
    • Crypto — an on-chain address (and network) where the user must send funds.
    • Fiat — a bank reference or IBAN the user must transfer to.
  3. Once the inbound transfer is detected on-chain or reported by the bank, the user's balance is credited automatically.

v1 vs v2

  • v1 (POST /v1/deposits) — standard deposit; requires name, email, country, and KYC id.
  • v2 (POST /v2/deposits) — extended; additionally requires city, postalCode, and dob (YYYY-MM-DD). Use v2 when your corridor or funding method mandates full address and date of birth.
Authorizations:
oauth2
Request Body schema: application/json
Any of
amount
required
number > 0

Amount to be deposited

currency
required
string
Enum: "USDC" "USDT" "CUSD" "BTC" "ETH" "POL" "SOL" "TRX" "AVAX" "XRP" "BNB"

Currency of the deposit

required
string or string
object or object

User data of the person/company making the deposit

userDataId
string

Account ID of the person/company making the deposit

Responses

Request samples

Content type
application/json
{
  • "amount": 100,
  • "currency": "EUR",
  • "rail": "SEPA",
  • "userData": {
    },
  • "userDataId": "string"
}

Response samples

Content type
application/json
{
  • "depositId": "01CLFXMT67II",
  • "userData": {
    },
  • "createdAt": 1723027132,
  • "rail": "BALANCE",
  • "receivedAt": 1723027132,
  • "expectedAmount": 1000,
  • "amount": 1000,
  • "currency": "EUR",
  • "fee": 10,
  • "expectedFee": 10,
  • "feeCurrency": "EUR",
  • "status": "Pending",
  • "depositInfo": {
    },
  • "depositInfoPending": true,
  • "openbanking": {
    }
}

List deposits

This endpoint retrieves a list of deposits based on various filters.

Authorizations:
oauth2
query Parameters
string or string
Examples: currency=EUR

Optional currency code to filter the deposits

minAmount
number >= 0
maxAmount
number >= 0
from
integer >= 0
to
integer >= 0
userEmail
string <email>
Example: userEmail=user@example.com

Email of the user making the request

search
string

General search (e.g. email or text). When provided, backend may use it for userEmail or text search.

limit
number >= 0
page
number >= 0
string or string or (Array of strings or strings)
Examples: status=Pending status=Pending&status=Success status=Pending&status=Processing&status=Success

Optional status to filter deposits. Can be a single status or an array of statuses for multiple filtering

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a deposit (v2)

Creates a new deposit request, returning the payment instructions the end user must follow to fund their account.

How deposits work

  1. Call POST /v1/deposits with the currency, amount, and customer data.
  2. The response contains the payment instructions:
    • Crypto — an on-chain address (and network) where the user must send funds.
    • Fiat — a bank reference or IBAN the user must transfer to.
  3. Once the inbound transfer is detected on-chain or reported by the bank, the user's balance is credited automatically.

v1 vs v2

  • v1 (POST /v1/deposits) — standard deposit; requires name, email, country, and KYC id.
  • v2 (POST /v2/deposits) — extended; additionally requires city, postalCode, and dob (YYYY-MM-DD). Use v2 when your corridor or funding method mandates full address and date of birth.

v2 note: this variant additionally requires userData.city, userData.postalCode, and userData.dob (YYYY-MM-DD). Use v2 when possible.

Authorizations:
oauth2
Request Body schema: application/json
object or object
userDataId
string

User data ID of the person/company making the deposit

amount
required
number > 0

Amount to be deposited

required
string or string

Currency of the deposit

rail
string
Enum: "BALANCE" "SEPA" "BTC" "ETH" "MATIC" "POLYGON" "CELO" "TRON" "SOLANA" "ARBITRUM" "OPTIMISM" "AVALANCHE" "BSC" "BASE" "XRP" "PIX_BR" "UPI" "IMPS" "TRY_BANK_TRANSFER" "AED_BANK_TRANSFER" "SPEI" "IDR_BANK_TRANSFER" "CREDIT_CARD" "THAI_QR" "VIET_QR" "GCASH" "ARGENTINA_BANK_TRANSFER" "PSE" "BANK_DEPOSIT_COL"

Rail for the deposit for crypto deposits

Responses

Request samples

Content type
application/json
{
  • "userData": {
    },
  • "userDataId": "string",
  • "amount": 100,
  • "currency": "EUR",
  • "rail": "SEPA"
}

Response samples

Content type
application/json
{
  • "depositId": "01CLFXMT67II",
  • "userData": {
    },
  • "createdAt": 1723027132,
  • "rail": "BALANCE",
  • "receivedAt": 1723027132,
  • "expectedAmount": 1000,
  • "amount": 1000,
  • "currency": "EUR",
  • "fee": 10,
  • "expectedFee": 10,
  • "feeCurrency": "EUR",
  • "status": "Pending",
  • "depositInfo": {
    },
  • "depositInfoPending": true,
  • "openbanking": {
    }
}

Get deposit details

This endpoint retrieves details of a specific deposit.

Authorizations:
oauth2
path Parameters
depositId
required
string = 12 characters ^[A-Z0-9]+$
Examples: 01CLFXMT67II 2R7E5Y5KFXP8 4FWWRE3Y2URM

ID of the deposit

Responses

Response samples

Content type
application/json
{
  • "depositId": "01CLFXMT67II",
  • "userData": {
    },
  • "createdAt": 1723027132,
  • "rail": "BALANCE",
  • "receivedAt": 1723027132,
  • "expectedAmount": 1000,
  • "amount": 1000,
  • "currency": "EUR",
  • "fee": 10,
  • "expectedFee": 10,
  • "feeCurrency": "EUR",
  • "status": "Pending",
  • "depositInfo": {
    },
  • "depositInfoPending": true,
  • "openbanking": {
    }
}

Delete a deposit

This endpoint deletes a specific deposit.

Authorizations:
oauth2
path Parameters
depositId
required
string = 12 characters ^[A-Z0-9]+$
Examples: 01CLFXMT67II 2R7E5Y5KFXP8 4FWWRE3Y2URM

ID of the deposit

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "string"
}

Orders

Create an order

This endpoint creates a new order. The order follows a three-step flow:

  1. Origin — Receive the specified origin amount and currency (e.g. USDC on MATIC, EUR via SEPA).

  2. Trade execution — Once the origin funds are confirmed, the trade is executed at the quoted rate.

  3. Payout — After successful execution the destination funds are sent to the destinationTransferData address provided in the request (e.g. Venezuelan bank via BANK_DEPOSIT_VEN, phone payment via PHONE_DEPOSIT_VEN, Brazilian PIX via PIX_BR, or a crypto wallet address).

Important: For some currencies (e.g., INR), after the user completes the payment you must confirm the payin by calling POST /v1/orders/{orderId}/confirm-payin.

For a standalone payout from balance (without a trade) use POST /v1/withdrawals instead.

IMPS (India) UTR confirmation

  • If destinationTransferData.type is IMPS, after you complete the bank transfer you will receive a UTR (Unique Transaction Reference).
  • You must then confirm the payin by calling POST /v1/orders/{orderId}/confirm-payin and set referenceId to the received UTR.
Authorizations:
oauth2
Request Body schema: application/json
quoteId
required
string <uuid>

The unique identifier of the created quote

object or object

Required when the quote origin is not BALANCE (payer). If the payer email is new, include address, city, postalCode, state, country, firstName, lastName, taxId, kycId for deposit provisioning.

object or object

User data of the person/company that will receive the funds

Balance (object) or SEPA (object) or ETH (object) or MATIC (object) or SOL (object) or TRON (object) or CELO (object) or BTC (object) or SOLANA (object) or XRP (object) or CARDANO (object) or BSC (object) or ARBITRUM (object) or OPTIMISM (object) or AVALANCHE (object) or BASE (object) or Bank Deposit COL (object) or Bank Deposit BR (object) or PIX BR (object) or Bank Deposit VEN (object) or Phone Deposit VEN (object) or Bank Deposit IN (object) or IMPS (object) or Thai QR (object) or Viet QR (object) or GCash (object) or Mobile Payment IN (object) or Bank Deposit VN (object) or Bank Deposit AR (object) or Bank Deposit NG (object) or PSE (object)

The details required for the end user destination transfer method.

externalReference
string

External reference of the order

integrationSessionId
string^int_[A-Za-z0-9]{16}$

Integration session ID for partner attribution tracking

Responses

Request samples

Content type
application/json
{
  • "quoteId": "123e4567-e89b-12d3-a456-426614174000",
  • "userData": {
    },
  • "destinationUserData": {
    },
  • "destinationTransferData": {
    },
  • "externalReference": "string",
  • "integrationSessionId": "string"
}

Response samples

Content type
application/json
{
  • "orderId": "01CLFXMT67II",
  • "deposit": {
    },
  • "trade": {
    },
  • "withdraw": {
    },
  • "createdAt": 1723027132,
  • "updatedAt": 1723027132,
  • "status": "Pending",
  • "externalRefeference": "string",
  • "fee": 6.37,
  • "expectedFee": 6.88,
  • "expectedGasFee": 6.88,
  • "feeCurrency": "EUR"
}

List orders

This endpoint retrieves a list of orders based on various filters.

Authorizations:
oauth2
query Parameters
currency
string
Example: currency=EUR

Optional currency code to filter the items

minAmount
number >= 0
maxAmount
number >= 0
from
integer >= 0
to
integer >= 0
userEmail
string <email>
Example: userEmail=user@example.com

Email of the user making the request

search
string

General search (e.g. email or text). When provided, backend may use it for userEmail or text search.

limit
number >= 0
page
number >= 0
string or string or (Array of strings or strings)
Examples: status=Pending status=Pending&status=Success status=Pending&status=Processing&status=Success status=Received&status=Exchanging&status=Withdrawn

Optional status to filter orders. Can be a single status or an array of statuses for multiple filtering

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get order details

This endpoint retrieves details of a specific order.

Authorizations:
oauth2
path Parameters
orderId
required
string = 12 characters ^[A-Z0-9]+$
Examples: 01CLFXMT67II 2R7E5Y5KFXP8 4FWWRE3Y2URM

ID of the order

Responses

Response samples

Content type
application/json
{
  • "orderId": "01CLFXMT67II",
  • "deposit": {
    },
  • "trade": {
    },
  • "withdraw": {
    },
  • "createdAt": 1723027132,
  • "updatedAt": 1723027132,
  • "status": "Pending",
  • "externalRefeference": "string",
  • "fee": 6.37,
  • "expectedFee": 6.88,
  • "expectedGasFee": 6.88,
  • "feeCurrency": "EUR"
}

Delete an order

This endpoint deletes a specific order. The order must be in status PENDING.

Authorizations:
oauth2
path Parameters
orderId
required
string = 12 characters ^[A-Z0-9]+$
Examples: 01CLFXMT67II 2R7E5Y5KFXP8 4FWWRE3Y2URM

ID of the order

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "string"
}

Confirm payin for an order

This endpoint confirms a payin transaction for a specific order by providing the reference ID of the payment. For IMPS (India), provide the UTR you receive after completing the transfer as the referenceId.

Authorizations:
oauth2
path Parameters
orderId
required
string

ID of the order

Request Body schema: application/json
orderId
required
string = 12 characters ^[A-Z0-9]+$

ID of the order

referenceId
required
string

Reference ID of the payin, for India is the UTR given after the payment

Responses

Request samples

Content type
application/json
{
  • "orderId": "01CLFXMT67II",
  • "referenceId": "123"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "string"
}

KYC

Create KYC request

Starts or continues identity verification (KYC) for a user in your workspace. Request and response fields are documented on the CreateKYCRequest and CreateKYCResponse schemas.

Authorizations:
oauth2
Request Body schema: application/json
userEmail
required
string <email> [ 1 .. 254 ] characters ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

User email. Must match your workspace account onboarding rules.

userPhone
string

Optional. Required for some corridors (e.g. India, Turkey). Format: country code with +, a hyphen, then the number (e.g. +52-1234567890).

externalUserId
string

Optional. Your own user identifier in your system, if you track users externally.

countryCode
required
string
Enum: "AW" "AF" "AO" "AI" "AX" "AL" "AD" "AE" "AR" "AM" "AS" "AQ" "TF" "AG" "AU" "AT" "AZ" "BI" "BE" "BJ" "BQ" "BF" "BD" "BG" "BH" "BS" "BA" "BL" "BY" "BZ" "BM" "BO" "BR" "BB" "BN" "BT" "BV" "BW" "CF" "CA" "CC" "CH" "CL" "CN" "CI" "CM" "CD" "CG" "CK" "CO" "KM" "CV" "CR" "CU" "CW" "CX" "KY" "CY" "CZ" "DE" "DJ" "DM" "DK" "DO" "DZ" "EC" "EG" "ER" "EH" "ES" "EE" "ET" "FI" "FJ" "FK" "FR" "FO" "FM" "GA" "GB" "GE" "GG" "GH" "GI" "GN" "GP" "GM" "GW" "GQ" "GR" "GD" "GL" "GT" "GF" "GU" "GY" "HK" "HM" "HN" "HR" "HT" "HU" "ID" "IM" "IN" "IO" "IE" "IR" "IQ" "IS" "IL" "IT" "JM" "JE" "JO" "JP" "KZ" "KE" "KG" "KH" "KI" "KN" "KR" "KW" "LA" "LB" "LR" "LY" "LC" "LI" "LK" "LS" "LT" "LU" "LV" "MO" "MF" "MA" "MC" "MD" "MG" "MV" "MX" "MH" "MK" "ML" "MT" "MM" "ME" "MN" "MP" "MZ" "MR" "MS" "MQ" "MU" "MW" "MY" "YT" "NA" "NC" "NE" "NF" "NG" "NI" "NU" "NL" "NO" "NP" "NR" "NZ" "OM" "PK" "PA" "PN" "PE" "PH" "PW" "PG" "PL" "PR" "KP" "PT" "PY" "PS" "PF" "QA" "RE" "RO" "RU" "RW" "SA" "SD" "SN" "SG" "GS" "SH" "SJ" "SB" "SL" "SV" "SM" "SO" "PM" "RS" "SS" "ST" "SR" "SK" "SI" "SE" "SZ" "SX" "SC" "SY" "TC" "TD" "TG" "TH" "TJ" "TK" "TM" "TL" "TO" "TT" "TN" "TR" "TV" "TW" "TZ" "UG" "UA" "UM" "UY" "US" "UZ" "VA" "VC" "VE" "VG" "VI" "VN" "VU" "WF" "WS" "YE" "ZA" "ZM" "ZW"

ISO 3166-1 alpha-2 issuing country (e.g. ES, GB). Pre-selects the country in the hosted verification widget; the backend maps it to ISO alpha-3 for the provider WebSDK.

sendOTPMail
required
boolean

Whether to send an OTP email to the user. Exact behavior follows your integration contract with VirtuaBroker.

type
required
string
Enum: "INDIVIDUAL" "BUSINESS"

KYC category: INDIVIDUAL for a natural person or BUSINESS for a business flow, per your product setup.

language
string

Optional. Widget UI language and access-token locale (e.g. en, es, fr). If omitted or blank, en is used. Use codes supported by the verification provider WebSDK.

theme
string
Enum: "dark" "light"

Optional. Hosted widget theme for the provider WebSDK. Default: dark (omit or send dark). Send light only for light mode.

blank
boolean

Optional. If true, the hosted widget page uses blank framing (minimal chrome: no extra branding, borders, or padding around the iframe).

width
string

Optional. CSS width for the widget container on the hosted page (e.g. 100%, 800px, 1200px).

height
string

Optional. CSS height for the widget container on the hosted page (e.g. 100vh, 600px, auto).

forceMobile
boolean

Optional. If true, forces the verification widget to render its mobile layout regardless of the screen width.

Responses

Request samples

Content type
application/json
{
  • "userEmail": "user@example.com",
  • "userPhone": "string",
  • "externalUserId": "string",
  • "countryCode": "AW",
  • "sendOTPMail": true,
  • "type": "INDIVIDUAL",
  • "language": "string",
  • "theme": "dark",
  • "blank": true,
  • "width": "string",
  • "height": "string",
  • "forceMobile": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "kycUrl": "string",
  • "kycId": "string",
  • "userEmail": "string",
  • "missingInfo": {
    },
  • "status": "PENDING",
  • "errorMessage": "string"
}

Get KYC status by account email

Retrieves the KYC verification status for an account by email.

Authorizations:
oauth2
path Parameters
accountEmail
required
string <email> [ 1 .. 254 ] characters ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

Email address

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "value": {
    }
}

Get KYC status (deprecated) Deprecated

Deprecated: use GET /v1/kyc/{accountEmail} instead. Retrieves the KYC verification status for a user by query param.

Authorizations:
oauth2
query Parameters
userEmail
required
string <email> [ 1 .. 254 ] characters ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

User email

Responses

Response samples

Content type
application/json
{
  • "status": "PENDING",
  • "missingInfo": {
    },
  • "message": "string"
}

Openbanking

Create Openbanking payment

Creates a hosted open-banking payment session (Web Form) for an order or deposit. Amount, currency, and payee details are taken from the order or deposit. Optionally send a language code for the form UI.

Authorizations:
oauth2
path Parameters
orderId
required
string

ID of the order or deposit

Request Body schema: application/json
language
string

Language code for the form (e.g., en, de, es)

Responses

Request samples

Content type
application/json
{
  • "language": "string"
}

Response samples

Content type
application/json
{
  • "orderId": "01CLFXMT67II",
  • "webForm": {},
  • "embed": {
    },
  • "usage": {
    }
}

Get Openbanking payment status

Returns the status of an open-banking payment for a given order or deposit id (the same id used when creating the session). The response includes session status and, when available, the latest callback details.

Authorizations:
oauth2
path Parameters
orderId
required
string

Order id or deposit id (query/path; same identifier used when creating the Web Form)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "orderId": "string",
  • "openbanking": {
    },
  • "metadata": {
    },
  • "note": "string"
}

Withdrawals

Create a withdrawal (payout from balance)

Creates a payout from the user's available balance. The balance is validated and reserved atomically before processing.

Payout paths: (a) this endpoint pays out directly from an existing balance; (b) for a trade-then-payout flow use POST /v1/orders instead (quote → order with destinationTransferData).

destinationTransferData.type must match the payout rail — representative values:

  • SEPA — EUR bank transfer (IBAN required).
  • PIX_BR — Brazilian PIX instant transfer; BANK_DEPOSIT_BR for TED/DOC.
  • BANK_DEPOSIT_VEN — Venezuelan bank transfer (account number + bank code + tax ID).
  • PHONE_DEPOSIT_VEN — Venezuelan phone-based payout (phone number + bank code + tax ID).
  • Crypto: use the network name as type (e.g. MATIC, ETH, TRON) with an address field.
Authorizations:
oauth2
Request Body schema: application/json
amount
required
number > 0

Amount to be withdrawn

currency
required
string

Currency of the withdrawal

userEmail
required
string <email>

Email of the user making the request

destinationTranferId
string

ID of the destination transfer method

Balance (object) or SEPA (object) or ETH (object) or MATIC (object) or SOL (object) or TRON (object) or CELO (object) or BTC (object) or SOLANA (object) or XRP (object) or CARDANO (object) or BSC (object) or ARBITRUM (object) or OPTIMISM (object) or AVALANCHE (object) or BASE (object) or Bank Deposit COL (object) or Bank Deposit BR (object) or PIX BR (object) or Bank Deposit VEN (object) or Phone Deposit VEN (object) or Bank Deposit IN (object) or IMPS (object) or Thai QR (object) or Viet QR (object) or GCash (object) or Mobile Payment IN (object) or Bank Deposit VN (object) or Bank Deposit AR (object) or Bank Deposit NG (object) or PSE (object) (WithdrawalInfo)

Payout destination details. The type field selects the rail. Representative values: SEPA (EUR bank, requires IBAN), PIX_BR (Brazilian PIX instant), BANK_DEPOSIT_VEN (Venezuelan bank transfer — account number, bank code, tax ID), PHONE_DEPOSIT_VEN (Venezuelan phone-based payout — phone number, bank code, tax ID), MATIC / ETH / TRON (crypto wallet with address field). Use GET /v1/currencies to discover available rails and their required fields. Either this field or destinationTranferId must be provided.

Responses

Request samples

Content type
application/json
{
  • "amount": 1000,
  • "currency": "EUR",
  • "userEmail": "user@example.com",
  • "destinationTranferId": "123",
  • "destinationTransferData": {
    }
}

Response samples

Content type
application/json
{
  • "withdrawalId": "01CLFXMT67II",
  • "userData": {
    },
  • "createdAt": 1723027132,
  • "updatedAt": 1723027132,
  • "userEmail": "user@example.com",
  • "amount": 1000,
  • "currency": "EUR",
  • "fee": 10,
  • "feeCurrency": "EUR",
  • "destinationTransferData": {
    },
  • "status": "Pending",
  • "withdrawalInfo": {
    },
  • "source": "externalApi",
  • "requires2FA": false,
  • "twoFactorToken": "abc123",
  • "twoFactorApprovedAt": 1723027132,
  • "errorCode": "INSUFFICIENT_BALANCE",
  • "errorDetails": "Insufficient balance for withdrawal",
  • "reviewedBy": "admin@example.com",
  • "reviewedAt": 1723027132
}

List withdrawals

This endpoint retrieves a list of withdrawals based on various filters such as status, currency, date range, etc.

Authorizations:
oauth2
query Parameters
currency
string
Example: currency=EUR

Optional currency code to filter the items

minAmount
number >= 0
maxAmount
number >= 0
from
integer >= 0
to
integer >= 0
userEmail
string <email>
Example: userEmail=user@example.com

Email of the user making the request

search
string

General search (e.g. email or text). When provided, backend may use it for userEmail or text search.

limit
number >= 0
page
number >= 0
string or string or (Array of strings or strings)
Examples: status=Pending status=Pending&status=Success status=Pending&status=Processing&status=Success

Optional status to filter withdrawals. Can be a single status or an array of statuses for multiple filtering

network
string
Examples: network=Ethereum

Network filter for the withdrawals in case of crypto withdrawals

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get withdrawal details

This endpoint retrieves details of a specific withdrawal.

Authorizations:
oauth2
path Parameters
withdrawalId
required
string

ID of the withdrawal

userEmail
string <email>
Example: user@example.com

Email of the user making the request

Responses

Response samples

Content type
application/json
{
  • "withdrawalId": "01CLFXMT67II",
  • "userData": {
    },
  • "createdAt": 1723027132,
  • "updatedAt": 1723027132,
  • "userEmail": "user@example.com",
  • "amount": 1000,
  • "currency": "EUR",
  • "fee": 10,
  • "feeCurrency": "EUR",
  • "destinationTransferData": {
    },
  • "status": "Pending",
  • "withdrawalInfo": {
    },
  • "source": "externalApi",
  • "requires2FA": false,
  • "twoFactorToken": "abc123",
  • "twoFactorApprovedAt": 1723027132,
  • "errorCode": "INSUFFICIENT_BALANCE",
  • "errorDetails": "Insufficient balance for withdrawal",
  • "reviewedBy": "admin@example.com",
  • "reviewedAt": 1723027132
}

Delete a withdrawal

This endpoint cancels a specific withdrawal. The withdrawal must be in status Pending. Once executed, the withdrawal changes to status PendingCancel, and the reserved balance is restored.

Authorizations:
oauth2
path Parameters
withdrawalId
required
string

ID of the withdrawal

userEmail
string <email>
Example: user@example.com

Email of the user making the request

Responses

Response samples

Content type
application/json
{ }

Mocks

Mock approved KYC (integration testing)

Applies a successful test KYC for a customer so you can validate flows without a full live verification. Required: email of the individual or pending customer. Optional: firstName, lastName, country (ISO 3166-1 alpha-2). Not intended for production use.

Authorizations:
oauth2
Request Body schema: application/json
email
required
string <email> [ 1 .. 254 ] characters ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

Email address

firstName
string
lastName
string
country
string = 2 characters

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "firstName": "string",
  • "lastName": "string",
  • "country": "st"
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "value": {
    }
}

Mock approved KYB for an organisation (integration testing)

Applies a successful test KYB for an organisation so you can validate flows without a full live verification. Required: email of the organisation representative account. Optional: countryOfIncorporation (ISO 3166-1 alpha-2). Not intended for production use.

Authorizations:
oauth2
Request Body schema: application/json
email
required
string <email> [ 1 .. 254 ] characters ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

Email address

countryOfIncorporation
string = 2 characters

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "countryOfIncorporation": "st"
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "value": {
    }
}

Support

Create a support ticket

Opens a new support ticket. Use this for payment issues, KYC blocks, or any case requiring VirtuaBroker assistance.

Authorizations:
oauth2
Request Body schema: application/json
accountId
required
string non-empty
topic
required
string
Enum: "payment_issue" "order_problem" "deposit_question" "technical_support" "account_issue" "payment_delayed" "kyc" "kyb_review_request" "technical_error" "fraud" "general_info"
subject
required
string [ 1 .. 200 ] characters
message
required
string [ 1 .. 5000 ] characters
priority
string
Default: "medium"
Enum: "low" "medium" "high" "urgent"
object

Responses

Request samples

Content type
application/json
{
  • "accountId": "string",
  • "topic": "payment_issue",
  • "subject": "string",
  • "message": "string",
  • "priority": "low",
  • "linkedTo": {
    }
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "value": null
}

List support tickets

Returns a paginated list of support tickets. Filter by accountId, status, priority, or topic.

Authorizations:
oauth2
query Parameters
accountId
string
status
string
Enum: "open" "in_progress" "resolved" "closed"
priority
string
Enum: "low" "medium" "high" "urgent"
topic
string
Enum: "payment_issue" "order_problem" "deposit_question" "technical_support" "account_issue" "payment_delayed" "kyc" "kyb_review_request" "technical_error" "fraud" "general_info"
assignedTo
string <email> [ 1 .. 254 ] characters ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

Email address

type
string
Enum: "order" "deposit" "payment"
search
string
from
number or null
to
number or null
limit
number [ 1 .. 100 ]
Default: 20
page
number >= 1
Default: 1
sort
string
Default: "latest_activity"
Enum: "latest_activity" "priority" "createdAt"

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "value": null
}

Get support ticket details

Returns full details for a single support ticket by ID.

Authorizations:
oauth2
path Parameters
ticketId
required
string non-empty

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "value": null
}

Pending Payments

List pending payments

Returns incoming transfers that have not yet been linked to an order or deposit. Use filters to locate specific transfers by counterparty name, reference, IBAN, or amount.

Authorizations:
oauth2
query Parameters
currency
string
Example: currency=EUR

Optional currency code to filter the items

minAmount
number >= 0
maxAmount
number >= 0
from
integer >= 0
to
integer >= 0
userEmail
string <email>
Example: userEmail=user@example.com

Email of the user making the request

search
string

General search (e.g. email or text). When provided, backend may use it for userEmail or text search.

limit
number >= 0
page
number >= 0
name
string
Example: name=John Doe

Filter by counterparty name (case-insensitive partial match)

reference
string
Example: reference=REF123

Filter by reference or ID (partial match)

iban
string
Example: iban=ES9121000418450200051332

Filter by IBAN (case-insensitive partial match)

ibanCountry
string
Example: ibanCountry=ES

Filter by IBAN country code (e.g., ES, DE)

amount
number > 0
Example: amount=1000

Filter by exact amount

boolean or string

If true, only unlinked transfers with readyToLinkAt set (queue ready for linking).

Responses

Response samples

Content type
application/json
{
  • "transfers": [
    ],
  • "total": 0,
  • "page": 0,
  • "limit": 0
}

Get pending payment details

Returns full details for a single pending transfer including counterparty information and any pre-linking suggestion.

Authorizations:
oauth2
path Parameters
transferId
required
string

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "amount": 0,
  • "currency": "string",
  • "date": "string",
  • "reference": "string",
  • "counterparty": {
    }
}

Link transfer to an order or deposit

Links an incoming transfer to an existing order or deposit. Provide the entityId (order ID or deposit ID) and the entityType.

Authorizations:
oauth2
path Parameters
transferId
required
string
Request Body schema: application/json
transferId
required
string

Transfer ID without provider prefix (from path parameter)

entityId
required
string

Order ID or Deposit ID to link to (from request body)

entityType
required
string
Enum: "order" "deposit"

Type of entity to link to (from request body)

Responses

Request samples

Content type
application/json
{
  • "transferId": "12345",
  • "entityId": "01CLFXMT67II",
  • "entityType": "deposit"
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "transferId": "string",
  • "entityId": "string",
  • "entityType": "order"
}

Create a deposit from a pending transfer

Creates a new deposit using an incoming transfer as the funding source. The transfer is automatically linked to the resulting deposit.

Authorizations:
oauth2
path Parameters
transferId
required
string
Request Body schema: application/json
Any of
amount
required
number > 0

Amount to be deposited

currency
required
string
Enum: "USDC" "USDT" "CUSD" "BTC" "ETH" "POL" "SOL" "TRX" "AVAX" "XRP" "BNB"

Currency of the deposit

required
string or string
object or object

User data of the person/company making the deposit

userDataId
string

Account ID of the person/company making the deposit

transferId
required
string

Transfer ID without provider prefix (from path parameter)

Responses

Request samples

Content type
application/json
{
  • "amount": 100,
  • "currency": "EUR",
  • "rail": "SEPA",
  • "userData": {
    },
  • "userDataId": "string",
  • "transferId": "12345"
}

Response samples

Content type
application/json
{
  • "depositId": "01CLFXMT67II",
  • "userData": {
    },
  • "createdAt": 1723027132,
  • "rail": "BALANCE",
  • "receivedAt": 1723027132,
  • "expectedAmount": 1000,
  • "amount": 1000,
  • "currency": "EUR",
  • "fee": 10,
  • "expectedFee": 10,
  • "feeCurrency": "EUR",
  • "status": "Pending",
  • "depositInfo": {
    },
  • "depositInfoPending": true,
  • "openbanking": {
    },
  • "transferId": "string",
  • "message": "string"
}

Create an order from a pending transfer

Creates a new order using an incoming transfer as the funding source. The transfer is automatically linked to the resulting order.

Authorizations:
oauth2
path Parameters
transferId
required
string
Request Body schema: application/json
quoteId
required
string <uuid>

The unique identifier of the created quote

object or object

Required when the quote origin is not BALANCE (payer). If the payer email is new, include address, city, postalCode, state, country, firstName, lastName, taxId, kycId for deposit provisioning.

object or object

User data of the person/company that will receive the funds

Balance (object) or SEPA (object) or ETH (object) or MATIC (object) or SOL (object) or TRON (object) or CELO (object) or BTC (object) or SOLANA (object) or XRP (object) or CARDANO (object) or BSC (object) or ARBITRUM (object) or OPTIMISM (object) or AVALANCHE (object) or BASE (object) or Bank Deposit COL (object) or Bank Deposit BR (object) or PIX BR (object) or Bank Deposit VEN (object) or Phone Deposit VEN (object) or Bank Deposit IN (object) or IMPS (object) or Thai QR (object) or Viet QR (object) or GCash (object) or Mobile Payment IN (object) or Bank Deposit VN (object) or Bank Deposit AR (object) or Bank Deposit NG (object) or PSE (object)

The details required for the end user destination transfer method.

externalReference
string

External reference of the order

integrationSessionId
string^int_[A-Za-z0-9]{16}$

Integration session ID for partner attribution tracking

transferId
required
string

Transfer ID without provider prefix (from path parameter)

Responses

Request samples

Content type
application/json
{
  • "quoteId": "QUOTE123",
  • "userData": {
    },
  • "destinationUserData": {
    },
  • "destinationTransferData": {
    },
  • "externalReference": "string",
  • "integrationSessionId": "string",
  • "transferId": "12345"
}

Response samples

Content type
application/json
{
  • "orderId": "01CLFXMT67II",
  • "deposit": {
    },
  • "trade": {
    },
  • "withdraw": {
    },
  • "createdAt": 1723027132,
  • "updatedAt": 1723027132,
  • "status": "Pending",
  • "externalRefeference": "string",
  • "fee": 6.37,
  • "expectedFee": 6.88,
  • "expectedGasFee": 6.88,
  • "feeCurrency": "EUR",
  • "transferId": "string",
  • "message": "string"
}

Remove a pre-link suggestion

Removes an automatic pre-linking suggestion from a pending transfer, allowing it to be matched to a different order or deposit.

Authorizations:
oauth2
path Parameters
transferId
required
string
Request Body schema: application/json
transferId
required
string

Transfer ID without provider prefix (from path parameter)

reason
required
string non-empty

Reason for removing prelink (from request body)

Responses

Request samples

Content type
application/json
{
  • "transferId": "12345",
  • "reason": "Incorrect prelink match"
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "transferId": "string"
}