VNX Platform API v1 (1.2.5)

Download OpenAPI specification:

General Usage

This document describes usage of the VNX Platform Trading API that allows minting, burning and trading of VNX coins in an automated manner. Our API is organized into publicly accessible endpoints (trading pairs, quotes) which require authentication with a public key only, and private authenticated endpoints (balance, trading) which require requests to be signed with a private key. You can generate API keys in the My Account section on the VNX Platform.

Requests, Responses and Errors

Requests

Request payloads are form-encoded (Content-Type: application/x-www-form-urlencoded) or JSON (Content-Type: application/json), and all requests must specify a User-Agent header.

Responses

Responses are JSON encoded and differ for accepted(received) and error responses. The accepted response contains keys specific to a particular request and possibly an error key in case of business level error (reject)

Examples of Accepted(Received) Response

  {
      "timestamp": "2021-03-22T17:18:03Z",
      "OrdId": 1,
      "OrdStatus": "Filled"
  }

  {
      "timestamp": "2021-03-22T17:18:03Z",
      "ordId": 2,
      "ordStatus": "Rejected",
      "error": {
          "code": "limit_too_far_from_market_price",
          "message": "The limit price is too far from the market price" 
      }
  }

The error response has HTTP status other than Ok and contains the key error with subkeys: code, status, message.

Example Error Response

  {
      "code": "invalid_nonce",
      "status": 400,
      "message": "Invalid nonce"
  }

Authentication

Headers and Signature

An ECDSA256 public-private keys pair is required to access the authenticated endpoints, you can generate the keys in the My Account section on the VNX Platform

CAUTION Never share your private key with anyone, it should only be used to generate the x-app-signed-data signature for your request

Authenticated requests must include x-app-public-key, x-app-signed-data and x-app-nonce HTTP headers.

x-app-nonce

The nonce. Nonce must be an always increasing, unsigned 64-bit integer, unique for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use a UNIX timestamp in milliseconds.

NOTE There is no way to reset the nonce for a Public key to a lower value, so be sure to use a nonce generation method that won't produce numbers less than the previous nonce. Too many requests with invalid nonces can result in temporary bans. Problems can arise from requests arriving out of order due to Public keys being shared across processes, or from system clock drift/recalibration.

x-app-public-key

The Public key of your key pair

x-app-signed-data

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to:

Sign of (URI path + POST data + nonce) with private key and convert it to base64url

The code snippet for generating the signature in Node.js follows below.

Code Examples

Node JS

  const crypto = require('crypto');

  /** Sign Data
  *
  * @param {string} path         - URL of the request endpoint starting with /api, e.g. /api/v1/private/queryOrders
  * @param {object} request      - JSON object with all parameters and their values, e.g. {symbol:"VCHF/CHF"}
  * @param {number} nonce        - unique always increasing positive integer number, e.g. UNIX timestamp in milliseconds
  * @param {string} pk64         - base64 encoded private key in PEM format
  */
  signData(path, request, nonce, pk64) {

    // Create private key object
    let pk = Buffer.from(pk64, 'base64').toString();

    const sortedRequest = sortObjectDeep(request);
    const data = path + JSON.stringify(sortedRequest) + String(nonce);

    const signer = crypto.createSign('sha256');
    signer.update(data);
    signer.end();

    // Create signature
    const signature = signer.sign(pk);
    // Convert signature to Base64url
    const signatureBase64url = signature.toString('base64');

    return signatureBase64url;

  }

Request body (POST data) must be serialized into canonical JSON with recursive lexicographic key ordering. The code snippet for sortObjectDeep method in Node.js follows below.

Code Examples

Node JS

  /**
  * Recursively sorts object keys in lexicographic order to produce a canonical JSON structure.
  *
  * Request body must be serialized into canonical JSON with recursive lexicographic key ordering.
  *
  * This function:
  * - Sorts keys of plain objects (`{}`) at all nesting levels
  * - Preserves array order (does NOT sort arrays, only processes their elements)
  * - Leaves primitive values (string, number, boolean, null) unchanged
  * - Ignores non-plain objects (Date, Buffer, class instances, etc.)
  *
  * The resulting object can be safely passed to `JSON.stringify()` to produce
  * a deterministic and stable string representation for cryptographic signing.
  *
  * @param {*} value - Any JSON-serializable value (object, array, primitive)
  * @returns {*} New value with all object keys sorted recursively
  *
  */
  function sortObjectDeep(value) {
      if (Array.isArray(value)) {
          return value.map(sortObjectDeep);
      }

      if (value && typeof value === 'object' && value.constructor === Object) {
          const sorted = {};
          Object.keys(value)
              .sort()
              .forEach((key) => {
                  sorted[key] = sortObjectDeep(value[key]);
              });
          return sorted;
      }

      return value;
  }

Request Limits

We have various safeguards in place to protect against system abuse, DDoS attacks, etc. For REST API requests, these are broadly organised into request limits specific to the REST API.

NOTE (Temporary) Maximum 1 request per 1 sec for a particular Public key.

Changelog

  • June 2024 - Initial version
  • September 2024 - Added queryOrders and queryTrades endpoints
  • November 2024 - Added assets, depositAddress, withdrawAddresses, withdraw, mintTokens and burnTokens endpoints
  • June 2025 - Added support for dest_tag on XRP blockchain
  • October 2025 - Modified fee structure in Get Trading Pairs response
  • March 2026 - Modified quotes and assets responses, updated mintTokens and burnTokens endpoints to fully support minting and burning of commodity based tokens (e.g. VNXAU), added querySupplyChanges endpoint
  • April 2026 - added Payment Rails endpoints

Public Endpoints

Below you can find the endpoints that require authentication with a public key.

Get Trading API Info

Get the name and the version of this API, you can call it to be sure that you specified the correct host and that the Trading API service is up and running on this host.

Authorizations:
PublicKeyAuth

Responses

Response samples

Content type
application/json
{
  • "error": {
    }
}

Get Assets Information

Get information about the assets that are available for deposit, withdrawal and minting. Asset information includes the list of supported blockchains for each asset

Authorizations:
PublicKeyAuth

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "assets": [
    ]
}

Get Trading Pairs Information

Get information about tradable pairs including status, fee schedules and order size limitations.

Authorizations:
PublicKeyAuth
query Parameters
status
string
Enum: "online" "halted"

Optionally filter output by the Trading pairs status

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "pairs": [
    ]
}

Get Quotes Information

Get current bid, ask and last prices and available liquidity for each trading pair (symbol).

Authorizations:
PublicKeyAuth
query Parameters
symbols
Array of strings

Optionally filter output by the list of trading pairs (symbols) as base/quoted currency

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "quotes": [
    ]
}

Private Endpoints

Below you can find the endpoints that require requests to be signed with a private key.

Get Account Balance

Get available balances for each asset you have in your account on the VNX Platform.

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "balances": [
    ]
}

Add Order

Place a new order with given parameters

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
timestamp
required
string <date-time>

Request date-time

clordid
required
string

User specified unique order reference

symbol
required
string

Trading pair (symbol) as base/quoted currency, for example VNXAU/BTC

side
required
string
Enum: "Buy" "Sell"

Order direction (Buy/Sell)

ordtype
required
string
Value: "Limit"

Order type (Limit only)

timeinforce
required
string
Value: "FOK"

Order time in force (Fill or Kill only)

orderqty
required
number <float>

Order quantity with maximum decimal places from Trading pair attribute 'qty_decimals'

price
required
number <float>

Limit price

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "result": "success",
  • "order": {
    },
  • "error": {
    }
}

Query Orders

Query the history of orders

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
symbol
string

Optionally filter output by this trading pair (symbol) as base/quoted currency, for example VNXAU/BTC

clordid
string

Optionally filter output by this user specified unique order reference

date
string

Optionally filter output by this date, format "YYYY-MM-DD"

limit
number <integer>

Maximum number of orders to be returned. Default 50 if not specified

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "orders": [
    ]
}

Query Trades

Query the history of trades

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
symbol
string

Optionally filter output by this trading pair (symbol) as base/quoted currency, for example VNXAU/BTC

clordid
string

Optionally filter output by this user specified unique order reference

date
string

Optionally filter output by this date, format "YYYY-MM-DD"

limit
number <integer>

Maximum number of trades to be returned. Default 50 if not specified

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "trades": [
    ]
}

Query Supply Changes

Query the history of mint and burn requests

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/json
asset
string

Optionally filter output by this asset, for example VNXAU

requestid
string

Optionally filter output by this unique mint/burn request reference

date
string

Optionally filter output by this date, format "YYYY-MM-DD"

limit
number <integer>

Maximum number of requests to be returned. Default 50 if not specified

Responses

Request samples

Content type
application/json
{
  • "asset": "VNXAU",
  • "requestid": "string",
  • "date": "2024-09-12",
  • "limit": 0
}

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "requests": [
    ]
}

Get Deposit Address

Get deposit address for a particular asset and blockchain

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
asset
string

Asset being deposited, for example VCHF

blockchain
string

Blockchain code, for example ETH

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "address": "0x7B0C15f39cD987A7d3F5D8D10B57ac6d633E9403",
  • "dest_tag": 287166653,
  • "minimum": "1"
}

Get Withdraw Addresses

Get a list of withdrawal addresses

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
blockchain
string

Optionally filter addresses for specific blockchain, for example ETH

destination
string

Find the address by its Address label that is configured in your account

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "addresses": [
    ]
}

Withdraw Assets

Make a withdrawal request

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
asset
string

Asset being withdrawn, for example VCHF

quantity
number <float>

Amout to be withdrawn

destination
string

Address Label of a Withdrawal address, that is configured in your account

memo
string

Optional memo for withdrawals on XLM blockchain

dest_tag
number <integer>

Optional destination tag for withdrawals on XRP blockchain

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "txids": [
    ],
  • "fee": 0.5
}

Mint Tokens

Mint a specified amount of an asset on a particular blockchain in exchange for the asset's base currency. For commodity assets, the payment currency and the maximum price must be specified in the request parameters

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
asset
string

Asset to be minted, for example VCHF

blockchain
string

Blockchain where the asset should be minted, for example ETH

quantity
number <integer>

Mint quantity, specified in units if unit is present in the request

price
number <float>

Price in payment currency, required for commodity asset mint requests

unit
string

Unit (Lot size or Metal bar size), required for commodity asset mint requests

currency
string

Payment currency, required for commodity asset mint requests

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "txid": 123,
  • "requestid": 321,
  • "fee": 0.1,
  • "spent": 100000,
  • "spent_currency": "EUR"
}

Burn Tokens

Burn a specified amount of an asset and receive asset's base currency. For commodity assets, the received currency and the minimum price must be specified in the request parameters

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
asset
string

Asset to be burned, for example VEUR

quantity
number <integer>

Burn quantity, specified in units if unit is present in the request

price
number <float>

Price in received currency, required for commodity asset burn requests

unit
string

Unit (Lot size or Metal bar size), required for commodity asset burn requests

currency
string

Received currency, required for commodity asset burn requests

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "txid": 123,
  • "requestid": 321,
  • "fee": 0.1,
  • "received": 100000,
  • "received_currency": "EUR"
}

Payments Endpoints

Below you can find the endpoints that require JSON (Content-Type: application/json) requests to be signed with a private key.

Add Payment Rail

Add Fiat-to-Stablecoin rail (Pay-In) or Stablecoin-to-Fiat rail (Pay-Out) Fiat-to-Stablecoin rail automates conversion from the inbound fiat currency payment to the referenced stablecoin and withdrawal to the designated whitelisted wallet (destination). Stablecoin-to-Fiat rail automates conversion from the inbound stablecoin transfer to the referenced currency and payout to the provided destination bank account.

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/json
railtype
required
string
Enum: "FiatToStablecoin" "StablecoinToFiat"

Payment Rail type (FiatToStablecoin/StablecoinToFiat)

Sender party (object) or Sender wallets (object)

Sender info

object

Wallet info - mandatory for FiatToStablecoin rail

object

Bank Account info - mandatory for StablecoinToFiat rail

object

Payment instruction details to be transferred to a payment system

required
object

Instructions info

Responses

Request samples

Content type
application/json
{
  • "railtype": "FiatToStablecoin",
  • "sender": {
    },
  • "wallet": {
    },
  • "bankaccount": {
    },
  • "paymentdetails": {
    },
  • "instructions": {
    }
}

Response samples

Content type
application/json
{
  • "railid": "3998dfdd-6e94-4387-9451-ebc0b64a2d7b",
  • "status": "Pending",
  • "reason": "Unavailable currency AED"
}

Query Payment Rails

Actual payment rail data is provided to a client by Query Request with optional filtering parameters

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
railid
string <uuid>

Payment rail id (uuid)

railtype
string
Enum: "FiatToStablecoin" "StablecoinToFiat"

Payment Rail type (FiatToStablecoin/StablecoinToFiat)

status
string
Enum: "Pending" "Rejected" "Active" "Deleted"

Status of the new rail

date
string

Optionally filter output by this date, format "YYYY-MM-DD"

limit
number <integer>

Maximum number of requests to be returned. Default 50 if not specified

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "rails": [
    ]
}

Delete Payment Rail

Delete payment rail by rail id

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/json
railid
required
string <uuid>

Payment rail id (uuid)

Responses

Request samples

Content type
application/json
{
  • "railid": "3998dfdd-6e94-4387-9451-ebc0b64a2d7b"
}

Response samples

Content type
application/json
{
  • "railid": "4bdbda0a-03de-4557-a4a8-ac0325a035d9",
  • "type": "FiatToStablecoin",
  • "status": "Deleted",
  • "created": "2026-05-27T15:47:42.389Z"
}

Query Payments

Actual payments is provided to a client by Query Request with optional filtering parameters

header Parameters
x-app-public-key
string

The Public key of your key pair

x-app-nonce
integer <int64>

Nonce must be an always increasing, unsigned 64-bit integer, for each request that is made with a particular Public key. While a simple counter starting from 1 would provide a valid nonce, a more usual method of generating a valid nonce is to use e.g. a UNIX timestamp in milliseconds.

x-app-signed-data
string

Encrypted signature of your message. Authenticated requests must be signed with a signature generated with your private key, nonce, payload, and URI path according to: Sign of (URI path + POST data + nonce) with private key and convert it to base64url

Request Body schema: application/x-www-form-urlencoded
id
string <uuid>

Payment Id

providerid
string

Provider payment Id

end2endid
string

End to end Id

direction
string
Enum: "In" "Out"

Payment direction

status
string
Enum: "Completed" "Rejected" "Processing"

Payment status

railid
string <uuid>

Payment rail id (uuid)

orderreference
string

Order reference

valuedate
string or null <date>

Value date

Responses

Response samples

Content type
application/json
{
  • "timestamp": "2019-08-24T14:15:22Z",
  • "payments": [
    ]
}