--- url: /websockets/account.md description: WebSocket channel for authenticated account events and order commands --- # Account Channel ``` wss://api.valr.com/ws/account ``` The Account WebSocket channel provides real-time updates about your VALR account and supports low-latency order placement commands. ## Authentication The Account channel requires authentication. You can authenticate using either method: ### Connection Headers Authentication is performed by passing HTTP headers during the WebSocket handshake. The following headers are required: | Header | Description | |---|---| | `X-VALR-API-KEY` | Your API key | | `X-VALR-SIGNATURE` | HMAC-SHA512 signature (see below) | | `X-VALR-TIMESTAMP` | Current Unix timestamp in milliseconds | The signature is computed as: ``` Signature = HMAC-SHA512(API_SECRET, TIMESTAMP + "GET" + "/ws/account") ``` Connection example: ```javascript const WebSocket = require('ws'); const headers = { 'X-VALR-API-KEY': 'YOUR_API_KEY', 'X-VALR-SIGNATURE': 'COMPUTED_SIGNATURE', 'X-VALR-TIMESTAMP': Date.now().toString() }; const ws = new WebSocket('wss://api.valr.com/ws/account', { headers }); ``` ### In-band Authentication Connect first, then send an `AUTHENTICATE` message: ```json { "type": "AUTHENTICATE", "payload": { "apiKey": "YOUR_API_KEY", "signature": "SIGNATURE", "timestamp": 1234567890123 } } ``` ## Events (Server to Client) The following events are sent from the server to your client. Some are delivered automatically upon connection, while others require an explicit subscription. ### Auto-subscribed Events These events are sent automatically once you are authenticated: | Event | Description | |---|---| | `BALANCE_UPDATE` | Balance changes for any currency | | `OPEN_ORDERS_UPDATE` | Changes to your open orders | | `ORDER_PROCESSED` | Order processing results | | `FAILED_ORDER` | Failed order placement | | `FAILED_CANCEL_ORDER` | Failed order cancellation | | `NEW_ACCOUNT_TRADE` | Trades on your account (order book only) | | `NEW_ACCOUNT_HISTORY_RECORD` | Transaction history records | | `INSTANT_ORDER_COMPLETED` | Completed simple buy/sell orders | | `NEW_PENDING_RECEIVE` | Pending cryptocurrency deposits | | `NEW_PENDING_SEND` | Pending cryptocurrency withdrawals | | `SEND_STATUS_UPDATE` | Withdrawal status updates | ### Subscription-required Events These events must be explicitly subscribed to: | Event | Description | |---|---| | `ORDER_STATUS_UPDATE` | Order status change notifications | To subscribe: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "ORDER_STATUS_UPDATE" } ] } ``` ## Commands (Client to Server) You can send the following commands through the WebSocket connection for lower-latency order management: | Command | Description | |---|---| | `PLACE_LIMIT_ORDER` | Place a limit order | | `PLACE_MARKET_ORDER` | Place a market order | | `CANCEL_ORDER` | Cancel an open order | | `MODIFY_ORDER` | Modify an existing order | | `PLACE_BATCH_ORDERS` | Place multiple orders in a batch | All commands follow this request format: ```json { "type": "COMMAND_TYPE", "clientMsgId": "unique-correlation-id", "payload": { ... } } ``` The `clientMsgId` field is optional but recommended for correlating responses to requests. ## Message Format All server-to-client messages use this envelope structure: ```json { "type": "EVENT_TYPE", "data": { ... } } ``` For full payload schemas, see the individual operation pages in the sidebar. --- --- url: /ws-docs/sendMarginInfo.md description: WebSocket SEND — /ws/account --- # Account margin information update (Beta) `SEND` **Server to Client** on `wss://api.valr.com/ws/account` (Beta) Receive periodic notifications of the account's current margin information, currently sent every 5 seconds. Requires explicit subscription. On subscription the latest update is sent immediately. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "MARGIN_INFO" } ] } ``` ## Message **Event type:** `MARGIN_INFO` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | marginFraction | string | Yes | - | | collateralizedMarginFraction | string | Yes | - | | initialMarginFraction | string | Yes | - | | totalLeveragedExposureInReference | string | Yes | - | | collateralizedBalancesInReference | string | Yes | - | | referenceCurrency | string | Yes | - | | initialRequiredInReference | string | Yes | - | | availableInReference | string | Yes | - | | maintenanceMarginFraction | string | Yes | - | | autoCloseMarginFraction | string | Yes | - | | leverageMultiple | number (double) | Yes | - | | totalPositionsAtEntryInReference | string | Yes | - | | totalUnrealisedFuturesPnlInReference | string | Yes | - | | totalBorrowedInReference | string | Yes | - | | tradeReservedInReference | string | Yes | - | ### Example ```json "{\n \"type\": \"MARGIN_INFO\",\n \"data\": {\n \"marginFraction\": \"1.90363696\",\n \"collateralizedMarginFraction\": \"0.09883855\",\n \"initialMarginFraction\": \"0.098837526\",\n \"totalLeveragedExposureInReference\": \"478.041761878\",\n \"collateralizedBalancesInReference\": \"151.809292840675\",\n \"referenceCurrency\": \"USDC\",\n \"initialRequiredInReference\": \"151.808803678845\",\n \"availableInReference\": \"862.76900859039\",\n \"maintenanceMarginFraction\": \"0.047995245\",\n \"autoCloseMarginFraction\": \"0.017056799\",\n \"leverageMultiple\": 0.53,\n \"totalPositionsAtEntryInReference\": \"373.48142334\",\n \"totalUnrealisedFuturesPnlInReference\": \"-26.45828977\",\n \"totalBorrowedInReference\": \"78.102048768\",\n \"tradeReservedInReference\": \"0\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV1WalletFiatCurrencyAccounts.md description: 'POST /v1/wallet/fiat/{currency}/accounts' --- # Add bank account `POST /v1/wallet/fiat/{currency}/accounts` **Tags:** Fiat Wallet Link a bank account to your VALR account for fiat withdrawals. The `bank` field should contain a valid bank identifier. Use the `Banks for Currency` request for a list of supported banks for the given currency. The `country` field must be the valid 2 character ISO 3166-1 code for the country in which the bank account is registered. The `accountType` field accepts: `CHEQUE`, `SAVINGS`, or `TRANSMISSION`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR) | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | bank | string | Yes | Bank identifier code. Use the Banks for Currency endpoint for a list of valid codes. | | accountHolder | string | Yes | The name of the bank account holder. | | accountNumber | string | Yes | The bank account number. | | branchCode | string | Yes | The branch code for the bank account. | | accountType | string | Yes | The type of bank account: `CHEQUE`, `SAVINGS`, or `TRANSMISSION`. | | country | string | Yes | The ISO 3166-1 alpha-2 country code where the bank account is registered (e.g., `ZA`). | ## Responses ### 202 Bank account added successfully **Content-Type:** `application/json` **Example:** ```json { "id": "a317d907-7439-447c-879f-c05bddfedadc", "bankCode": "FNB", "bankName": "FNB/RMB", "accountHolder": "Frodo Baggins", "accountNumber": "62792461544", "branchCode": "040000", "accountType": "Current/Cheque", "status": "VERIFIED", "insertedAt": "2023-03-03T14:41:53.841072Z", "updatedAt": "2023-03-03T14:41:54.062808Z", "country": "ZA", "currency": { "symbol": "R", "decimalPlaces": 2, "isActive": true, "shortName": "ZAR", "longName": "Rand", "supportedWithdrawDecimalPlaces": 2, "collateral": true, "collateralWeight": "1" } } ``` ### 400 Bad request - Invalid request body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendAggregatedOrderbookUpdate.md description: WebSocket SEND — /ws/trade --- # Aggregated order book updated `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when the order book has been updated. Contains the full order book with all orders aggregated by price level, showing the total quantity and order count at each level. Subscribe with specific currency pairs to filter updates. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "AGGREGATED_ORDERBOOK_UPDATE" } ] } ``` ## Message **Event type:** `AGGREGATED_ORDERBOOK_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | asks | WsOrderbookLevel\[] | Yes | - | | bids | WsOrderbookLevel\[] | Yes | - | #### asks (WsOrderbookLevel) | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | orderCount | integer (int32) | Yes | - | #### bids (WsOrderbookLevel) | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | orderCount | integer (int32) | Yes | - | ### Example ```json "{\n \"type\": \"AGGREGATED_ORDERBOOK_UPDATE\",\n \"currencyPairSymbol\": \"BTCZAR\",\n \"data\": {\n \"asks\": [\n {\n \"side\": \"sell\",\n \"quantity\": \"1.50000000\",\n \"price\": \"960000\",\n \"currencyPair\": \"BTCZAR\",\n \"orderCount\": 3\n },\n {\n \"side\": \"sell\",\n \"quantity\": \"0.75000000\",\n \"price\": \"961000\",\n \"currencyPair\": \"BTCZAR\",\n \"orderCount\": 1\n }\n ],\n \"bids\": [\n {\n \"side\": \"buy\",\n \"quantity\": \"2.00000000\",\n \"price\": \"950000\",\n \"currencyPair\": \"BTCZAR\",\n \"orderCount\": 5\n },\n {\n \"side\": \"buy\",\n \"quantity\": \"1.25000000\",\n \"price\": \"949000\",\n \"currencyPair\": \"BTCZAR\",\n \"orderCount\": 2\n }\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /guides/ai-integration.md description: >- Access VALR API documentation in LLM-friendly formats for use with AI coding assistants, agents, and chatbots --- # AI Integration VALR API documentation is available in machine-readable formats designed for use with AI coding assistants, agents, and automated tooling. These follow the [llms.txt](https://llmstxt.org/) standard — a convention for providing LLM-friendly content alongside traditional web documentation. ## Available Endpoints | URL | Description | |---|---| | [`/llms.txt`](/llms.txt) | Index of all documentation pages with titles and links | | [`/llms-full.txt`](/llms-full.txt) | Complete documentation as a single markdown file | ### llms.txt A lightweight index listing every documentation page — guides, API endpoints, and WebSocket operations — with titles and URLs. Use this when you need to find specific topics or endpoints without loading the full documentation. ### llms-full.txt The entire documentation site rendered as a single markdown file, including all guide content and every REST API endpoint with request/response schemas. Use this when you need comprehensive context about the VALR API — for example, when building an integration from scratch or answering broad questions about available functionality. ## Usage with AI Tools ### Cursor, Windsurf, and Similar IDEs Most AI-powered IDEs support adding documentation URLs as context. Add the full documentation URL to give your AI assistant complete knowledge of the VALR API: Refer to your IDE's documentation for the specific method — typically this is done through a project-level documentation or context configuration. ### Claude Code Reference the documentation URL directly in your prompt or add it as project context: ### ChatGPT, Claude, and Other Chat Interfaces Paste the contents of `/llms-full.txt` into your conversation, or provide the URL if the tool supports fetching web content. ### Custom Agents and Automation Fetch the documentation programmatically for use in agent pipelines or RAG systems: The content is plain markdown, so no parsing is required — it can be passed directly into an LLM context window. ## What's Included Both files are generated automatically from the same sources that power this documentation site: * **Guides** — authentication, rate limiting, error codes, caching, performance, and WebSocket usage * **REST API endpoints** — every operation from the OpenAPI specification, including request parameters, response schemas, and example values * **WebSocket operations** — real-time streaming API documentation The content is regenerated on every deployment, so it stays in sync with the latest API specification. ## The llms.txt Standard The `/llms.txt` convention is an emerging standard for making website content accessible to large language models. Rather than requiring AI tools to parse HTML pages, sites provide pre-formatted markdown at well-known URLs. For more detail on the standard, see [llmstxt.org](https://llmstxt.org/). --- --- url: /guides/ai-support.md description: Explore VALR API documentation with AI-powered support --- # AI Support --- --- url: /ws-docs/sendAllowedOrderTypesUpdated.md description: WebSocket SEND — /ws/trade --- # Allowed order types updated `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when the set of allowed order types for a currency pair has changed. The data payload is a JSON array of allowed order type strings. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "ALLOWED_ORDER_TYPES_UPDATED" } ] } ``` ## Message **Event type:** `ALLOWED_ORDER_TYPES_UPDATED` ### Example ```json "{\n \"type\": \"ALLOWED_ORDER_TYPES_UPDATED\",\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"data\": [\n \"STOP_LOSS_LIMIT\",\n \"TAKE_PROFIT_LIMIT\",\n \"LIMIT\",\n \"LIMIT_POST_ONLY\",\n \"SIMPLE\",\n \"MARKET\"\n ]\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /api.md description: >- VALR REST API Reference — endpoints for trading, market data, and account management --- # REST API Reference The VALR REST API provides programmatic access to your account, trading, and market data. All endpoints are available over HTTPS at: ``` https://api.valr.com ``` ## Quick Reference | | | |---|---| | **Base URL** | `https://api.valr.com` | | **Protocol** | HTTPS only | | **Content-Type** | `application/json` | | **Authentication** | HMAC-SHA512 signed requests ([guide](/guides/authentication)) | | **Rate Limits** | 2,000 req/min per API key, 1,200 req/min per IP ([details](/guides/rate-limiting)) | ## Authentication All non-public endpoints require API key authentication with HMAC-SHA512 request signing. Public endpoints under `/v1/public/*` (market data, order books, currencies) do not require authentication. ::: tip 🔑 Before You Start Two-Factor Authentication (2FA) must be enabled on your VALR account before you can generate API keys. See the [Authentication guide](/guides/authentication) for setup instructions and code examples in 5 languages. ::: ## Response Format Successful responses return HTTP status codes in the `200–299` range. A `202 Accepted` response means the request has been accepted for processing but is not yet complete — check the order status via REST or subscribe to [WebSocket events](/websockets/) for real-time updates. ## Endpoints Browse the full API reference below, organised by tag. Select any endpoint in the sidebar to view request parameters, response schemas, and try it out. --- --- url: /guides/authentication.md description: How to authenticate with the VALR API using HMAC-based API key signing --- # Authentication Authenticated endpoints require HMAC-based API key authentication. Public endpoints under `/v1/public/*` do not require authentication. ## API Keys API keys are generated from the VALR website under your account settings. Each key has scoped permissions that control what actions it can perform: | Permission | Description | |---|---| | **View access** | Read account balances, order history, and market data | | **Trade** | Place and cancel orders | | **Transfer** | Transfer funds between wallets | | **Withdraw** | Withdraw crypto and fiat | | **Link Bank Account** | Link and manage bank accounts | API keys and secrets are 64 characters long. Example format: ``` API Key: 4961b74efac86b25cce8fbe4c9811c4c7a787b7a5996660afcc2e287ad864363 API Secret: 4961b74efac86b25cce8fbe4c9811c4c7a787b7a5996660afcc2e287ad864363 ``` ::: danger ⚠️ WARNING If your API Secret is compromised, your funds are at risk. ::: ## Security Best Practices * **Never send your API secret in requests** — it is only used locally to generate signatures * **Do not share your API key or secret** with anyone * **Do not commit keys to source control** — use environment variables or a secrets manager * **Delete and regenerate keys immediately** if you suspect they have been compromised ## Request Signing Every authenticated request must be signed using HMAC-SHA512. The signature is computed over a concatenation of the following parameters: | Parameter | Description | |---|---| | `timestamp` | Current Unix timestamp in milliseconds (must match the `X-VALR-TIMESTAMP` header) | | `verb` | HTTP method in uppercase (`GET`, `POST`, `PUT`, `DELETE`) | | `path` | Request path including query parameters (e.g., `/v1/account/balances`) | | `body` | JSON request body (empty string for requests without a body) | | `subaccountId` | Sub-account ID (empty string if not using sub-accounts) | ``` Signature = HMAC-SHA512(API_SECRET, timestamp + verb + path + body + subaccountId) ``` ::: warning JSON Key Ordering The `body` parameter must be the **exact JSON string** sent in the request body. JSON key ordering matters — if your serialisation library reorders keys, the signature will not match. ::: ## Code Examples ### JavaScript (Node.js) ```javascript const crypto = require('crypto'); function signRequest(apiSecret, timestamp, verb, path, body = '', subaccountId = '') { return crypto .createHmac('sha512', apiSecret) .update(timestamp.toString()) .update(verb.toUpperCase()) .update(path) .update(body) .update(subaccountId) .digest('hex'); } ``` ### Go ```go package main import ( "crypto/hmac" "crypto/sha512" "encoding/hex" "fmt" "strconv" "strings" "time" ) func signRequest(apiSecret string, timestamp time.Time, verb string, path string, body string, subaccountId string) string { mac := hmac.New(sha512.New, []byte(apiSecret)) timestampString := strconv.FormatInt(timestamp.UnixNano()/1000000, 10) mac.Write([]byte(timestampString)) mac.Write([]byte(strings.ToUpper(verb))) mac.Write([]byte(path)) mac.Write([]byte(body)) mac.Write([]byte(subaccountId)) return hex.EncodeToString(mac.Sum(nil)) } func main() { timestamp := time.Now() signature := signRequest("your_api_secret", timestamp, "GET", "/v1/account/balances", "", "") fmt.Println(signature) } ``` ### C\# ```csharp using System; using System.Security.Cryptography; using System.Text; public static class ValrAuth { public static string SignRequest(string apiSecret, long timestamp, string verb, string path, string body = "", string subaccountId = "") { var message = timestamp.ToString() + verb.ToUpper() + path + body + subaccountId; using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(apiSecret)); var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message)); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } } ``` ### Python ```python import hmac import hashlib import time def sign_request(api_secret, timestamp, verb, path, body='', subaccount_id=''): message = str(timestamp) + verb.upper() + path + body + subaccount_id signature = hmac.new( api_secret.encode(), message.encode(), hashlib.sha512 ).hexdigest() return signature # Usage timestamp = int(time.time() * 1000) signature = sign_request('your_api_secret', timestamp, 'GET', '/v1/account/balances') ``` ### Java ```java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; public class ValrAuth { public static String signRequest(String apiSecret, long timestamp, String verb, String path, String body, String subaccountId) { try { String message = Long.toString(timestamp) + verb.toUpperCase() + path + (body != null ? body : "") + (subaccountId != null ? subaccountId : ""); Mac mac = Mac.getInstance("HmacSHA512"); SecretKeySpec secretKey = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA512"); mac.init(secretKey); byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8)); StringBuilder hexString = new StringBuilder(); for (byte b : hash) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } catch (Exception e) { throw new RuntimeException("Failed to sign request", e); } } } ``` ::: tip Sub-account Signing When making requests on behalf of a sub-account, pass the sub-account ID as the `subaccountId` parameter in the signing functions above and include it in the `X-VALR-SUB-ACCOUNT-ID` header. Use an empty string when not operating on a sub-account. ::: ## Verify Your Implementation Use the following test data to verify that your signing implementation produces the correct output. ### GET Request Example | Parameter | Value | |---|---| | API Secret | `4961b74efac86b25cce8fbe4c9811c4c7a787b7a5996660afcc2e287ad864363` | | Timestamp | `1558014486185` | | Verb | `GET` | | Path | `/v1/account/balances` | | Body | *(empty)* | **Expected signature:** ``` 9d52c181ed69460b49307b7891f04658e938b21181173844b5018b2fe783a6d4c62b8e67a03de4d099e7437ebfabe12c56233b73c6a0cc0f7ae87e05f6289928 ``` ### POST Request Example | Parameter | Value | |---|---| | API Secret | `4961b74efac86b25cce8fbe4c9811c4c7a787b7a5996660afcc2e287ad864363` | | Timestamp | `1558017528946` | | Verb | `POST` | | Path | `/v1/orders/market` | | Body | `{"customerOrderId":"ORDER-000001","pair":"BTCUSDC","side":"BUY","quoteAmount":"80000"}` | **Expected signature:** ``` 09f536e3dfdad58443f16010a97a0a21ad27486b7b8d6d4103170d885410ed77f037f1fa628474190d4f5c08ca12c1acc850901f1c2e75c6d906ec3b32b008d0 ``` ## Making an Authenticated API Call To make an authenticated request, include the following four headers: | Header | Value | |---|---| | `X-VALR-API-KEY` | Your API key | | `X-VALR-SIGNATURE` | The HMAC-SHA512 signature generated above | | `X-VALR-TIMESTAMP` | The timestamp used to generate the signature (milliseconds since epoch) | | `X-VALR-SUB-ACCOUNT-ID` | Your sub-account ID (omit if not using sub-accounts) | Steps: 1. Generate a Unix timestamp in milliseconds 2. Build the signature string: `timestamp + verb + path + body + subaccountId` 3. Compute the HMAC-SHA512 signature using your API secret 4. Include all four headers in the request ### Complete Request Examples The following curl examples show fully assembled authenticated requests using the test vector data from the [Verify Your Implementation](#verify-your-implementation) section above. **GET request:** ```bash curl -X GET "https://api.valr.com/v1/account/balances" \ -H "Content-Type: application/json" \ -H "X-VALR-API-KEY: your_api_key" \ -H "X-VALR-SIGNATURE: 9d52c181ed69460b49307b7891f04658e938b21181173844b5018b2fe783a6d4c62b8e67a03de4d099e7437ebfabe12c56233b73c6a0cc0f7ae87e05f6289928" \ -H "X-VALR-TIMESTAMP: 1558014486185" ``` **POST request:** ```bash curl -X POST "https://api.valr.com/v1/orders/market" \ -H "Content-Type: application/json" \ -H "X-VALR-API-KEY: your_api_key" \ -H "X-VALR-SIGNATURE: 09f536e3dfdad58443f16010a97a0a21ad27486b7b8d6d4103170d885410ed77f037f1fa628474190d4f5c08ca12c1acc850901f1c2e75c6d906ec3b32b008d0" \ -H "X-VALR-TIMESTAMP: 1558017528946" \ -d '{"customerOrderId":"ORDER-000001","pair":"BTCUSDC","side":"BUY","quoteAmount":"80000"}' ``` **DELETE request with body:** Some endpoints (e.g., cancelling an order) use `DELETE` with a JSON body. The body must be included in the signature string, just as with `POST` or `PUT`. ```bash curl -X DELETE "https://api.valr.com/v2/orders/order" \ -H "Content-Type: application/json" \ -H "X-VALR-API-KEY: your_api_key" \ -H "X-VALR-SIGNATURE: your_generated_signature" \ -H "X-VALR-TIMESTAMP: 1558017528946" \ -d '{"orderId":"0c2a434b-1329-4f87-a66d-e9f12e7f1234","pair":"BTCUSDC"}' ``` ::: tip Replace `your_api_key` with your actual API key. The signatures shown here correspond to the test data in the verification section — in production, generate a fresh signature for every request. ::: ### WebSocket Authentication WebSocket connections use the same three authentication headers (`X-VALR-API-KEY`, `X-VALR-SIGNATURE`, `X-VALR-TIMESTAMP`) sent with the first message on connection. ## Public Endpoints Endpoints under `/v1/public/*` do not require authentication. These include market data such as order books, trade history, and currency information. --- --- url: /ws-docs/sendBalanceUpdate.md description: WebSocket SEND — /ws/account --- # Balance updated `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when any currency balance changes on your account. Includes available, reserved, and total balances along with lending and borrowing amounts. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `BALANCE_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | currency | object | Yes | - | | available | string | Yes | - | | reserved | string | Yes | - | | total | string | Yes | - | | updatedAt | string | Yes | - | | lendReserved | string | Yes | - | | borrowCollateralReserved | string | Yes | - | | borrowedAmount | string | Yes | - | | totalInReference | string | Yes | - | | totalInReferenceWeighted | string | Yes | - | | referenceCurrency | string | Yes | - | ### Example ```json "{\n \"type\": \"BALANCE_UPDATE\",\n \"data\": {\n \"currency\": {\n \"id\": 1,\n \"shortName\": \"BTC\",\n \"longName\": \"Bitcoin\",\n \"decimalPlaces\": 8\n },\n \"available\": \"0.50000000\",\n \"reserved\": \"0.10000000\",\n \"total\": \"0.60000000\",\n \"updatedAt\": \"2024-09-27T12:30:00.000Z\",\n \"lendReserved\": \"0\",\n \"borrowCollateralReserved\": \"0\",\n \"borrowedAmount\": \"0\",\n \"totalInReference\": \"342000.00\",\n \"totalInReferenceWeighted\": \"342000.00\",\n \"referenceCurrency\": \"ZAR\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV1BundlesBuy.md description: POST /v1/bundles/buy --- # Buy Bundle `POST /v1/bundles/buy` **Tags:** Bundles Buy a cryptocurrency bundle. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | amount | string | Yes | The amount to spend in the pay currency. | | payCurrency | string | Yes | The currency used to pay for the bundle (e.g., USDT). | | bundleSymbol | string | Yes | The symbol of the bundle to buy (e.g., VALR3, VALR10). | ## Responses ### 200 Bundle purchase initiated successfully **Content-Type:** `application/json` **Example:** ```json { "success": true, "id": "0199ffe6-c82f-70f2-88f0-65ef198a41f3", "payAmount": "3", "payCurrency": "USDT", "receiveAmount": "0.03082065", "receiveCurrency": "VALR3" } ``` ### 400 Bad request - Invalid bundle purchase request **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "error": "Invalid fund" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /guides/caching.md description: HTTP cache headers and cache durations for VALR API endpoints --- # Caching Some GET requests are cached by default. Cached responses include the HTTP `Cache-Control` header indicating how long the response can be cached. ## Cache-Control Header Example header: ``` cache-control: max-age=60,public ``` | Directive | Description | |---|---| | `max-age` | The number of seconds the response is considered fresh | | `public` | The response can be stored by any cache (browser, CDN, proxy) | ## Public Routes | Endpoint | max-age (seconds) | |---|---| | `/marketsummary` | 60 | | `/:currencypair/marketsummary` | 10 | | `/currencies` | 60 | | `/pairs` | 60 | | `/:currencyPair/orderbook` | 30 | | `/:currencyPair/orderbook/full` | 30 | | `/:currencyPair/trades` | 30 | | `/ordertypes` | 60 | | `/:currencypair/ordertypes` | 60 | ## Authenticated Routes | Endpoint | max-age (seconds) | |---|---| | `/marketdata` | 1 | | `/fiat/:currency/banks` | 600 | | `/fiat/:currency/auto-buy` | 60 | | `/portfolio` | 1 | --- --- url: /api-docs/deleteV1OrdersConditionals.md description: DELETE /v1/orders/conditionals --- # Cancel all conditional orders `DELETE /v1/orders/conditionals` **Tags:** Conditional Orders Cancel all open conditional orders for the user. A `200 OK` response means the request to cancel the conditional orders was accepted. You can either use the Order Status REST API or the WebSocket API to receive status updates about this request. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Cancel all conditional orders request accepted **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | customerOrderId | string | No | - | **Example:** ```json [ { "orderId": "13ae156c-8c18-4e7a-9a43-2e2891221a53" }, { "orderId": "1554825d-dd3c-4fe1-9471-52ff6e2aab56" }, { "orderId": "c0358c7d-10fd-4b60-8193-769a53da712e", "customerOrderId": "ConditionalOrder001" } ] ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV1OrdersConditionalsCurrencyPair.md description: 'DELETE /v1/orders/conditionals/{currencyPair}' --- # Cancel all conditional orders for currency pair `DELETE /v1/orders/conditionals/{currencyPair}` **Tags:** Conditional Orders Cancel open conditional orders for a given pair. A `200 OK` response means the request to cancel the conditional orders was accepted. You can either use the Order Status REST API or the WebSocket API to receive status updates about this request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | A valid currency pair (e.g., BTCUSDTPERP for futures, BTCZAR for spot) | ## Responses ### 200 Cancel all conditional orders for pair request accepted **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | customerOrderId | string | No | - | **Example:** ```json [ { "orderId": "d1469f6e-774f-422b-877a-fa7ae6a03dfe" } ] ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV1Orders.md description: DELETE /v1/orders --- # Cancel all orders `DELETE /v1/orders` **Tags:** Orders Cancel all open orders associated with this account. A `200 OK` response means the request to cancel the orders was accepted. You can either use the Order Status REST API or the WebSocket API to receive status updates about this request. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Cancel all orders request accepted **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | customerOrderId | string | No | - | **Example:** ```json [ { "orderId": "c66a13ec-2ac6-4a52-9eca-608e4480194f" }, { "orderId": "53485e46-ca8e-46c6-a784-0c175bbcd554" } ] ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV1OrdersCurrencyPair.md description: 'DELETE /v1/orders/{currencyPair}' --- # Cancel all orders for currency pair `DELETE /v1/orders/{currencyPair}` **Tags:** Orders Cancel all open orders for the given currency pair. A `200 OK` response means the request to cancel the orders was accepted. You can either use the Order Status REST API or the WebSocket API to receive status updates about this request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair (e.g., BTCUSDC) | ## Responses ### 200 Cancel all orders for pair request accepted **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | customerOrderId | string | No | - | **Example:** ```json [ { "orderId": "0198510c-09fa-7f86-8ddb-b6b222b4e509" }, { "orderId": "0198510c-25db-758b-9c63-fa610ac091e4" }, { "orderId": "0198e5f9-c72f-7bc8-b763-449c067b8c33" } ] ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/receiveCancelLimitOrder.md description: WebSocket RECEIVE — /ws/account --- # Cancel an order via WebSocket `RECEIVE` **Client to Server** on `wss://api.valr.com/ws/account` Cancel an open order through the WebSocket connection. The server responds with a `CANCEL_ORDER_WS_RESPONSE` message. If the request is invalid, an `INVALID_CANCEL_ORDER_REQUEST` message is returned. **Request format:** ```json { "type": "CANCEL_LIMIT_ORDER", "clientMsgId": "unique-correlation-id", "payload": { ... } } ``` ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `CANCEL_LIMIT_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | pair | string | Yes | - | | customerOrderId | string | No | - | ### Example ```json "{\n \"type\": \"CANCEL_LIMIT_ORDER\",\n \"clientMsgId\": \"c3d4e5f6-correlation-id\",\n \"payload\": {\n \"orderId\": \"68b4e939-0f90-41ed-8525-8c9c3509ca63\",\n \"pair\": \"BTCUSDT\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/deleteV1OrdersConditionalsConditional.md description: DELETE /v1/orders/conditionals/conditional --- # Cancel conditional order `DELETE /v1/orders/conditionals/conditional` **Tags:** Conditional Orders Cancel an open conditional order. A `200 OK` response means the request to cancel the order was accepted. You can either use the Order Status REST API or use the WebSocket API to receive status updates about this request. The `DELETE` request requires a JSON request body with either `orderId` (the UUID assigned by VALR) or `customerOrderId` (your custom order ID, if one was specified when placing the order). Both `orderId` and `pair` must be specified together. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | pair | string | Yes | - | | orderId | string | No | - | | customerOrderId | string | No | - | ## Responses ### 202 Cancel conditional order request accepted ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV2OrdersOrder.md description: DELETE /v2/orders/order --- # Cancel order `DELETE /v2/orders/order` **Tags:** Orders Cancel an open order. A 200 OK response means the request to cancel the order was successfully completed. You can additionally use either the Order Status REST API or WebSocket API to receive status updates about this request. **Request body format**: Either specify orderId (UUID format) and pair, or customerOrderId and pair. Do not provide both orderId and customerOrderId in the same request. **Required parameters**: pair (currency pair), and either orderId or customerOrderId. **Notes**: Only open orders can be cancelled. The customerOrderId must match the value specified when creating the order. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string | No | - | | customerOrderId | string | No | - | | pair | string | Yes | - | ## Responses ### 200 Order cancelled successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "e3b3c227-8240-41af-990b-40df7c3afc69" } ``` ### 400 Invalid request parameters (e.g., missing order ID, invalid UUID format, or both IDs provided) **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found or already filled/cancelled **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV1OrdersOrder.md description: DELETE /v1/orders/order --- # Cancel order `DELETE /v1/orders/order` **Tags:** Orders Cancel an open order. A `202 Accepted` response means the request to cancel the order was accepted. You can either use the Order Status REST API or the WebSocket API to receive status updates about this request. The DELETE request requires a JSON request body with either `orderId` and `pair`, or `customerOrderId` and `pair`. Do not provide both orderId and customerOrderId in the same request. When you receive this response, it does not always mean that the order has been cancelled. When the response is `202 Accepted`, you can either use the Order Status REST API or the WebSocket API to receive status updates about this order. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string | No | - | | customerOrderId | string | No | - | | pair | string | Yes | - | ## Responses ### 202 Cancel order request accepted ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found or already filled/cancelled **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV1LoansUnlock.md description: DELETE /v1/loans/unlock --- # Cancel Unlock Request `DELETE /v1/loans/unlock` **Tags:** Lending Cancels a pending unlock request for a loan. This removes a previously submitted unlock request, returning the loan to its prior state. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | Currency symbol of the unlock request to cancel. | | loanId | string | Yes | Unique identifier of the loan. | ## Responses ### 202 Unlock request cancelled successfully ### 400 Bad request - No existing unlock request found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -19236, "message": "Cancel Loan unlock request not processed, no existing unlock requested" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendAddConditionalOrder.md description: WebSocket SEND — /ws/account --- # Conditional order added `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a conditional order (take-profit or stop-loss) has been added for an open position. The triggerType can be MARK\_PRICE or LAST\_TRADED. The conditionalType can be TAKE\_PROFIT or STOP\_LOSS. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `ADD_CONDITIONAL_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | triggerOrderSide | string | Yes | - | | triggerOrderType | string | Yes | - | | currencyPair | string | Yes | - | | createdAt | string | Yes | - | | updatedAt | string | Yes | - | | triggerType | string | Yes | - | | conditionalType | string | Yes | - | | customerOrderId | string | No | - | | positionSide | string | Yes | - | | positionId | string | Yes | - | | quantity | string | Yes | - | | takeProfitTriggerPrice | string | No | - | | takeProfitPlacePrice | string | No | - | | allowMargin | boolean | Yes | - | ### Example ```json "{\n \"type\": \"ADD_CONDITIONAL_ORDER\",\n \"data\": {\n \"orderId\": \"019a29f4-489e-7f1e-87dc-c5ef7439a755\",\n \"triggerOrderSide\": \"sell\",\n \"triggerOrderType\": \"limit-reduce-only\",\n \"currencyPair\": \"BTCUSDTPERP\",\n \"createdAt\": \"2025-10-28T08:34:26.590Z\",\n \"updatedAt\": \"2025-10-28T08:34:26.590Z\",\n \"triggerType\": \"LAST_TRADED\",\n \"conditionalType\": \"TAKE_PROFIT\",\n \"customerOrderId\": \"testWS\",\n \"positionSide\": \"buy\",\n \"positionId\": \"008dea13-85f4-69d5-28a9-03714f849984\",\n \"quantity\": \"0.0003\",\n \"takeProfitTriggerPrice\": \"117000\",\n \"takeProfitPlacePrice\": \"113000\",\n \"allowMargin\": false\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendRemoveConditionalOrder.md description: WebSocket SEND — /ws/account --- # Conditional order removed `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a conditional order has been removed. The reason field indicates why the order was removed (e.g. CANCELLED\_BY\_USER). ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `REMOVE_CONDITIONAL_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | pair | string | Yes | - | | reason | string | Yes | - | | customerOrderId | string | No | - | ### Example ```json "{\n \"type\": \"REMOVE_CONDITIONAL_ORDER\",\n \"data\": {\n \"orderId\": \"019a29f4-489e-7f1e-87dc-c5ef7439a755\",\n \"pair\": \"BTCUSDTPERP\",\n \"reason\": \"CANCELLED_BY_USER\",\n \"customerOrderId\": \"testWS\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV1WalletCryptoCurrencyWithdraw.md description: 'POST /v1/wallet/crypto/{currency}/withdraw' --- # Create new crypto withdrawal `POST /v1/wallet/crypto/{currency}/withdraw` **Tags:** Crypto Wallet Withdraw cryptocurrency funds to an address. Withdrawals created with more decimals than the number supported by the currency will be rounded down to the `withdrawalDecimalPlaces` specified for the network (see documentation on the `/v1/public/currencies` endpoint for more info). The request body for currencies supporting a memo or payment reference, such as XRP, XMR, XEM or XLM, will accept an optional field called "paymentReference". The max length for the `paymentReference` is 256 characters. **Withdrawal using an address:** `networkType` is a request field that can be optionally supplied to specify the network that should be used for the withdrawal. It is very important to make sure that the `networkType` supplied corresponds to the withdrawal `address` supplied. In cases where the incorrect `networkType` is supplied for an `address` it may result in loss of funds. If `networkType` is not specified, it will be defaulted based on the configuration for the currency that can be found at `/v1/public/currencies`. **Beneficiary Information:** `beneficiaryName`, `isCorporate`, `isSelfHosted`, `serviceProviderId` and `serviceProviderName` are fields to support the collection of the beneficiary's (recipient's) information, in accordance with South African regulations that govern crypto asset service providers like VALR. These fields are required for accounts subject to South African regulations unless an `addressBookId` with saved beneficiary information is provided. **Withdrawal using an addressBookId:** When doing a withdrawal by using an `addressBookId`, `networkType` does not need to be specified as the `networkType` of the address book entry will be used. Provided that the address book has beneficiary information saved, beneficiary related fields do not need to be supplied in the withdrawal request. **Borrowing:** Use the `allowBorrow` option to borrow funds against assets in your account. Collateral is locked while the loan is outstanding. Interest accrues hourly and is capitalised into the loan. You can repay the loan whenever you prefer. Crypto Loans are only available in margin-enabled Subaccounts. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the currency you are withdrawing (e.g., BTC, ETH, XRP, ADA) | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | amount | string | Yes | The amount (in the specified currency). | | addressBookId | string | No | The unique identifier of an address book entry for the withdrawal. Either addressBookId or address must be provided. | | address | string | No | The address to which the crypto will be sent. Either address or addressBookId must be provided. | | networkType | string | No | Specifies the network to use for the withdrawal. If not specified, defaults based on currency configuration. | | paymentReference | string | No | Optional memo or payment reference for currencies that support it (e.g. XRP, XLM). Max 256 characters. | | allowBorrow | boolean | No | If true, borrow funds against assets in your account. Default: false. | | beneficiaryName | string | No | The full name of the recipient of the withdrawal. | | isCorporate | boolean | No | true if the recipient is a legal entity/business, false if a person. | | isSelfHosted | boolean | No | true if the recipient controls their own keys, false if they use a crypto asset service provider. | | serviceProviderName | string | No | The name of the recipient's crypto asset service provider. Only used when the service provider list does not include the required exchange. Cannot be used simultaneously with serviceProviderId. | | serviceProviderId | string | No | Unique identifier of the recipient's crypto asset service provider. See /v1/wallet/crypto/service-providers for the full list. Cannot be used simultaneously with serviceProviderName. | ## Responses ### 202 Withdrawal request accepted **Content-Type:** `application/json` **Example:** ```json { "id": "686ce4b8-1504-4f9c-b217-f6f24300cfb3" } ``` ### 400 Bad request - Invalid request body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -19213, "message": "Margin not enabled for account" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1WalletFiatCurrencyWithdraw.md description: 'POST /v1/wallet/fiat/{currency}/withdraw' --- # Create new fiat withdrawal `POST /v1/wallet/fiat/{currency}/withdraw` **Tags:** Fiat Wallet Withdraw your fiat funds into one of your linked bank accounts. The request body accepts an optional field called "fast". If the value of this field is "true" the withdrawal will be processed with real-time clearing ("RTC") (participating banks only) or real-time gross settlement ("RTGS") during our next withdrawal run. Use the `allowBorrow` option to borrow funds against assets in your account. Collateral is locked while the loan is outstanding. Interest accrues hourly and is capitalised into the loan. You can repay the loan whenever you prefer. Crypto Loans are only available in margin-enabled Subaccounts. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR) | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | linkedBankAccountId | string | Yes | The UUID of the linked bank account to withdraw to. Use the Get Bank Accounts endpoint to retrieve linked accounts. | | amount | string | Yes | The amount to withdraw in the specified fiat currency. | | fast | boolean | No | If `true`, the withdrawal will be processed with real-time clearing (RTC) or real-time gross settlement (RTGS) during the next withdrawal run. Participating banks only. | | allowBorrow | boolean | No | If `true`, funds will be borrowed against assets in your account. Only available in margin-enabled subaccounts. | ## Responses ### 202 Withdrawal request accepted **Content-Type:** `application/json` **Example:** ```json { "id": "e5bc0b2f-8fa2-4c3d-baa9-9548666cfedd" } ``` ### 400 Bad request - Invalid request or margin not enabled **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -19213, "message": "Margin not enabled for account available=0|amount=500|fee=25" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1Loans.md description: POST /v1/loans --- # Create New Loan `POST /v1/loans` **Tags:** Lending Create a new loan offer for the current account. Loan offers are prioritised from the lowest to highest interest rate, with FIFO applied for offers at the same rate. If the loan offer is utilised, the lender earns the prevailing hourly rate, which is the higher of the specified `hourlyRate` and the marginal highest `hourlyRate` determined by the loan auction each hour. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | Symbol of the currency to be loaned. | | amount | number | Yes | The amount to be loaned. | | hourlyRate | string | Yes | Minimum hourly interest rate as a percentage (e.g., 0.00004%). Minimum and maximum values may change and can vary between currencies. | ## Responses ### 200 Loan created successfully **Content-Type:** `application/json` **Example:** ```json { "id": "1289055810346737664" } ``` ### 400 Bad request - Invalid loan parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicCurrencies.md description: GET /v1/public/currencies --- # Currencies `GET /v1/public/currencies` **Tags:** Public Get a list of currencies supported by VALR. A currency may optionally expose: defaultNetworkType - the network type identifier that will be used if a network type is not specified on a deposit request or a withdrawal request via the API; supportedNetworks - a list of networks that are available to use for deposits and/or withdrawals for a given currency. NOTE: If a currency does not expose any supported networks, it means that both withdrawals and deposits are not available for the specified currency on VALR. If a currency does expose supported networks, either both withdrawals and deposits are available, or one of withdrawals or deposits is not available for that network. This can be determined using the `deposit` and `withdraw` properties on each network in `supportedNetworks`. For withdrawals, the `withdrawalDecimalPlaces` specified on the `supportedNetworks` level is the maximum scale of the value that will be submitted to the network and will be rounded down to that scale if a value with a larger scale is provided. This is a public API and therefore the values are cached. In particular `estimatedSendCost` may be out of date. For an up to date estimation of the cost to withdraw crypto on-chain, refer to the `withdrawCost` field of the Wallets / Crypto / Withdrawal Config Info API. ## Responses ### 200 List of all supported currencies **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | symbol | string | Yes | - | | isActive | boolean | Yes | - | | shortName | string | Yes | - | | longName | string | Yes | - | | decimalPlaces | string | Yes | - | | withdrawalDecimalPlaces | string | Yes | - | | paymentReferenceFieldName | string | No | - | | collateral | boolean | Yes | - | | collateralWeight | string | Yes | - | | defaultNetworkType | string | No | - | | supportedNetworks | V1SupportedNetworkForApi\[] | No | - | **`supportedNetworks` properties:** | Property | Type | Required | Description | |---|---|---|---| | networkType | string | Yes | - | | networkLongName | string | No | - | | tokenContract | string | No | - | | minimumWithdrawAmount | string | No | - | | estimatedSendCost | string | No | - | | deposit | boolean | Yes | - | | withdraw | boolean | Yes | - | | withdrawalDecimalPlaces | string | No | - | **Example:** ```json [ { "symbol": "BTC", "isActive": true, "shortName": "BTC", "longName": "Bitcoin", "decimalPlaces": "8", "withdrawalDecimalPlaces": "8", "collateral": true, "collateralWeight": "0.95", "defaultNetworkType": "Bitcoin", "supportedNetworks": [ { "networkType": "Bitcoin", "networkLongName": "Bitcoin", "minimumWithdrawAmount": "0.0002", "estimatedSendCost": "0.000012", "deposit": true, "withdraw": true, "withdrawalDecimalPlaces": "8" } ] }, { "symbol": "R", "isActive": true, "shortName": "ZAR", "longName": "Rand", "decimalPlaces": "2", "withdrawalDecimalPlaces": "2", "collateral": true, "collateralWeight": "1" } ] ``` --- --- url: /api-docs/getV1PublicPairs.md description: GET /v1/public/pairs --- # Currency Pairs `GET /v1/public/pairs` **Tags:** Public Get a list of all the currency pairs supported by VALR. ## Responses ### 200 List of all currency pairs **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | symbol | string | Yes | - | | baseCurrency | string | Yes | - | | quoteCurrency | string | Yes | - | | shortName | string | Yes | - | | active | boolean | Yes | - | | minBaseAmount | string | Yes | - | | maxBaseAmount | string | Yes | - | | minQuoteAmount | string | Yes | - | | maxQuoteAmount | string | Yes | - | | tickSize | string | Yes | - | | baseDecimalPlaces | string | Yes | - | | marginTradingAllowed | boolean | Yes | - | | currencyPairType | string | Yes | - | | initialMarginFraction | string | No | - | | maintenanceMarginFraction | string | No | - | | autoCloseMarginFraction | string | No | - | **Example:** ```json [ { "symbol": "ETHZAR", "baseCurrency": "ETH", "quoteCurrency": "ZAR", "shortName": "ETH/ZAR", "active": true, "minBaseAmount": "0.0002", "maxBaseAmount": "69.21", "minQuoteAmount": "10", "maxQuoteAmount": "5000000", "tickSize": "1", "baseDecimalPlaces": "8", "marginTradingAllowed": true, "currencyPairType": "SPOT", "initialMarginFraction": "0.2", "maintenanceMarginFraction": "0.1", "autoCloseMarginFraction": "0.033333333" }, { "symbol": "ETHUSDTPERP", "baseCurrency": "ETH", "quoteCurrency": "USDT", "shortName": "ETH/USDTPERP", "active": true, "minBaseAmount": "0.001", "maxBaseAmount": "32", "minQuoteAmount": "1", "maxQuoteAmount": "100000", "tickSize": "0.1", "baseDecimalPlaces": "3", "marginTradingAllowed": false, "currencyPairType": "FUTURE", "initialMarginFraction": "0.025", "maintenanceMarginFraction": "0.0125", "autoCloseMarginFraction": "0.0125" } ] ``` --- --- url: /api-docs/getV1PublicPairsType.md description: 'GET /v1/public/pairs/{type}' --- # Currency Pairs by type `GET /v1/public/pairs/{type}` **Tags:** Public Get a list of all the currency pairs supported by VALR, filtered by type. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | type | path | string | Yes | The type of currency pairs to return. Examples: SPOT, FUTURE | ## Responses ### 200 List of currency pairs matching the specified type **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | symbol | string | Yes | - | | baseCurrency | string | Yes | - | | quoteCurrency | string | Yes | - | | shortName | string | Yes | - | | active | boolean | Yes | - | | minBaseAmount | string | Yes | - | | maxBaseAmount | string | Yes | - | | minQuoteAmount | string | Yes | - | | maxQuoteAmount | string | Yes | - | | tickSize | string | Yes | - | | baseDecimalPlaces | string | Yes | - | | marginTradingAllowed | boolean | Yes | - | | currencyPairType | string | Yes | - | | initialMarginFraction | string | No | - | | maintenanceMarginFraction | string | No | - | | autoCloseMarginFraction | string | No | - | **Example:** ```json [ { "symbol": "ETHZAR", "baseCurrency": "ETH", "quoteCurrency": "ZAR", "shortName": "ETH/ZAR", "active": true, "minBaseAmount": "0.0002", "maxBaseAmount": "69.21", "minQuoteAmount": "10", "maxQuoteAmount": "5000000", "tickSize": "1", "baseDecimalPlaces": "8", "marginTradingAllowed": true, "currencyPairType": "SPOT", "initialMarginFraction": "0.2", "maintenanceMarginFraction": "0.1", "autoCloseMarginFraction": "0.033333333" }, { "symbol": "BNBUSDC", "baseCurrency": "BNB", "quoteCurrency": "USDC", "shortName": "BNB/USDC", "active": true, "minBaseAmount": "0.0008", "maxBaseAmount": "80", "minQuoteAmount": "0.52", "maxQuoteAmount": "52000", "tickSize": "0.1", "baseDecimalPlaces": "4", "marginTradingAllowed": false, "currencyPairType": "SPOT" } ] ``` --- --- url: /api-docs/deleteV1WalletFiatCurrencyAccountsId.md description: 'DELETE /v1/wallet/fiat/{currency}/accounts/{id}' --- # Delete bank account `DELETE /v1/wallet/fiat/{currency}/accounts/{id}` **Tags:** Fiat Wallet Delete a linked bank account. **Note:** This DELETE endpoint requires the `Content-Type: application/json` header with an empty JSON body `{}`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR) | | id | path | string | Yes | The UUID identifier of the linked bank account to delete | ## Responses ### 204 Bank account deleted successfully ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/deleteV1AccountSubaccount.md description: DELETE /v1/account/subaccount --- # Delete subaccount `DELETE /v1/account/subaccount` **Tags:** Subaccounts Deletes an existing subaccount. Can only be called by a primary account API key with Trade permissions. Please note the subaccount can only be deleted once all balances are transferred out. **Note:** Returns 204 even if deletion cannot complete due to residual balance, margin, or futures. Verify deletion via `GET /v1/account/subaccounts`. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | integer (int64) | Yes | - | ## Responses ### 204 Subaccount deleted successfully ### 400 Bad request - Subaccount still has balances **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -11163, "message": "Cannot disable sub account with balances" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/putV1LoansRate.md description: PUT /v1/loans/rate --- # Edit Loan Rate `PUT /v1/loans/rate` **Tags:** Lending Updates a loan by modifying its minimum interest rate. The `hourlyRate` is a percentage (e.g., 0.00004%). Minimum and maximum values may change and can vary between currencies. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | Currency symbol of the loan to update. | | hourlyRate | string | Yes | New minimum hourly interest rate as a percentage (e.g., 0.00004%). Minimum and maximum values may change and can vary between currencies. | | loanId | string | Yes | Unique identifier of the loan to update. | ## Responses ### 202 Loan rate updated successfully ### 400 Bad request - Invalid rate **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/receiveCancelOnDisconnect.md description: WebSocket RECEIVE — /ws/account --- # Enable cancel-on-disconnect `RECEIVE` **Client to Server** on `wss://api.valr.com/ws/account` When enabled, all open orders for the account will be cancelled when the WebSocket disconnects. This is experimental and it is the user's responsibility to reconnect after cancellation. The server responds with a `CANCEL_ON_DISCONNECT_UPDATE` message. **Request format:** ```json { "type": "CANCEL_ON_DISCONNECT", "payload": { ... } } ``` ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `CANCEL_ON_DISCONNECT` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | cancelOnDisconnect | boolean | Yes | - | ### Example ```json "{\n \"type\": \"CANCEL_ON_DISCONNECT\",\n \"payload\": {\n \"cancelOnDisconnect\": true\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/putV1MarginAccountStatus.md description: PUT /v1/margin/account/status --- # Enable Margin Trading For Account `PUT /v1/margin/account/status` **Tags:** Margin Enable an account to trade with margin. The request body requires accountStatusFieldName (MARGIN\_ENABLED or FUTURES\_ENABLED) and enabled (true or false). **Note:** This endpoint only works on subaccounts, not primary accounts. **Warning:** Enabling margin or futures on a subaccount is permanent and cannot be reversed. Subaccounts with margin or futures enabled cannot be deleted. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | accountStatusFieldName | string | Yes | The account status field to update: `MARGIN_ENABLED` or `FUTURES_ENABLED`. | | enabled | boolean | Yes | Set to `true` to enable or `false` to disable. | ## Responses ### 200 Margin trading status updated successfully ### 400 Bad request - Failed to enable margin or futures **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -11418, "message": "Proof of address is required to access this feature. Please log in and visit one of our futures pairs to complete registration." } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /guides/error-codes.md description: API error codes grouped by domain --- # Error Codes Client-visible error codes returned by the API, grouped by domain. ## General General API errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -113 | INVALID\_JSON | Invalid JSON payload | 400 | | -112 | CURRENCY\_NOT\_SUPPORTED | Currency not supported | 400 | | -111 | MARKET\_SUMMARY\_NOT\_FOUND | Market summary not found | 404 | | -109 | INVALID\_CURRENCY\_SYMBOL | Invalid currency symbol | 400 | | -108 | WITHDRAW\_LIMIT\_REACHED | Amount exceeds daily limit | 400 | | -94 | ACCOUNT\_NOT\_FOUND | Wrong email or password. | 500 | | -93 | UNAUTHORIZED | Unauthorized | 401 | | -54 | WITHDRAW\_CANCELLED | Withdraw cancelled. | 500 | | -53 | WITHDRAW\_ALREADY\_VERIFIED | Withdrawal already verified, cannot verify twice. | 500 | | -52 | WITHDRAW\_EXPIRED | Withdrawal request expired. Please create a new one. | 500 | | -50 | INVALID\_WITHDRAW\_ADDRESS | Invalid Withdraw address. | 400 | | -48 | WITHDRAW\_FEE\_INCORRECT | Withdraw fee incorrect, please restart withdrawal. | 500 | | -46 | WITHDRAW\_UNAVAILABLE | Withdrawal currently unavailable. | 500 | | -40 | UNKNOWN\_ERROR\_PLACING\_BITTREX\_ORDER | We could not fulfill the order at this time. Please try again later or contact support. | 500 | | -39 | ORDER\_SIZE\_TOO\_LARGE | Please decrease your amount. | 400 | | -38 | ORDER\_SIZE\_TOO\_SMALL | Please increase your amount. | 400 | | -33 | INVALID\_INSTANT\_ORDER\_CURRENCY | Invalid pay currency for order side and currency pair | 500 | | -32 | CURRENCY\_PAIR\_NOT\_ACTIVE | The given currency pair is not active | 400 | | -30 | COULD\_NOT\_GET\_RECEIVE\_ADDRESS | Could not get deposit address | 500 | | -29 | BLOCKCHAIN\_SEND\_FAILURE | Unknown Blockchain Send Failure | 500 | | -26 | INVALID\_BUCKET\_PERIOD | Invalid Bucket period seconds, please see api documentation for valid period | 500 | | -24 | INVALID\_TRADE\_FEES | Invalid trade fees | 500 | | -21 | INVALID\_CURRENCY\_PAIR | Unsupported Currency Pair | 400 | | -11 | INVALID\_REQUEST | Invalid Request, please check your request and try again | 400 | | -9 | NOT\_ENOUGH\_LIQUIDITY\_FOR\_MARKET\_ORDER | Unable to fulfill your order, please contact support. | 500 | | -6 | INSUFFICIENT\_BALANCE | Insufficient Balance | 400 | | -1 | INVALID\_ORDER | Invalid Order. | 400 | ## Miscellaneous Miscellaneous errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -10015 | USER\_DB\_QUERY\_TIMEOUT | Request timeout. Reduce your query range and try again or contact support. | 503 | ## Account Account-related errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -11672 | ORDER\_INSTRUCTION\_NOT\_FOUND | Order instruction not found | 404 | | -11669 | INTERNAL\_TRANSFER\_DUAL\_AUTH\_IS\_REQUIRED | Internal transfer requires dual auth to initiate | 400 | | -11652 | INTERNAL\_TRANSFERS\_NOT\_AVAILABLE | Internal transfers are currently not available. | 503 | | -11651 | INTERNAL\_TRANSFER\_REASON\_IS\_INVALID | Internal transfer reason is invalid for a dynamic internal transfer | 400 | | -11600 | REQUESTED\_ACCOUNT\_ACTION\_ALREADY\_PENDING | Account already has a pending request for this action | 400 | | -11534 | ACCOUNT\_BORROW\_EXCEEDED\_FOR\_COLLATERALIZED\_LENDING | Account total borrow limit would be exceeded and is therefore not allowed. | 400 | | -11533 | CURRENCY\_BORROW\_EXCEEDED\_FOR\_COLLATERALIZED\_LENDING | Account borrow limit for requested currency would be exceeded and is therefore not allowed. | 400 | | -11532 | INVALID\_LEVERAGE\_MULTIPLE\_SELECTED | Invalid leverage multiple selected. | 400 | | -11531 | PAIR\_POSITION\_EXCEEDED\_DUE\_TO\_LEVERAGE\_UPDATE | Increased leverage would have exceeded position limit for pair. | 400 | | -11530 | ORDER\_TYPE\_NOT\_ALLOWED\_IN\_POST\_ONLY\_MODE | Selected order type is not allowed for the currency pair while post-only mode is in effect. | 400 | | -11529 | CANNOT\_BORROW\_CURRENCY | Margin is currently not supported for this pay currency | 400 | | -11528 | PAIR\_POSITION\_EXCEEDED | Order would have exceeded position limit for pair | 400 | | -11527 | ACCOUNT\_BORROW\_EXCEEDED | Order would have exceeded debt limit for account | 400 | | -11526 | CURRENCY\_BORROW\_EXCEEDED | Order would have exceeded borrow limit for currency | 400 | | -11525 | REDUCE\_ONLY\_NOT\_SUPPORTED\_ON\_NON\_FUTURE\_PAIRS | Reduce only is not supported for non future pairs | 400 | | -11524 | TIME\_IN\_FORCE\_NOT\_SUPPORTED\_FOR\_REDUCE\_ONLY\_ORDERS | Reduce only is not supported for Good Till Cancelled orders | 400 | | -11523 | REDUCE\_ONLY\_NO\_DECREASE | Reduce only order would not have decreased position and was therefore cancelled. | 400 | | -11522 | REDUCE\_ONLY\_NO\_OPEN\_POSITION | No open position for reduce only order | 400 | | -11521 | SPOT\_ORDER\_SLIPPAGE\_PROTECTED | Order cancelled as it would have matched outside of slippage price band | 400 | | -11520 | FUTURE\_ORDER\_MATCH\_OUTSIDE\_PRICE\_BAND | Order would have matched outside price band | 400 | | -11519 | FUTURE\_ORDER\_OUTSIDE\_PRICE\_BAND | Order price is outside price band | 400 | | -11515 | INVALID\_ORDER\_TYPE | Invalid order type | 400 | | -11514 | TIME\_IN\_FORCE\_NOT\_SUPPORTED\_FOR\_POST\_ONLY\_ORDERS | Post only not supported for orders other than Good Till Cancelled | 400 | | -11513 | POST\_ONLY\_NOT\_SUPPORTED\_FOR\_STOP\_ORDERS | Post only not supported for stop orders | 400 | | -11512 | IOC\_NOT\_MATCHED\_ON\_ENTRY | Immediate Or Cancel order did not match and was therefore cancelled. | 400 | | -11511 | FOK\_NOT\_MATCHED\_FULLY\_ON\_ENTRY | Fill Or Kill order not fully filled and therefore cancelled. | 400 | | -11510 | STOP\_ORDER\_TRIGGERED\_ON\_PLACE | Stop order failed as it would have been triggered immediately | 400 | | -11509 | INSUFFICIENT\_RESERVED\_BALANCE | Insufficient Reserved Balance | 400 | | -11506 | STOP\_ORDER\_EXISTS | Stop order already exists | 400 | | -11505 | INVALID\_QUANTITY | Invalid quantity | 400 | | -11504 | INVALID\_PRICE | Invalid stop order limit price | 400 | | -11503 | INVALID\_STOP\_PRICE | Invalid stop price | 400 | | -11502 | DUPLICATE\_CUSTOMER\_ORDER\_ID | Duplicate customer order id's are not allowed | 400 | | -11500 | SELF\_TRADE\_NOT\_ALLOWED | We did not execute this order since it would have matched with your own order on the Exchange | 400 | | -11499 | SELF\_TRADE\_NOT\_ALLOWED\_ACROSS\_ACCOUNTS | We did not execute this order since it would have matched with an order on one of your other accounts on the Exchange | 400 | | -11423 | SUB\_ACCOUNT\_PROFILE\_INFO\_ALREADY\_EXISTS | Sub account with Id, E-mail or Cell number already exists | 409 | | -11420 | PROOF\_OF\_ADDRESS\_REQUIRED\_FUTURES | Proof of address verification is required to access Futures trading. Sign in to your account via website and navigate to a Futures pair to initiate verification. | 400 | | -11418 | PROOF\_OF\_ADDRESS\_REQUIRED | Proof of address is required to access this feature. | 400 | | -11273 | API\_KEY\_WITHDRAW\_ADDRESS\_NOT\_WHITELISTED | The withdraw address is not whitelisted. | 400 | | -11272 | API\_KEY\_IP\_NOT\_WHITELISTED | The originating IP Address has not been whitelisted. | 401 | | -11271 | API\_KEY\_COUNTRY\_NOT\_WHITELISTED | The originating IP Address country has not been whitelisted. | 401 | | -11270 | API\_KEY\_TIMESTAMP\_HEADER\_MISSING\_OR\_INVALID | API key header missing or is invalid: X-VALR-TIMESTAMP | 400 | | -11269 | API\_KEY\_SIGNATURE\_HEADER\_MISSING | API key header missing: X-VALR-SIGNATURE | 400 | | -11264 | API\_KEY\_INVALID | API key or secret is invalid | 401 | | -11259 | API\_KEY\_MESSAGE\_TIMESTAMP\_EXPIRED | Timestamp cannot be more than 10 seconds in the past | 400 | | -11258 | API\_KEY\_REQUEST\_TIMESTAMP\_TOO\_EARLY | Timestamp cannot be more than 10 seconds in the past | 400 | | -11257 | API\_KEY\_REQUEST\_BLACKLISTED | Duplicate message received | 500 | | -11252 | API\_KEY\_INVALID\_SIGNATURE | Request has an invalid signature | 401 | | -11163 | CANNOT\_DISABLE\_SUB\_ACCOUNT\_WITH\_BALANCES | Cannot disable sub account with balances | 400 | | -11136 | SUB\_ACCOUNT\_LIMIT\_EXCEEDED | New subaccount limit exceeded | 403 | | -11134 | SUB\_ACCOUNT\_NOT\_FOUND | Subaccount not found | 400 | | -11133 | SUB\_ACCOUNT\_INTERNAL\_TRANSFER\_NOT\_ALLOWED | Internal transfer did not succeed | 403 | | -11132 | SUB\_ACCOUNT\_ALREADY\_EXISTS | A subaccount with that label already exists | 403 | ## Orders Order timeout and processing errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -12024 | SLIPPAGE\_PRICE\_DOES\_NOT\_MEET\_TICK\_SIZE | The slippage price does not meet the minimum tick size (price increment). | 400 | | -12023 | INVALID\_REQUEST\_WITH\_ADDITIONAL\_INFO | Invalid Request, please check your request and try again | 400 | | -12018 | V2\_CANCEL\_ORDER\_REQUEST\_ALREADY\_SUBMITTED | Duplicate cancel order request submitted. A request for this identifier is already being processed. | 400 | | -12017 | INVALID\_MARK\_PRICE\_BUCKET\_REQUEST | Invalid mark price buckets request. | 400 | | -12015 | WITHDRAWALS\_NOT\_AVAILABLE | Withdrawals are currently not available. | 503 | | -12012 | INVALID\_ORDER\_QUANTITY\_PRECISION | Order quantity has more than allowed decimal places | 400 | | -12010 | INVALID\_CANCEL\_ORDER\_REQUEST | Invalid cancel order request. | 400 | | -12009 | MAX\_OPEN\_ORDERS\_FOR\_PAIR | You are only allowed to create a maximum of 500 open orders per currency pair | 400 | | -12008 | ORDER\_GREATER\_THAN\_MAX\_ORDER\_SIZE | Order greater than maximum order size | 400 | | -12007 | MINIMUM\_ORDER\_SIZE\_NOT\_MET | Minimum order size not met | 400 | | -12006 | DOES\_NOT\_MEET\_TICK\_SIZE | The order price does not meet the minimum tick size (price increment). | 400 | | -12005 | ORDER\_TYPE\_NOT\_ALLOWED\_FOR\_PAIR | Selected order type is not allowed for the currency pair. | 400 | ## Crypto Cryptocurrency and exchange integration errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -13520 | WIRE\_DEPOSITS\_UNAVAILABLE | Wire deposits are currently unavailable | 400 | | -13519 | WIRE\_WITHDRAWALS\_UNAVAILABLE | Wire withdrawals are currently unavailable | 400 | | -13517 | WIRE\_DEPOSIT\_LOOKUP\_FAILED | Unknown error when fetching wire deposit from Circle | 500 | | -13516 | WIRE\_WITHDRAWAL\_LOOKUP\_FAILED | Unknown error when fetching wire withdrawal from Circle | 500 | | -13512 | INVALID\_WIRE\_BANK\_ACCOUNT | Failed to link bank account since the bank account details provided are invalid | 400 | | -13503 | WIRE\_DEPOSIT\_NOT\_FOUND | Could not find wire deposit | 404 | | -13493 | WIRE\_WITHDRAWAL\_AMOUNT\_BELOW\_MINIMUM | Amount is lower than the minimum | 400 | | -13480 | WIRE\_WITHDRAWAL\_NOT\_FOUND | Could not find wire withdrawal | 404 | | -13479 | WIRE\_WITHDRAWALS\_TEMPORARILY\_DISABLED | Wire withdrawals have been temporarily suspended | 400 | | -13477 | WIRE\_BANK\_ACCOUNT\_LOOKUP\_FAILED | Unknown error when fetching wire bank account | 500 | | -13475 | WIRE\_BANK\_ACCOUNT\_NOT\_ACTIVE | Wire bank account is not active | 500 | | -13473 | WIRE\_BANK\_ACCOUNT\_INSTRUCTIONS\_LOOKUP\_FAILED | Unknown error when fetching wire bank account instructions | 500 | | -13472 | WIRE\_BANK\_ACCOUNT\_ALREADY\_DELETED | Wire bank account already deleted | 500 | | -13471 | WIRE\_BANK\_ACCOUNT\_ALREADY\_ACTIVATED | Wire bank account already activated | 500 | | -13470 | WIRE\_BANK\_ACCOUNT\_NOT\_FOUND | Could not find wire bank account | 404 | | -13469 | WIRE\_BANK\_ACCOUNT\_LINKING\_TEMPORARILY\_DISABLED | Wire bank account linking has been temporarily suspended | 400 | | -13463 | INTERNAL\_BLOCKCHAIN\_SEND\_REQUIRES\_RECIPIENT\_ADDRESS | Internal blockchain send requires a recipient address | 500 | | -13430 | ADDRESS\_BOOK\_CHANGES\_RESTRICTED | Address Book changes are restricted in your region | 400 | | -13429 | VALR\_PAY\_DISABLED\_BY\_ADDRESS\_BOOK\_ONLY\_WITHDRAWALS | VALR Pay not available, as withdrawals to address book entries only is enabled. Please contact support to change | 400 | | -13428 | ADDRESS\_BOOK\_ENTRY\_STILL\_WARMING\_UP | Address book entry too new. Withdrawals not allowed yet | 400 | | -13427 | NON\_ADDRESS\_BOOK\_WITHDRAWALS\_DISABLED | Withdrawals to addresses not in your address book are disabled. Please contact support to change | 400 | | -13426 | ADDRESS\_BOOK\_ENTRY\_LABEL\_IN\_USE | The label provided is already in use. | 400 | | -13425 | ADDRESS\_BOOK\_ENTRY\_ALREADY\_ACTIVATED | This address is already in your address book. | 500 | | -13424 | ADDRESS\_BOOK\_ENTRY\_VALIDATION\_FAILURE | Unknown address book entry validation failure | 500 | | -13423 | ADDRESS\_BOOK\_ENTRY\_CURRENCY\_WRONG | Address book entry not valid for specified currency | 500 | | -13422 | ADDRESS\_BOOK\_ENTRY\_NOT\_FOUND | Could not find address book entry. | 404 | | -13420 | ADDRESS\_BOOK\_CHANGES\_TEMPORARILY\_DISABLED | Address Book changes have been temporarily suspended | 400 | | -13419 | NETWORK\_FEE\_FOR\_TRANSACTION\_EXCEEDED | Withdrawals to this address are not allowed | 400 | | -13418 | BANK\_ACCOUNT\_LINKING\_TEMPORARILY\_DISABLED | Bank account linking has been temporarily suspended | 400 | | -13417 | API\_KEY\_CREATE\_TEMPORARILY\_SUSPENDED | API Key creation has been suspended | 400 | | -13415 | WITHDRAWALS\_TEMPORARILY\_SUSPENDED | Withdrawals have been suspended | 400 | | -13411 | WITHDRAW\_AMOUNT\_BELOW\_MINIMUM | Please ensure withdrawal amount is larger than | 400 | | -13410 | PAYMENT\_REFERENCE\_MISSING | This withdrawal address requires a | 400 | | -13405 | INVALID\_WITHDRAW\_TRANSACTION\_REFERENCE | Invalid transaction reference | 400 | | -13404 | INVALID\_WITHDRAW\_AMOUNT | Invalid withdraw amount, please ensure amount is larger than minimum | 400 | | -13403 | SEND\_NOT\_FOUND | Could not find send | 404 | | -13402 | CURRENCY\_DOES\_NOT\_SUPPORT\_PAYMENT\_REFERENCE | This currency does not support a payment reference field | 400 | | -13400 | UNSUPPORTED\_CURRENCY\_DECIMAL\_PLACES | Unsupported currency decimal places | 400 | | -13213 | UNKNOWN\_ERROR\_REQUESTING\_BITTREX\_QUOTE | We could not fulfil your request at this time. Please try again later or contact support. | 500 | | -13212 | AMOUNT\_MUST\_BE\_GREATER\_THAN\_ZERO | Amount must be greater than zero | 400 | | -13105 | RECEIVE\_ADDRESS\_NOT\_SUPPORTED\_FOR\_CURRENCY\_NETWORK\_TYPE | Deposit address is not supported for the specified currency and network type | 400 | | -13104 | RECEIVE\_ADDRESS\_NOT\_SUPPORTED\_IN\_REGION | Deposit address is not supported in your region | 403 | | -13018 | BLOCKCHAIN\_INVALID\_NETWORK\_FOR\_CURRENCY | Unable to validate network type for provided currency | 400 | | -13017 | BLOCKCHAIN\_SEND\_TRUSTLINE\_NOT\_VALID | Unable to verify trustline. Please confirm that your address has an active trustline for this asset. | 400 | ## Corporate Corporate signup and verification errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -14205 | TRADING\_WITH\_CURRENCY\_NOT\_ALLOWED | Trading on this pair is not supported in your region | 451 | | -14204 | BUY\_NOT\_AVAILABLE\_FOR\_CURRENCY | Purchase of currency is currently unavailable. | 500 | | -14203 | COULD\_NOT\_GET\_LINKED\_ACCOUNT | The requested bank account does not exist | 404 | | -14202 | SIMPLE\_SWAP\_NOT\_AVAILABLE\_FOR\_CURRENCIES | This service is currently unavailable for one or both of the selected currencies | 500 | ## Payments Payment, fiat, and funding errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -15875 | FIAT\_WITHDRAWALS\_TO\_BANK\_BRANCH\_RESTRICTED | Withdrawals using the selected branch code are not supported. Please try a valid branch in your region or contact support. | 400 | | -15447 | PAYMENT\_NOT\_PARTIALLY\_REVERSIBLE | Partial reversal of payment not allowed. | 400 | | -15440 | PAYMENTS\_FOR\_RECIPIENT\_NOT\_SUPPORTED\_IN\_REGION | Payment recipient cannot receive payments in the selected currency | 400 | | -15439 | PAYMENTS\_FOR\_SENDER\_NOT\_SUPPORTED\_IN\_REGION | Payments in the selected currency are not supported in your region | 400 | | -15438 | PAYMENT\_NOT\_REVERSIBLE | Reversal of payment not allowed. | 400 | | -15437 | RECEIVING\_A\_PAYMENT\_DISABLED\_DUE\_TO\_MARGINING | VALR Pay not supported on an account with margin trading enabled. Coming soon! | 400 | | -15435 | MAKING\_A\_PAYMENT\_DISABLED\_DUE\_TO\_MARGINING | VALR Pay not supported on an account with margin trading enabled. Coming soon! | 400 | | -15433 | PAYMENT\_AMOUNT\_EXCEEDS\_MAXIMUM | Maximum payment amount is | 400 | | -15432 | URLS\_NOT\_ALLOWED | URLs not allowed | 400 | | -15431 | INVALID\_PAYMENT\_HISTORY\_FILTER | Invalid payment filter specified | 400 | | -15430 | PAYMENT\_AMOUNT\_BELOW\_MINIMUM | Minimum payment amount is | 400 | | -15426 | PAYMENT\_TO\_SELF\_NOT\_ALLOWED | Payment cannot be sent to yourself. | 400 | | -15424 | UNKNOWN\_PAY\_ID | Unknown Pay ID | 404 | | -15420 | PAYMENT\_ALREADY\_AUTHORISED | Payment already authorised | 400 | | -15418 | CELL\_NUMBER\_NOT\_UNIQUE | Unable to make payment. Please contact support | 500 | | -15417 | PAYMENT\_HAS\_TOO\_MANY\_IDENTIFIERS | Payment has too many recipient identifiers | 400 | | -15416 | PAYMENT\_MISSING\_RECIPIENT\_IDENTIFIER | Payment missing recipient identifier | 400 | | -15407 | PAYMENT\_NOT\_FOUND | Cannot find payment | 404 | | -15401 | PAYMENT\_TO\_RECIPIENT\_DISABLED | Unable to make payment. Please contact support | 400 | | -15400 | PAYMENTS\_TEMPORARILY\_DISABLED | Payments have been temporarily suspended | 400 | | -15322 | CAN\_NOT\_WITHDRAW\_TO\_A\_DELETED\_BANK\_ACCOUNT | This bank account has been deleted. Please add the account and try again. | 400 | | -15321 | CAN\_NOT\_WITHDRAW\_TO\_AN\_UNCONFIRMED\_BANK\_ACCOUNT | This bank account is not confirmed. Please complete our verification process to withdraw. | 400 | | -15320 | FIAT\_WITHDRAWALS\_NOT\_ALLOWED\_FOR\_CURRENCY | Withdrawals in the selected currency are not supported in your region | 451 | | -15318 | FIAT\_WITHDRAWAL\_CURRENCY\_MISMATCH | Withdrawal currency does not match the currency of selected bank account | 400 | | -15317 | BANK\_REMOTE\_FETCH\_FAILURE | Unable to fetch remote list of banks | 500 | | -15315 | INVALID\_BANK\_CODE | Bank code not found | 404 | | -15314 | COULD\_NOT\_ACQUIRE\_WITHDRAWAL\_LOCK | Withdrawal could not be processed. Please try again. | 500 | | -15309 | CAN\_NOT\_WITHDRAW\_TO\_AN\_UNVERIFIED\_BANK\_ACCOUNT | This bank account is not verified. Please withdraw to a verified account. | 400 | | -15307 | FIAT\_WITHDRAWAL\_AMOUNT\_BELOW\_MINIMUM | Amount is lower than the minimum | 400 | | -15209 | CAN\_NOT\_ACTIVATE\_DELETED\_LINKED\_ACCOUNT | This bank account has been deleted and can not be activated again | 400 | | -15208 | LINKED\_ACCOUNT\_ALREADY\_ACTIVATED | This bank account has already been linked | 400 | | -15207 | LINKED\_ACCOUNT\_REGISTRATION\_EXPIRED | The authorization link has expired. Please start over. | 400 | | -15134 | CURRENCY\_NOT\_ALLOWED\_FOR\_FIAT\_DEPOSIT\_AUTO\_BUY | Auto-buys in the selected currency are not supported in your region | 451 | | -15132 | CURRENCY\_NOT\_ENABLED\_FOR\_FIAT\_DEPOSIT\_AUTO\_BUY | Currency not enabled for Auto-Buy | 400 | | -15111 | FIAT\_DEPOSITS\_NOT\_ALLOWED\_FOR\_CURRENCY | Deposits in the selected currency are not supported in your region | 451 | | -15105 | COULD\_NOT\_GET\_FIAT\_DEPOSIT\_REFERENCE\_CODE | Could not get deposit reference code. Please try again. | 500 | ## Account Management Account configuration and sub-account errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -17216 | CANNOT\_DISABLE\_SHARED\_SUB\_ACCOUNT | Cannot disable shared sub account | 400 | ## Price Alerts Price alert errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -18006 | UNSUPPORTED\_PRICE\_ALERT\_CURRENCY\_PAIR | The given currency pair is not enabled for price alerts at this time. | 400 | | -18004 | MAX\_PRICE\_ALERTS | Price alerts Limit Reached, you are allowed up to 20. | 400 | | -18001 | PRICE\_ALERT\_NOT\_FOUND | Cannot find price alert to delete. | 404 | | -18000 | PRICE\_ALERT\_ALREADY\_EXISTS | Cannot add the price alert as it already exists for the given currency pair and price. | 400 | ## Maintenance Feature maintenance and proxy errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -19802 | INVALID\_PAYMENT\_PROVIDER\_SERVICE | Unsupported payment provider | 404 | | -19800 | UNKNOWN\_ERROR\_FROM\_COMPETITION\_SERVICE | Unknown error occurred while processing competition request, please contact support | 500 | | -19700 | UNKNOWN\_ERROR\_FROM\_STAKING\_SERVICE | Unknown error occurred while processing staking operation, please contact support | 500 | | -19502 | CURRENCY\_UNDER\_MAINTENANCE | Currency currently under maintenance. Please try again in a few minutes. | 500 | | -19244 | BORROW\_FOR\_WITHDRAWAL\_NOT\_AVAILABLE\_FOR\_SELECTED\_CURRENCY | Borrowing for withdrawal and internal transfers currently not available for selected currency | 400 | | -19243 | BORROW\_FOR\_WITHDRAWAL\_NOT\_AVAILABLE | Borrowing for withdrawal and internal transfers currently not available | 400 | | -19242 | NON\_MARGIN\_PAIR\_NOT\_SUPPORTED\_ON\_MARGIN\_ACCOUNTS\_ACTIVATE\_MARGIN | Non margin pair trades are currently not supported on margin enabled accounts. Please cancel all open orders on non margin pairs before enabling margin, or, use a different sub-account. | 400 | | -19241 | NON\_MARGIN\_PAIR\_NOT\_SUPPORTED\_ON\_MARGIN\_ACCOUNTS | Non margin pair trades are currently not supported on margin enabled accounts. Please consider using a different sub-account to trade non margin pairs. | 400 | | -19240 | SWAP\_NOT\_SUPPORTED\_ON\_ACCOUNT\_WITH\_MARGIN\_OR\_FUTURES | Simple swaps are not available on Margin or Futures Accounts. Please use a Sub Account that does not have Margin or Futures enabled. | 400 | | -19239 | INVALID\_AMOUNT | Invalid loan amount. | 400 | | -19238 | INVALID\_LOAN\_RATE | Invalid loan rate, cannot be more than 10 digits | 400 | | -19237 | COULD\_NOT\_REQUEST\_CANCEL\_LOAN\_UNLOCK | Something went wrong and we could not cancel your request to unlock your loan, please try again or contact support | 500 | | -19236 | CANNOT\_CANCEL\_NO\_LOAN\_UNLOCK\_NOT\_REQUESTED | Cancel Loan unlock request not processed, no existing unlock requested | 400 | | -19232 | UNLOCK\_REQUEST\_AMOUNT\_GREATER\_THAN\_LOAN\_AMOUNT | The requested unlock amount is more than the total loan amount | 400 | | -19230 | LOAN\_UNLOCK\_ALREADY\_REQUESTED | Loan unlock already requested, please cancel the existing unlock if adjustment is needed | 400 | | -19229 | STOP\_ORDERS\_NOT\_SUPPORTED\_FOR\_FUTURES | Stop Orders are currently not supported for futures | 400 | | -19228 | CANNOT\_DISABLE\_FUTURES\_FOR\_ACCOUNT | Disabling futures for an account is not currently supported | 400 | | -19227 | FUTURES\_NOT\_ENABLED\_FOR\_ACCOUNT | Futures trading is not enabled for this account. Sign in to your account via website and navigate to a Futures pair to enable. | 400 | | -19225 | CANNOT\_DISABLE\_MARGIN\_FOR\_ACCOUNT | Disabling margin for an account is not currently supported | 400 | | -19222 | COULD\_NOT\_ADD\_LOAN | We could not add your loan request, please contact support | 500 | | -19220 | MARGIN\_NOT\_SUPPORTED\_FOR\_ORDER\_TYPE | Margin not enabled currently enabled on given order type | 400 | | -19219 | MARGIN\_NOT\_ENABLED\_FOR\_PAIR | Margin not enabled for given currency pair | 400 | | -19214 | ACCOUNT\_IN\_LIQUIDATION | Request cannot be placed when account is in liquidation | 400 | | -19213 | MARGIN\_NOT\_ENABLED\_FOR\_ACCOUNT | Margin not enabled for account | 400 | | -19209 | PLEASE\_UNLOCK\_EXISTING\_LOAN\_FIRST | Please unlock existing loan first before creating a new one | 400 | | -19208 | COULD\_NOT\_REQUEST\_LOAN\_UNLOCK | Something went wrong and we could not request to unlock your loan, please try again or contact support | 500 | | -19207 | LOAN\_NOT\_FOUND | Loan not found | 404 | | -19202 | INSUFFICIENT\_LIQUIDITY\_FOR\_BORROW | The borrow amount is unavailable currently, please try again later | 500 | ## Futures Futures and margin trading errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -21417 | COULD\_NOT\_SUBMIT\_MODIFY\_CONDITIONAL\_REQUEST | Could not submit modify conditional order request, please try again later or contact support. | 500 | | -21416 | CONDITIONAL\_MODIFY\_TRIGGERED\_IMMEDIATELY | Could not modify conditional order as it would have triggered immediately | 400 | | -21414 | CONDITIONAL\_WOULD\_NOT\_HAVE\_MODIFIED | Modify conditional order would not have modified anything and was cancelled | 400 | | -21413 | COULD\_NOT\_FIND\_CONDITIONAL\_ORDER\_TO\_MODIFY | Invalid order id, could not find conditional order to modify | 400 | | -21411 | LINKED\_ORDER\_NOT\_FOUND | Linked order not found for pair. | 400 | | -21410 | LINKED\_ORDER\_HAS\_TRIGGER\_ORDER | Order already has a linked conditional order, modify or cancel your existing conditional order. | 400 | | -21409 | CONDITIONAL\_ORDERS\_NOT\_SUPPORTED\_ON\_SPOT | Conditional orders are not supported on non futures pairs | 400 | | -21408 | TOO\_MANY\_CONDITIONAL\_ORDERS | Maximum number of conditional orders exceeded. | 400 | | -21405 | NO\_OPEN\_POSITION\_FOR\_CONDITIONAL\_ORDER | No open position for conditional order | 400 | | -21403 | CONDITIONAL\_TRIGGERED\_IMMEDIATELY | Could not place conditional order as it would have triggered immediately | 400 | | -21402 | TAKE\_PROFIT\_MORE\_THAN\_STOP\_LOSS | Stop loss can't be less than take profit on sell | 400 | | -21401 | TAKE\_PROFIT\_LESS\_THAN\_STOP\_LOSS | Take profit can't be less than stop loss on buy | 400 | | -21400 | TAKE\_PROFIT\_STOP\_LOSS\_PRICE\_EQUAL | Take profit and stop loss price can't be equal | 400 | | -21313 | MODIFY\_ORDERS\_DISABLED | Modify orders currently disabled | 400 | | -21311 | MODIFY\_REQUEST\_NOT\_ALLOWED\_WITH\_PLACE\_IN\_SAME\_BATCH | A modify request is not allowed in the same batch as a place request | 400 | | -21306 | COULD\_NOT\_SUBMIT\_MODIFY\_REQUEST | Could not modify order request, please try again later or contact support. | 500 | | -21304 | UNKNOWN\_MODIFY\_ORDER\_ERROR | Could not modify the order, please cancel if not cancelled and re-place | 500 | | -21302 | COULD\_NOT\_FIND\_ORDER\_TO\_MODIFY | Invalid order id, could not find order to modify | 400 | | -21100 | CANNOT\_CHANGE\_PRIMARY\_ACCOUNT\_MARGIN\_STATUS | Can only change margin account status on a sub account | 400 | ## Platform Platform, policy, and system errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -30071 | SERVICE\_PROVIDER\_NOT\_FOUND | Service provider not found. | 400 | | -30068 | BENEFICIARY\_INFO\_REQUIRED | Beneficiary info required | 400 | | -30024 | BROKERAGE\_INSTRUCTION\_TARGET\_ACCOUNT\_EQUALS\_FEE\_ACCOUNT | Fee account can not be the same as trade account | 400 | ## Withdrawal Restrictions Withdrawal restriction errors | Code | Name | Message | HTTP Status | |---|---|---|---| | -32765 | WITHDRAWAL\_RESTRICTION\_APPLIED | Withdrawal denied. Minimum portfolio value would not be met after this withdrawal. | 400 | --- --- url: /ws-docs/sendFullOrderbookUpdate.md description: WebSocket SEND — /ws/trade --- # Full order book incremental update `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent after the initial FULL\_ORDERBOOK\_SNAPSHOT with incremental changes to the order book. Uses the same PascalCase structure. A quantity of "0" for an order indicates it should be removed. Apply updates using the SequenceNumber to ensure correct ordering. **Updating rules:** * If an order ID exists in the local book, update its quantity (remove if "0") * If an order ID is new, add it at the given price level * If a price level becomes empty, remove it * Verify the Checksum after applying each update ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "FULL_ORDERBOOK_UPDATE" } ] } ``` ## Message **Event type:** `FULL_ORDERBOOK_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | LastChange | integer (int64) | Yes | - | | Asks | WsFullOrderBookPriceLevel\[] | Yes | - | | Bids | WsFullOrderBookPriceLevel\[] | Yes | - | | SequenceNumber | integer (int64) | Yes | - | | Checksum | integer (int64) | Yes | - | #### Asks (WsFullOrderBookPriceLevel) | Property | Type | Required | Description | |---|---|---|---| | Price | string | Yes | - | | Orders | WsFullOrderBookOrder\[] | Yes | - | #### Bids (WsFullOrderBookPriceLevel) | Property | Type | Required | Description | |---|---|---|---| | Price | string | Yes | - | | Orders | WsFullOrderBookOrder\[] | Yes | - | ### Example ```json "{\n \"type\": \"FULL_ORDERBOOK_UPDATE\",\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"data\": {\n \"LastChange\": 1644242600000,\n \"Asks\": [\n {\n \"Price\": \"46150.00\",\n \"Orders\": [\n {\n \"orderId\": \"a38a0816-83a0-4340-b001-130ca2442417\",\n \"quantity\": \"0\"\n }\n ]\n }\n ],\n \"Bids\": [],\n \"SequenceNumber\": 456,\n \"Checksum\": 3456789012\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendFullOrderbookSnapshot.md description: WebSocket SEND — /ws/trade --- # Full order book snapshot `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent once on subscription. Contains the complete order book with individual orders visible at each price level (not aggregated). Uses PascalCase keys. After this initial snapshot, incremental updates are sent via FULL\_ORDERBOOK\_UPDATE messages. The order book checksum (CRC32) can be used to verify data integrity. The SequenceNumber is incremented on each update and can be used to detect missed messages. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "FULL_ORDERBOOK_SNAPSHOT" } ] } ``` ## Message **Event type:** `FULL_ORDERBOOK_SNAPSHOT` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | LastChange | integer (int64) | Yes | - | | Asks | WsFullOrderBookPriceLevel\[] | Yes | - | | Bids | WsFullOrderBookPriceLevel\[] | Yes | - | | SequenceNumber | integer (int64) | Yes | - | | Checksum | integer (int64) | Yes | - | #### Asks (WsFullOrderBookPriceLevel) | Property | Type | Required | Description | |---|---|---|---| | Price | string | Yes | - | | Orders | WsFullOrderBookOrder\[] | Yes | - | #### Bids (WsFullOrderBookPriceLevel) | Property | Type | Required | Description | |---|---|---|---| | Price | string | Yes | - | | Orders | WsFullOrderBookOrder\[] | Yes | - | ### Example ```json "{\n \"type\": \"FULL_ORDERBOOK_SNAPSHOT\",\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"data\": {\n \"LastChange\": 1644242571116,\n \"Asks\": [\n {\n \"Price\": \"46150.00\",\n \"Orders\": [\n {\n \"orderId\": \"a38a0816-83a0-4340-b001-130ca2442417\",\n \"quantity\": \"0.01\"\n }\n ]\n }\n ],\n \"Bids\": [\n {\n \"Price\": \"45850.00\",\n \"Orders\": [\n {\n \"orderId\": \"9e4b6b18-fd55-4e05-a355-1ffd5b6fbb63\",\n \"quantity\": \"0.001\"\n }\n ]\n }\n ],\n \"SequenceNumber\": 455,\n \"Checksum\": 2345678942\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendFundingRunCompleted.md description: WebSocket SEND — /ws/trade --- # Funding run completed `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when a funding rate calculation run has completed for a futures pair. This event has no data payload — the message only contains the type and currency pair symbol. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "FUNDING_RUN_COMPLETED" } ] } ``` ## Message **Event type:** `FUNDING_RUN_COMPLETED` ### Example ```json "{\n \"type\": \"FUNDING_RUN_COMPLETED\",\n \"currencyPairSymbol\": \"BTCUSDTPERP\"\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendPositionClosed.md description: WebSocket SEND — /ws/account --- # Futures position closed `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a futures position has been fully closed. If you manually close a position, you will receive both REDUCE\_POSITION and POSITION\_CLOSED. If a trade closes an existing position and flips it to the opposite side, you will first receive REDUCE\_POSITION and POSITION\_CLOSED for the original position, followed by OPEN\_POSITION\_UPDATE for the new position. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `POSITION_CLOSED` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | pair | string | Yes | - | | positionId | string | Yes | - | ### Example ```json "{\n \"type\": \"POSITION_CLOSED\",\n \"data\": {\n \"pair\": \"BTCUSDTPERP\",\n \"positionId\": \"08dea401-ba23-ded0-28a9-03d6d59c32a4\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendReducePosition.md description: WebSocket SEND — /ws/account --- # Futures position reduced `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a futures position has been partially or fully closed. On a partial close, you will receive both REDUCE\_POSITION and OPEN\_POSITION\_UPDATE events. On a full close, you will receive both REDUCE\_POSITION and POSITION\_CLOSED events. The quantity field specifies the amount by which the position was reduced. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `REDUCE_POSITION` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | orderSide | string | Yes | - | | quantity | string | Yes | - | | averageEntryPrice | string | Yes | - | | closePrice | string | Yes | - | | realisedPnl | string | Yes | - | | closeType | string | Yes | - | | createdAt | string | Yes | - | | fees | string | Yes | - | | positionId | string | Yes | - | | initialMarginFractionAtClose | string | Yes | - | ### Example ```json "{\n \"type\": \"REDUCE_POSITION\",\n \"data\": {\n \"currencyPair\": \"USDTZARPERP\",\n \"orderSide\": \"buy\",\n \"quantity\": \"140.576\",\n \"averageEntryPrice\": \"18.0002\",\n \"closePrice\": \"18\",\n \"realisedPnl\": \"-3.5706498\",\n \"closeType\": \"Trade\",\n \"createdAt\": \"2025-05-30T11:13:08.898Z\",\n \"fees\": \"3.5425346\",\n \"positionId\": \"27b1f2f1-a500-8dea-28a9-03190309a944\",\n \"initialMarginFractionAtClose\": \"0.1\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/getV1AccountBalances.md description: GET /v1/account/balances --- # Get account balances `GET /v1/account/balances` **Tags:** Account Returns the list of all wallets with their respective balances. You can view zero balances by specifying the excludeZeroBalances parameter to false. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | excludeZeroBalances | query | boolean | No | If true, excludes currencies with zero balance from the response. Defaults to false. | ## Responses ### 200 Account balances retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | Currency short name (e.g., BTC, ZAR, USDC) | | available | string | Yes | Balance available for trading or withdrawal | | reserved | string | Yes | Balance reserved in open orders | | total | string | Yes | Total balance including reserved, lend-reserved, and borrow-reserved amounts | | updatedAt | string | No | ISO 8601 timestamp of the last balance update | | lendReserved | string | Yes | Balance reserved in active lending offers | | borrowReserved | string | Yes | Balance reserved as collateral for borrows | | borrowedAmount | string | Yes | Outstanding borrowed amount | | totalInReference | string | Yes | Total balance value denominated in the reference currency | | totalInReferenceWeighted | string | Yes | Risk-weighted total balance in the reference currency | | referenceCurrency | string | Yes | The reference currency used for totalInReference calculations | **Example:** ```json [ { "currency": "USDT", "available": "44822.97549155", "reserved": "99.99925", "total": "145612.43129945", "updatedAt": "2023-04-25T09:00:04.406Z", "lendReserved": "100000", "borrowReserved": "689.4565579", "borrowedAmount": "0", "totalInReference": "7828.62533868", "totalInReferenceWeighted": "7828.62533868", "referenceCurrency": "USDC" }, { "currency": "BTC", "available": "0", "reserved": "0", "total": "-0.00101056", "updatedAt": "2023-04-25T09:00:00.103Z", "lendReserved": "0", "borrowReserved": "0", "borrowedAmount": "0.00101056", "totalInReference": "-28.29568", "totalInReferenceWeighted": "-27.588288", "referenceCurrency": "USDC" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1MarginStatus.md description: GET /v1/margin/status --- # Get Account Margin Information `GET /v1/margin/status` **Tags:** Margin Returns margining information for an account including margin fraction, collateralised margin fraction, initial margin fraction, collateralised balances in reference, reference currency, initial required in reference, available in reference, maintenance margin fraction, auto close margin fraction, leverage multiple, total positions at entry in reference, and total unrealised futures PnL in reference. **Note:** This endpoint uses `marginFraction` (camelCase) field naming. The `/v2/margin/status` endpoint includes additional fields. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Account margin information retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | marginFraction | string | No | - | | collateralisedMarginFraction | string | No | - | | initialMarginFraction | string | Yes | - | | totalBorrowedInReference | string | Yes | - | | collateralisedBalancesInReference | string | Yes | - | | referenceCurrency | string | Yes | - | | initialRequiredInReference | string | Yes | - | | availableInReference | string | Yes | - | | maintenanceMarginFraction | string | No | - | | autoCloseMarginFraction | string | No | - | | leverageMultiple | number (double) | No | - | | totalPositionsAtEntryInReference | string | No | - | | totalUnrealisedFuturesPnlInReference | string | No | - | | defaultInitialMarginFraction | string | Yes | - | | defaultMaintenanceMarginFraction | string | Yes | - | | defaultAutoCloseMarginFraction | string | Yes | - | **Example:** ```json { "marginFraction": "0.10710575", "collateralisedMarginFraction": "0.10398192", "initialMarginFraction": "0.10032321", "totalBorrowedInReference": "20065.42292", "collateralisedBalancesInReference": "2013.1832234925416", "referenceCurrency": "USDC", "initialRequiredInReference": "2013.027732", "availableInReference": "62.6810773874584", "maintenanceMarginFraction": "0.050161607", "autoCloseMarginFraction": "0.010075417", "leverageMultiple": 9.34, "totalPositionsAtEntryInReference": "20065.42292", "totalUnrealisedFuturesPnlInReference": "73.2578", "defaultInitialMarginFraction": "0.2", "defaultMaintenanceMarginFraction": "0.1", "defaultAutoCloseMarginFraction": "0.033333333" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV2MarginStatus.md description: GET /v2/margin/status --- # Get Account Margin Information `GET /v2/margin/status` **Tags:** Margin Returns margining information for an account including margin fraction, collateralised margin fraction, initial margin fraction, total leveraged exposure in reference, collateralised balances in reference, reference currency, initial required in reference, available in reference, maintenance margin fraction, auto close margin fraction, leverage multiple, total positions at entry in reference, total unrealised futures PnL in reference, total borrowed in reference, and trade reserved in reference. **Note:** This endpoint includes additional fields (`totalLeveragedExposureInReference`, `totalBorrowedInReference`, `tradeReservedInReference`) compared to `/v1/margin/status`. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Account margin information retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | marginFraction | string | No | - | | collateralizedMarginFraction | string | No | - | | initialMarginFraction | string | Yes | - | | totalLeveragedExposureInReference | string | Yes | - | | collateralizedBalancesInReference | string | Yes | - | | referenceCurrency | string | Yes | - | | initialRequiredInReference | string | Yes | - | | availableInReference | string | Yes | - | | maintenanceMarginFraction | string | No | - | | autoCloseMarginFraction | string | No | - | | leverageMultiple | number (double) | No | - | | totalPositionsAtEntryInReference | string | No | - | | totalUnrealisedFuturesPnlInReference | string | No | - | | totalBorrowedInReference | string | No | - | | tradeReservedInReference | string | Yes | - | | defaultInitialMarginFraction | string | Yes | - | | defaultMaintenanceMarginFraction | string | Yes | - | | defaultAutoCloseMarginFraction | string | Yes | - | **Example:** ```json { "marginFraction": "60.20150659", "collateralizedMarginFraction": "0.3958049", "initialMarginFraction": "0.2", "totalLeveragedExposureInReference": "40.87818421", "collateralizedBalancesInReference": "0", "referenceCurrency": "USDC", "initialRequiredInReference": "8.175636842", "availableInReference": "2444.74849043828165", "maintenanceMarginFraction": "0.1", "autoCloseMarginFraction": "0.033333333", "leverageMultiple": 0.02, "totalPositionsAtEntryInReference": "40.87818421", "totalUnrealisedFuturesPnlInReference": "0", "totalBorrowedInReference": "0", "tradeReservedInReference": "16.1797854537" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1MarginAccountStatus.md description: GET /v1/margin/account/status --- # Get Account Margin Status `GET /v1/margin/account/status` **Tags:** Margin Returns whether the account has margin trading enabled or not; and if it's currently in `Liquidation` state. ## Liquidation When an account falls below its maintenance margin, the value of its equity has dropped far enough that the risk that assets in the account won't cover all of the debt is beyond acceptable limits. VALR aims to liquidate accounts well before there is a risk of permanent loss. We achieve this by gradually selling off assets when the account falls below maintenance margin. The Liquidation process is set up in distinct stages that aim to keep an account above maintenance margin for as long as possible, reducing the impact of liquidation orders on order books and allowing customers the opportunity to take action to repay debt. All liquidation orders placed during the first stage (i.e. below maintenance but above auto-close, and whether matcher or not) will be visible as orders of the type "liquidation limit order" on the particular account in question. Similarly, for auto-close, the transfer of debt and assets out of the account will be visible on transaction history records as "liquidation takeover debt transfer" and "liquidation takeover asset transfer" respectively. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Account margin status retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | marginEnabled | boolean | Yes | - | | inLiquidation | boolean | Yes | - | | futuresEnabled | boolean | Yes | - | **Example:** ```json { "marginEnabled": true, "inLiquidation": false, "futuresEnabled": true } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1AccountTransactionhistory.md description: GET /v1/account/transactionhistory --- # Get account transaction history `GET /v1/account/transactionhistory` **Tags:** Account Transaction history for your account. The results of this request may be filtered by transaction types, currency and datetime. The `skip` and `limit` parameters may be applied to paginate the filtered results. ## Filtering by `transactionTypes` The `transactionTypes` parameter may be used to filter the returned items by a comma-separated list of transaction types from the following list of supported types: LIMIT\_BUY, LIMIT\_SELL, MARKET\_BUY, MARKET\_SELL, SIMPLE\_BUY, SIMPLE\_SELL, AUTO\_BUY, MAKER\_REWARD, BLOCKCHAIN\_RECEIVE, BLOCKCHAIN\_SEND, FIAT\_DEPOSIT, FIAT\_WITHDRAWAL, REFERRAL\_REBATE, REFERRAL\_REWARD, PROMOTIONAL\_REBATE, INTERNAL\_TRANSFER, FIAT\_WITHDRAWAL\_REVERSAL, PAYMENT\_SENT, PAYMENT\_RECEIVED, PAYMENT\_REVERSED, PAYMENT\_REWARD, OFF\_CHAIN\_BLOCKCHAIN\_WITHDRAW, OFF\_CHAIN\_BLOCKCHAIN\_DEPOSIT, SIMPLE\_SWAP\_BUY, SIMPLE\_SWAP\_SELL, SIMPLE\_SWAP\_FAILURE\_REVERSAL, ACCOUNT\_FUNDING, FUND, FIAT\_WITHDRAWAL\_FEE\_REVERSAL, CREDIT\_CARD\_DEPOSIT, SPOT\_BORROW\_INTEREST\_CHARGE, SPOT\_LEND\_INTEREST\_PAYMENT. ## Filtering by `startTime` or `endTime` The `startTime` or `endTime` parameters may be used to filter the returned items by the transaction date. The parameters will be interpreted as being in the UTC time zone and must be supplied in the ISO 8601 format (`2020-02-29T22:00:00.000Z`). These two parameters may be used together or separately. When `startTime` is used, transactions that have occurred since `startTime` are returned. When `endTime` is used, transactions that have occurred up to and including `endTime` are returned. **Note:** The `startTime` and `endTime` parameters are optional filters. However, omitting these parameters may result in slower response times. To mitigate this, a default time window such as the most recent 30 days may be automatically applied to the request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Number of records to skip for pagination | | limit | query | integer | No | Maximum number of records to return. Maximum 200. | | currency | query | string | No | Filter transactions by currency code (e.g., BTC, ZAR) | | transactionTypes | query | string | No | Comma-separated list of transaction types to filter by | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2024-01-01T00:00:00Z) | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2024-12-31T23:59:59Z) | | beforeId | query | string | No | Return transactions before this ID for cursor-based pagination | ## Responses ### 200 Transaction history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | transactionType | object | Yes | - | | debitCurrency | string | No | - | | debitValue | string | No | - | | creditCurrency | string | No | - | | creditValue | string | No | - | | feeCurrency | string | No | - | | feeValue | string | No | - | | eventAt | string | Yes | - | | additionalInfo | object | No | - | | id | string (uuid) | Yes | - | **`transactionType` properties:** | Property | Type | Required | Description | |---|---|---|---| | type | string | Yes | - | | description | string | Yes | - | **`additionalInfo` properties:** | Property | Type | Required | Description | |---|---|---|---| **Example:** ```json [ { "transactionType": { "type": "REFERRAL_REBATE", "description": "Referral Rebate" }, "creditCurrency": "XRP", "creditValue": "0.00032", "eventAt": "2025-07-04T08:38:13.550Z", "additionalInfo": { "sourceTransactionId": "1057478" }, "id": "0197d496-0f2e-726a-baeb-5d8b993e826a" }, { "transactionType": { "type": "SIMPLE_BUY", "description": "Simple Buy" }, "debitCurrency": "ZAR", "debitValue": "9.997956", "creditCurrency": "XRP", "creditValue": "0.1971936", "feeCurrency": "XRP", "feeValue": "0.0032064", "eventAt": "2025-07-04T08:38:13.407Z", "additionalInfo": { "costPerCoin": 49.89, "costPerCoinSymbol": "R", "currencyPairSymbol": "XRPZAR", "orderId": "0197d496-0e4e-7453-ae5b-1d930e8f3a81" }, "id": "0197d496-0e9f-7ef5-8476-c45cd13ccef5" } ] ``` ### 400 Bad request - Invalid query parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1BundlesAll.md description: GET /v1/bundles/all --- # Get All Available Bundles `GET /v1/bundles/all` **Tags:** Bundles Returns all available cryptocurrency bundles. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Available bundles retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "symbol": "VALR3", "referenceCurrency": "USDT", "supportedFlowCurrencies": [ "USDT" ], "hourlyFeeFraction": "0.00000228", "minInReference": "0.2", "maxInReference": "10001", "allocations": [ { "currency": "USDT", "weight": "0.0041" }, { "currency": "ZAR", "weight": "0.1327" }, { "currency": "BTC", "weight": "0.4147" }, { "currency": "ETH", "weight": "0.4484" } ], "previousRebalancedDate": 1761844860000, "nextRebalanceDate": 1764523260000, "rebalancePeriod": "1M" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersConditionals.md description: GET /v1/orders/conditionals --- # Get all conditional orders `GET /v1/orders/conditionals` **Tags:** Conditional Orders Get all active conditional orders for your account. A customerOrderId field will be returned in the response for all those orders that were created with a customerOrderId field. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Conditional orders retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | triggerOrderSide | string | Yes | - | | triggerOrderType | string | Yes | - | | currencyPair | string | Yes | - | | createdAt | string | Yes | - | | updatedAt | string | Yes | - | | triggerType | string | Yes | - | | conditionalType | string | Yes | - | | customerOrderId | string | No | - | | positionSide | string | No | - | | positionId | string (uuid) | No | - | | quantity | string | Yes | - | | takeProfitTriggerPrice | string | No | - | | takeProfitPlacePrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossPlacePrice | string | No | - | | linkedOrderId | string (uuid) | No | - | | allowMargin | boolean | Yes | - | **Example:** ```json [ { "orderId": "12d87c9e-ea28-416c-b0df-76ef6e2c0c05", "triggerOrderSide": "buy", "triggerOrderType": "limit-reduce-only", "currencyPair": "1000PEPEUSDTPERP", "createdAt": "2024-05-08T09:42:03.684Z", "updatedAt": "2024-05-08T09:42:03.684Z", "triggerType": "LAST_TRADED", "conditionalType": "TAKE_PROFIT", "positionSide": "sell", "positionId": "a478bbe1-6090-08de-28a9-03d971446924", "quantity": "0", "takeProfitTriggerPrice": "0.007359", "takeProfitPlacePrice": "0.0073" }, { "orderId": "e281eb8e-c315-4372-a7b6-8c5e5f5eb971", "triggerOrderSide": "sell", "triggerOrderType": "limit-reduce-only", "currencyPair": "AVAXUSDTPERP", "createdAt": "2024-10-12T03:08:19.060Z", "updatedAt": "2024-10-12T03:08:19.060Z", "triggerType": "LAST_TRADED", "conditionalType": "OT_OCO", "customerOrderId": "ConditionalByLastTraded", "quantity": "0.2", "takeProfitTriggerPrice": "44.74", "takeProfitPlacePrice": "44.8", "stopLossTriggerPrice": "30.1", "stopLossPlacePrice": "30", "linkedOrderId": "5b5ca343-2063-40dd-9c31-840dc72a5aab" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1AccountBalancesAll.md description: GET /v1/account/balances/all --- # Get all non-zero balances `GET /v1/account/balances/all` **Tags:** Subaccounts Returns the entire portfolio's balances that are greater than 0, grouped by account for the primary account and its subaccounts. Accounts with neither balance nor debt will be returned with an empty array. Can only be called using a primary account API key. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Portfolio balances retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | account | object | Yes | - | | balances | V1CurrencyBalanceForApi\[] | Yes | - | **`account` properties:** | Property | Type | Required | Description | |---|---|---|---| | label | string | Yes | - | | id | string | Yes | - | | accountTags | string\[] | No | - | | autoPayoutLinkedBankAccountId | string | No | - | **`balances` properties:** | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | - | | available | string | Yes | - | | reserved | string | Yes | - | | total | string | Yes | - | | updatedAt | string | No | - | | lendReserved | string | Yes | - | | borrowReserved | string | Yes | - | | borrowedAmount | string | Yes | - | **Example:** ```json [ { "account": { "label": "ox", "id": "1385226517613019136" }, "balances": [ { "currency": "ZAR", "available": "0", "reserved": "0", "total": "15", "updatedAt": "2025-07-01T10:46:29.408Z", "lendReserved": "0", "borrowReserved": "15", "borrowedAmount": "0" } ] }, { "account": { "label": "API key test", "id": "1385148772766830592" }, "balances": [] }, { "account": { "label": "Primary", "id": "0" }, "balances": [ { "currency": "ZAR", "available": "1265172.33437585412", "reserved": "0", "total": "1665172.33437585412", "updatedAt": "2025-07-01T14:14:37.218Z", "lendReserved": "400000", "borrowReserved": "0", "borrowedAmount": "0" }, { "currency": "USDC", "available": "83241.870104015439", "reserved": "5.5", "total": "83247.370104015439", "updatedAt": "2025-07-03T07:19:01.245Z", "lendReserved": "0", "borrowReserved": "0", "borrowedAmount": "0" } ] } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersOpen.md description: GET /v1/orders/open --- # Get all open orders `GET /v1/orders/open` **Tags:** Orders Get all open orders for your account. A customerOrderId field will be returned in the response for all those orders that were created with a customerOrderId field. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Open orders retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | Unique identifier for the order assigned by VALR | | side | string | Yes | Order side: buy or sell | | remainingQuantity | string | Yes | The quantity still to be filled | | price | string | Yes | The limit price of the order | | currencyPair | string | Yes | The currency pair (e.g., BTCZAR, ETHUSDC) | | createdAt | string | Yes | - | | originalQuantity | string | Yes | The total quantity specified when the order was placed | | filledPercentage | string | Yes | Percentage of the order that has been filled (0.00 to 100.00) | | customerOrderId | string | No | - | | stopPrice | string | No | - | | updatedAt | string | Yes | - | | status | string | Yes | Current status: Placed, Partially Filled | | type | string | Yes | Order type: limit, post-only limit | | timeInForce | string | Yes | Time in force policy: GTC, FOK, IOC | | allowMargin | boolean | Yes | Whether this order uses margin/leverage | **Example:** ```json [ { "orderId": "4cbf1b17-fa28-4be3-8d36-08b829cfedf9", "side": "sell", "remainingQuantity": "0.00005062", "price": "66391", "currencyPair": "BTCUSDC", "createdAt": "2024-05-08T11:51:29.169Z", "originalQuantity": "0.00015062", "filledPercentage": "66.39", "updatedAt": "2024-05-08T11:51:29.181Z", "status": "Partially Filled", "type": "limit", "timeInForce": "GTC", "allowMargin": true }, { "orderId": "4352df1d-6d24-472e-8a81-9c03e74690e7", "side": "sell", "remainingQuantity": "3", "price": "17.9", "currencyPair": "AVAXUSDC", "createdAt": "2024-05-08T11:55:14.422Z", "originalQuantity": "3", "filledPercentage": "0.00", "updatedAt": "2024-05-08T11:55:14.423Z", "status": "Placed", "type": "limit", "timeInForce": "GTC", "allowMargin": false } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV2Healthz.md description: GET /v2/healthz --- # Get API health status `GET /v2/healthz` **Tags:** Public Get the current status of the API. A 200 response indicates that the API is available. When VALR status is "read-only", all POST and DELETE requests on the API will return a 503 response. See the VALR Status endpoint for more information. ## Responses ### 200 Service is healthy --- --- url: /api-docs/getV1WalletFiatCurrencyDepositReferenceBuyCurrencySymbol.md description: 'GET /v1/wallet/fiat/{currency}/deposit/reference/{buyCurrencySymbol}' --- # Get auto-buy deposit reference `GET /v1/wallet/fiat/{currency}/deposit/reference/{buyCurrencySymbol}` **Tags:** Fiat Wallet Get the unique auto-buy Deposit Reference for the primary account or subaccount whose API Key is authorised. Payments in the `currencyCode` currency made with this reference will be used to buy `buyCurrencySymbol` currency. Use the Supported Auto-Buy Currencies request for the list of currencies supported for auto-buy with the pay currency. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR, USD) | | buyCurrencySymbol | path | string | Yes | The currency code to buy (e.g., BTC, ETH). See Supported Auto-Buy Currencies. | ## Responses ### 200 Auto-buy deposit reference retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "reference": "ETH2YBLFVQ" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicRisklimitCurrencyPair.md description: 'GET /v1/public/risklimit/{currencyPair}' --- # Get available leverage options `GET /v1/public/risklimit/{currencyPair}` **Tags:** Public Get the available leverage options for a given currency pair. Returns information about each leverage tier including initial margin fraction, maintenance margin fraction, auto-close margin fraction, risk limit value, and whether the tier is the default for the pair. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you would like to view the available leverage options. Example: ETHUSDTPERP | ## Responses ### 200 Available leverage options retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | pairSymbol | string | Yes | The symbol of the pair being queried. | | leverageMultiple | number | Yes | The debt-to-equity ratio, which is also the inverse of margin fraction. | | initialMarginFraction | number | Yes | The initial margin fraction required to place an order. | | maintenanceMarginFraction | number | Yes | The maintenance margin fraction below which stage 1 liquidation is triggered. | | autoCloseMarginFraction | number | Yes | The account margin fraction below which an account's debt and assets are transferred to the insurance fund, leaving the account with no further assets, debt or equity. | | riskLimitValue | number | Yes | The maximum position size in the chosen leverage tier in `riskLimitCurrency`. | | riskLimitCurrency | string | Yes | The currency symbol that the risk limit is specified in. | | isDefault | boolean | Yes | When `true` this indicates that this leverage tier is the VALR default for this pair. | **Example:** ```json [ { "pairSymbol": "BTCUSDTPERP", "leverageMultiple": 1, "initialMarginFraction": 1, "maintenanceMarginFraction": 0.25, "autoCloseMarginFraction": 0.0083, "riskLimitValue": 1500000, "riskLimitCurrency": "USDT", "isDefault": false }, { "pairSymbol": "BTCUSDTPERP", "leverageMultiple": 2, "initialMarginFraction": 0.5, "maintenanceMarginFraction": 0.25, "autoCloseMarginFraction": 0.0083, "riskLimitValue": 1500000, "riskLimitCurrency": "USDT", "isDefault": false } ] ``` ### 400 Unsupported currency pair **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -21, "message": "Unsupported Currency Pair" } ``` --- --- url: /api-docs/getV1WalletFiatCurrencyAccountsId.md description: 'GET /v1/wallet/fiat/{currency}/accounts/{id}' --- # Get bank account detail `GET /v1/wallet/fiat/{currency}/accounts/{id}` **Tags:** Fiat Wallet Get the details of a linked bank account. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR) | | id | path | string | Yes | The UUID identifier of the linked bank account | ## Responses ### 200 Bank account details retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "id": "47818b9d-1fdf-48b3-97f4-2578b5456a9a", "bank": "FNB/RMB", "accountHolder": "Frodo Baggins", "accountNumber": "62004626662", "branchCode": "250655", "accountType": "Current/Cheque", "createdAt": "2019-08-08T08:30:27.495181Z", "country": "ZA" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletFiatCurrencyAccounts.md description: 'GET /v1/wallet/fiat/{currency}/accounts' --- # Get bank accounts `GET /v1/wallet/fiat/{currency}/accounts` **Tags:** Fiat Wallet Get a list of bank accounts that are linked to your VALR account. Bank accounts can be linked by signing in to your account on www.VALR.com or by using the Add Bank Account request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR) | ## Responses ### 200 Bank accounts retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "id": "a4368195-571b-499f-93ae-717c44f92b1b", "bank": "FNB/RMB", "accountHolder": "Frodo Baggins", "accountNumber": "62792461544", "branchCode": "040000", "accountType": "Current/Cheque", "createdAt": "2023-03-03T14:37:24.095872Z", "country": "ZA" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletFiatCurrencyBanks.md description: 'GET /v1/wallet/fiat/{currency}/banks' --- # Get banks for currency `GET /v1/wallet/fiat/{currency}/banks` **Tags:** Fiat Wallet Get a list of banks supported for a given currency. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR) | ## Responses ### 200 Banks retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | code | string | Yes | - | | displayName | string | Yes | - | | defaultBranchCode | string | Yes | - | | rtcParticipant | boolean | Yes | - | | rtgsParticipant | boolean | Yes | - | | countryCode | string (UNDEFINED, AC, AD, AE, AF, AG, AI, AL, ...) | Yes | - | | deprecated | string | No | - | **Example:** ```json [ { "code": "ABSA", "displayName": "ABSA Bank", "defaultBranchCode": "632005", "rtcParticipant": true, "rtgsParticipant": true, "countryCode": "ZA" }, { "code": "FNB", "displayName": "FNB/RMB", "defaultBranchCode": "250655", "rtcParticipant": true, "rtgsParticipant": true, "countryCode": "ZA" }, { "code": "CAPITEC", "displayName": "Capitec Bank", "defaultBranchCode": "470010", "rtcParticipant": true, "rtgsParticipant": false, "countryCode": "ZA" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1BorrowsCurrencySymbolHistory.md description: 'GET /v1/borrows/{currencySymbol}/history' --- # Get Borrows History `GET /v1/borrows/{currencySymbol}/history` **Tags:** Borrows Returns a history of interest entries as calculated during the margin interest auction runs. At the beginning of every hour, the interest engine calculates the total borrow demand for each coin among all users. An auction is run by sorting the lending offers by minimum rate and taking the cheapest set that satisfies the borrowing demand. The borrowing rate is set to the minimum of the required marginal (most expensive) loan. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencySymbol | path | string | Yes | The currency symbol to filter borrow history by (e.g., BTC) | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2023-11-14T22:00:00.000Z) | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2023-12-14T22:00:00.000Z) | ## Responses ### 200 Borrows history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | - | | interestAmount | string | Yes | - | | quantity | string | Yes | - | | createdAt | string | Yes | - | **Example:** ```json [ { "currency": "BTC", "interestAmount": "0.00000002", "quantity": "0.0010096", "createdAt": "2023-04-23T10:00:00.098808Z" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV2BrokerageHistory.md description: GET /v2/brokerage/history --- # Get brokerage instruction history `GET /v2/brokerage/history` **Tags:** Brokerage Get brokerage instruction history. To retrieve all instructions across all subaccounts, make this request for your main account and specify `includeSubAccounts=true` as a query parameter. To retrieve all instructions for a particular subaccount, make this request using the `X-VALR-SUB-ACCOUNT-ID` header. Please see the Account / Subaccounts section for more information. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Skip this number of results. Default 0. | | limit | query | integer | No | Limit the results to this number. Default and Max 100. | | includeSubAccounts | query | boolean | No | If true, brokerage instruction history will be returned for the main account and all the subaccounts. Default false. | ## Responses ### 200 Brokerage instruction history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | identifier | string | Yes | Unique identifier for the brokerage instruction. | | orderId | string | Yes | Order id for the simple swap or the simple order placed as part of the brokerage instruction. | | transferId | string | No | The id of the internal transfer used to sweep the brokerage fee into the fee account. | | accountId | integer (int64) | Yes | Account on which the simple order / simple swap took place. `0` indicates the main account was used. | | feeAccountId | integer (int64) | Yes | The account to which the brokerage fee was transferred. | | requestedPayAmount | string | Yes | The total value of the brokerage instruction as specified in the request's `payAmount`. | | actualPayAmount | string | No | The total amount the simple order or swap was placed for. | | payCurrency | string | Yes | The currency for the amount specified in `payAmount`. | | receiveCurrency | string | Yes | The currency received after the simple order / swap completed. | | receiveAmount | string | No | The amount received in `receiveCurrency` after the simple order / swap completed. | | feeRate | string | Yes | The rate of the brokerage fee levied. | | feeCurrency | string | Yes | The currency in which the brokerage fee was collected. | | feeAmount | string | No | The total amount of the brokerage fee collected. | | customerOrderId | string | No | The custom order id specified in the request. | | createdAt | integer (int64) | Yes | Timestamp when the brokerage instruction was created (UTC). | | status | string | Yes | The status of the brokerage instruction. | | leg1TradeFeeAmount | string | No | Trade fees levied by VALR for the simple order or the first of two trades in a simple swap. | | leg1TradeFeeCurrency | string | No | The currency in which `leg1TradeFeeAmount` was levied. | | leg2TradeFeeAmount | string | No | Trade fees levied by VALR for the second of two trades in a simple swap. Not included if a simple order was used. | | leg2TradeFeeCurrency | string | No | The currency in which `leg2TradeFeeAmount` was levied. Not included if a simple order was used. | **Example:** ```json [ { "identifier": "48657a89-5ff6-483c-a8d4-e8a1d0648fb4", "orderId": "de689cf3-f667-4104-905b-2fdb439618bc", "transferId": "377573", "accountId": 0, "feeAccountId": 1311349150067826700, "requestedPayAmount": "100", "actualPayAmount": "99.99857355", "payCurrency": "ZAR", "receiveCurrency": "XRP", "receiveAmount": "75.544", "feeRate": "0.01", "feeCurrency": "XRP", "feeAmount": "0.75544", "customerOrderId": "brokerage-order-01", "createdAt": 1739378546678, "status": "COMPLETED", "leg1TradeFeeAmount": "0.0314130", "leg1TradeFeeCurrency": "USDT", "leg2TradeFeeAmount": "0.456", "leg2TradeFeeCurrency": "XRP" } ] ``` ### 401 Unauthorised - requires API key with view permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV2BrokerageQuote.md description: POST /v2/brokerage/quote --- # Get brokerage instruction quote `POST /v2/brokerage/quote` **Tags:** Brokerage Generate a new brokerage instruction quote. This quote is not guaranteed but serves as an indicator of how the brokerage instruction will execute. The brokerage instruction system automatically determines the necessary trades to convert from the pay currency to the receive currency, potentially using intermediate currency pairs. For example, converting ZAR to XRP might route as ZAR→USDT→XRP if no direct ZAR/XRP pair exists. ## Important Notes * The account on which the trade is performed can be specified using the HTTP header. Please see our Subaccounts section for more information. Not including the header will result in the order being placed against your main account. * **feeAccountId**: This account cannot be the same as the account in which the simple order / simple swap is placed. * **feeCurrency**: If the `feeCurrency` matches the `payCurrency` then the brokerage fee will be calculated from the `payAmount` prior to the simple order being placed. If the `feeCurrency` matches the `receiveCurrency` then the brokerage fee will be calculated after the simple order / swap has completed and will be a percentage of the received amount. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | payAmount | string | Yes | The total amount to be traded. The trade and brokerage fees should be included in this amount. | | payCurrency | string | Yes | The currency for the amount specified in `payAmount`. | | receiveCurrency | string | Yes | The currency that will be received after the simple order / swap completes. | | feeRate | number | Yes | The brokerage fee levied. `0.000` to `0.999` allowed. Fees are specified as a fraction, e.g. a 10% brokerage fee is `0.1`. | | feeCurrency | string | Yes | The currency in which the brokerage fee is to be collected. This should match either `payCurrency` or `receiveCurrency`. | | feeAccountId | integer (int64) | Yes | The account id to which the brokerage fee will be transferred. Set to `0` for the main account. Defaults to `0`. | | customerOrderId | string | No | Custom order id for tracking. Alphanumeric with a 50-character limit. | ## Responses ### 200 Quote generated successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | requestPayAmount | string | Yes | - | | actualPayAmount | string | Yes | - | | payCurrency | string | Yes | - | | receiveCurrency | string | Yes | - | | receiveAmount | string | Yes | - | | averagePrice | string | Yes | - | | leg1CurrencyPair | string | Yes | - | | leg2CurrencyPair | string | No | - | | averagePriceInPayCurrency | string | No | - | | averagePriceInReceiveCurrency | string | No | - | | feeRate | string | Yes | - | | feeAmount | string | Yes | - | | feeCurrency | string | Yes | - | | feeAccountId | integer (int64) | Yes | - | | customerOrderId | string | No | - | | leg1TradeFeeAmount | string | No | - | | leg1TradeFeeCurrency | string | No | - | | leg2TradeFeeAmount | string | No | - | | leg2TradeFeeCurrency | string | No | - | **Example:** ```json { "requestPayAmount": "100", "actualPayAmount": "100", "payCurrency": "ZAR", "receiveCurrency": "XRP", "receiveAmount": "75", "averagePrice": "1.3", "leg1CurrencyPair": "USDTZAR", "leg2CurrencyPair": "XRPUSDT", "averagePriceInPayCurrency": "1.3", "averagePriceInReceiveCurrency": "0.786", "feeRate": "0.01", "feeAmount": "0.75", "feeCurrency": "XRP", "feeAccountId": 1315586846625202200, "customerOrderId": "brokerage-order-01", "leg1TradeFeeAmount": "0.031413", "leg1TradeFeeCurrency": "USDT", "leg2TradeFeeAmount": "0.456", "leg2TradeFeeCurrency": "XRP" } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - requires API key with trade and internal transfer permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Insufficient funds or fee account access denied **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1BundlesTransactions.md description: GET /v1/bundles/transactions --- # Get Bundle Transaction History `GET /v1/bundles/transactions` **Tags:** Bundles Returns the bundle transaction history for the current account. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | bundleSymbol | query | string | Yes | The bundle symbol to filter by (e.g., VALR3, VALR10) | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | ## Responses ### 200 Bundle transaction history retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "id": "0199ffe6-c82f-70f2-88f0-65ef198a41f3", "symbol": "VALR10", "transactionType": "BUY", "payAmount": 5, "payCurrency": "USDT", "receiveAmount": "0.05431821", "receiveCurrency": "VALR10", "status": "complete", "createdAt": 1762248056314, "updatedAt": 1762248057125 } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PositionsClosed.md description: GET /v1/positions/closed --- # Get Closed Futures Positions Detail `GET /v1/positions/closed` **Tags:** Futures Returns a detailed view of the closed futures positions for an account, including pair, side, quantity, realised PnL, close type (Trade, Liquidation, Adl), close price, session average entry price, created timestamp, fees, and position ID. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | query | string | No | The name of the perpetual futures contract (e.g., BTCUSDTPERP) | | skip | query | integer | No | Skip this number of results (default 0) | | limit | query | integer | No | Limit the results to this number (default and max 100) | ## Responses ### 200 Closed futures positions detail retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | orderSide | string | Yes | - | | quantity | string | Yes | - | | averageEntryPrice | string | Yes | - | | closePrice | string | Yes | - | | realisedPnl | string | Yes | - | | closeType | string | Yes | - | | createdAt | string | Yes | - | | fees | string | Yes | - | | positionId | string | Yes | - | | initialMarginFractionAtClose | string | No | - | **Example:** ```json [ { "currencyPair": "USDTZARPERP", "orderSide": "buy", "quantity": "40", "averageEntryPrice": "19.01", "closePrice": "19", "realisedPnl": "-1.160201", "closeType": "Trade", "createdAt": "2023-11-14T19:51:49.988Z", "fees": "0.760201", "positionId": "046f52a0-758c-6ec8-28a9-03fe7b0b51bc" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PositionsClosedSummary.md description: GET /v1/positions/closed/summary --- # Get Closed Futures Positions Summary `GET /v1/positions/closed/summary` **Tags:** Futures Returns a summary of the closed futures positions for an account, including side, quantity, realised PnL, average entry price, position ID, currency pair, average close price, fees, and position created timestamp. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Closed futures positions summary retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | side | string | Yes | - | | quantity | string | Yes | - | | averageEntryPrice | string | Yes | - | | averageClosePrice | string | Yes | - | | realisedPnl | string | Yes | - | | fees | string | Yes | - | | positionCreatedAt | string | Yes | - | | positionId | string | Yes | - | | positionUpdatedAt | string | Yes | - | | initialMarginFractionAtClose | string | No | - | **Example:** ```json [ { "currencyPair": "USDTZARPERP", "side": "buy", "quantity": "44", "averageEntryPrice": "19.01", "averageClosePrice": "19", "realisedPnl": "-1.27622", "fees": "0.83622", "positionCreatedAt": "2023-11-14T19:49:09.317Z", "positionId": "046f52a0-758c-6ec8-28a9-03fe7b0b51bc" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersConditionalsConditionalCurrencyPairOrderidOrderId.md description: 'GET /v1/orders/conditionals/conditional/{currencyPair}/orderid/{orderId}' --- # Get conditional order status by order ID `GET /v1/orders/conditionals/conditional/{currencyPair}/orderid/{orderId}` **Tags:** Conditional Orders Get the conditional order status. A customerOrderId field will be returned in the response for all those orders that were created with a customerOrderId field. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | A valid currency pair (e.g., BTCUSDTPERP for futures, BTCZAR for spot) | | orderId | path | string | Yes | The order ID provided by VALR | ## Responses ### 200 Conditional order status retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | triggerOrderSide | string | Yes | - | | triggerOrderType | string | Yes | - | | currencyPair | string | Yes | - | | createdAt | string | Yes | - | | updatedAt | string | Yes | - | | triggerType | string | Yes | - | | conditionalType | string | Yes | - | | customerOrderId | string | No | - | | orderStatusType | string | Yes | - | | failedReason | string | No | - | | removeReason | string | No | - | | quantity | string | Yes | - | | takeProfitTriggerPrice | string | No | - | | takeProfitPlacePrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossPlacePrice | string | No | - | | linkedOrderId | string (uuid) | No | - | **Example:** ```json { "orderId": "e281eb8e-c315-4372-a7b6-8c5e5f5eb971", "triggerOrderSide": "sell", "triggerOrderType": "limit-reduce-only", "currencyPair": "AVAXUSDTPERP", "createdAt": "2024-10-12T03:08:19.060Z", "updatedAt": "2024-10-12T03:08:19.060Z", "triggerType": "LAST_TRADED", "conditionalType": "OT_OCO", "customerOrderId": "ConditionalByLastTraded", "orderStatusType": "Placed", "quantity": "0.2", "takeProfitTriggerPrice": "44.74", "takeProfitPlacePrice": "44.8", "stopLossTriggerPrice": "30.1", "stopLossPlacePrice": "44.8", "linkedOrderId": "5b5ca343-2063-40dd-9c31-840dc72a5aab" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Conditional order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersConditionalsCurrencyPairHistory.md description: 'GET /v1/orders/conditionals/{currencyPair}/history' --- # Get conditional order status history `GET /v1/orders/conditionals/{currencyPair}/history` **Tags:** Conditional Orders Get all conditional orders for your account per currency pair. A customerOrderId field will be returned in the response for all those orders that were created with a customerOrderId field. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | A valid currency pair (e.g., BTCUSDTPERP for futures, BTCZAR for spot) | | skip | query | integer | No | Number of records to skip for pagination | | limit | query | integer | No | Maximum number of records to return | | startTime | query | string | No | Start time in ISO 8601 format | | endTime | query | string | No | End time in ISO 8601 format | | triggeredOnly | query | boolean | No | If true, return only triggered conditional orders. Default false. | | removedOnly | query | boolean | No | If true, return only removed conditional orders. Default false. | | failedOnly | query | boolean | No | If true, return only failed conditional orders. Default false. | ## Responses ### 200 Conditional order status history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | triggerOrderSide | string | Yes | - | | triggerOrderType | string | Yes | - | | currencyPair | string | Yes | - | | createdAt | string | Yes | - | | updatedAt | string | Yes | - | | triggerType | string | Yes | - | | conditionalType | string | Yes | - | | customerOrderId | string | No | - | | orderStatusType | string | Yes | - | | failedReason | string | No | - | | removeReason | string | No | - | | quantity | string | Yes | - | | takeProfitTriggerPrice | string | No | - | | takeProfitPlacePrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossPlacePrice | string | No | - | | linkedOrderId | string (uuid) | No | - | **Example:** ```json [ { "orderId": "e281eb8e-c315-4372-a7b6-8c5e5f5eb971", "triggerOrderSide": "sell", "triggerOrderType": "limit-reduce-only", "currencyPair": "AVAXUSDTPERP", "createdAt": "2024-10-12T03:08:19.060Z", "updatedAt": "2024-10-12T03:08:19.167Z", "triggerType": "LAST_TRADED", "conditionalType": "OT_OCO", "customerOrderId": "ConditionalByLastTraded", "orderStatusType": "Placed", "quantity": "0.2", "takeProfitTriggerPrice": "44.74", "takeProfitPlacePrice": "44.8", "stopLossTriggerPrice": "30.1", "stopLossPlacePrice": "30", "linkedOrderId": "5b5ca343-2063-40dd-9c31-840dc72a5aab" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1AccountApi-keysCurrent.md description: GET /v1/account/api-keys/current --- # Get current API key info `GET /v1/account/api-keys/current` **Tags:** Account Returns the current API Key's information and permissions. This information includes the label, date created, and permissions. Permission levels are View Access, Trade, or Withdraw. If an API key has Whitelisted IP address ranges or Whitelisted Withdrawal addresses, the IP addresses and Currency withdrawal addresses will also be returned. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 API key info retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | label | string | Yes | - | | permissions | string\[] | Yes | - | | addedAt | string | Yes | - | | allowedIpAddressCidr | string | No | - | | allowedCountryCode | string | No | - | | allowedWithdrawAddressList | ApiKeyAllowedWithdrawAddressForDisplay\[] | No | - | | isSubAccount | boolean | Yes | - | **`allowedWithdrawAddressList` properties:** | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | - | | address | string | Yes | - | | networkType | string | No | - | | paymentReference | string | No | - | **Example:** ```json { "label": "Full Access Whitelisted IP and Address", "permissions": [ "View access", "Trade", "Withdraw" ], "addedAt": "2021-09-11T18:28:37.791401Z", "allowedIpAddressCidr": "41.157.66.231/32", "allowedWithdrawAddressList": [ { "currency": "BTC", "address": "2N1QAxqSn2B3CiHsLSzeReuysQXyCT8ZXWj" } ] } ``` ### 401 Unauthorised - Invalid or missing API key, or IP not whitelisted **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -11272, "message": "The originating IP Address has not been whitelisted." } ``` --- --- url: /api-docs/getV1WalletCryptoCurrencyDepositAddress.md description: 'GET /v1/wallet/crypto/{currency}/deposit/address' --- # Get deposit address `GET /v1/wallet/crypto/{currency}/deposit/address` **Tags:** Crypto Wallet Returns the default deposit address associated with currency specified in the path variable `:currencyCode` and the query param `networkType` (if specified). If `networkType` is not specified, it will be defaulted based on the configuration for the currency that can be found at `/v1/public/currencies`. Please also consult the supporting documentation for the `/v1/public/currencies` api which illustrates different network type scenarios. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency for which to get your deposit address (e.g., BTC, ETH, XRP) | | networkType | query | string | No | The network type to use when depositing the specified currency. If not specified, it will be defaulted based on the currency configuration. | ## Responses ### 200 Deposit address retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "currency": "ETH", "address": "0x614A03eBc3cC4a57Da341e52e4a0E9f89221710D", "networkType": "Ethereum" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletCryptoDepositHistory.md description: GET /v1/wallet/crypto/deposit/history --- # Get deposit history `GET /v1/wallet/crypto/deposit/history` **Tags:** Crypto Wallet Get the Deposit History records for a given currency. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Skip this number of results. (Default 0) | | limit | query | integer | No | Limit the results to this number. (Default and Max 100) | | startTime | query | string | No | ISO 8601 string (e.g., 2025-01-01T00:00:00Z) for the start of the time range. Defaults to the earliest date if not provided. | | endTime | query | string | No | ISO 8601 string (e.g., 2025-01-31T23:59:59Z) for the end of the time range. Defaults to the latest date if not provided. | | currency | query | string | No | Currency Code (e.g., BTC, ETH, XRP, ADA). Leave empty to retrieve records for all currencies. | ## Responses ### 200 Deposit history retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "currencyCode": "ETH", "receiveAddress": "0xcfb6fdfc030ec1b51eb1a03689f19735fdebe3b0", "transactionHash": "0xd97ca2ce13707cce6ce2b211499e14d04ce104250dbeb0b59359563c05a0577d", "amount": "0.0005", "createdAt": "2025-06-05T08:40:48Z", "confirmations": 5, "confirmed": true, "confirmedAt": "2025-06-05T08:41:56.879293Z" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletFiatCurrencyDepositReference.md description: 'GET /v1/wallet/fiat/{currency}/deposit/reference' --- # Get deposit reference `GET /v1/wallet/fiat/{currency}/deposit/reference` **Tags:** Fiat Wallet Get the unique Deposit Reference for the primary account or subaccount whose API Key is authorised. Payments made with this reference will be credited to your account. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR, USD) | ## Responses ### 200 Deposit reference retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | reference | string | Yes | - | **Example:** ```json { "reference": "VR8AFU9DD6" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1StakingBalances.md description: GET /v1/staking/balances --- # Get Earn Balances `GET /v1/staking/balances` **Tags:** Staking / DeFi Lending Get the current balances for the specified `earnType`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | earnType | query | string | No | The type of earn product to filter by. | ## Responses ### 200 Earn balances retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "currencySymbol": "SOL", "amount": "0.0001", "earnType": "STAKE", "lastUpdated": "2024-09-27T02:47:34.671Z" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1StakingBalancesAll.md description: GET /v1/staking/balances/all --- # Get Earn Balances for All Accounts `GET /v1/staking/balances/all` **Tags:** Staking / DeFi Lending Get the current balances for a specific `earnType` for all accounts (primary and subaccounts). ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | earnType | query | string | No | The type of earn product to filter by. | ## Responses ### 200 Earn balances for all accounts retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "accountLabel": "Primary", "accountPublicId": "0", "balances": [ { "currencySymbol": "SOL", "amount": "0", "earnType": "Stake", "lastUpdated": "2025-08-14T09:54:59.477Z" } ] } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1StakingHistory.md description: GET /v1/staking/history --- # Get Earn History `GET /v1/staking/history` **Tags:** Staking / DeFi Lending Get up to 100 of the most recent history items based on the specified skip and limit values. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencySymbol | query | string | No | The currency symbol to filter by (e.g., BTC, ETH). | | earnType | query | string | No | The type of earn product to filter by. | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | ## Responses ### 200 Earn history retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "type": "LOCK", "currencySymbol": "SOL", "amount": "0.0001", "earnType": "STAKE", "completedAt": "2024-09-27T02:47:34.671Z" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1StakingRates.md description: GET /v1/staking/rates --- # Get Earn Rates `GET /v1/staking/rates` **Tags:** Staking / DeFi Lending Get earn rates for available currencies for the specified `earnType`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | earnType | query | string | No | The type of earn product to filter by. | ## Responses ### 200 Earn rates retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "currencySymbol": "AVAX", "rate": "0.000001106846", "apy": "0.0096", "periodIntervalMinutes": 60, "minimumStakeAmount": "0", "earnType": "STAKE" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1StakingRewards.md description: GET /v1/staking/rewards --- # Get Earn Rewards `GET /v1/staking/rewards` **Tags:** Staking / DeFi Lending Get up to 100 of the most recent reward items based on the specified skip and limit values. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencySymbol | query | string | No | The currency symbol to filter by (e.g., BTC, ETH). | | earnType | query | string | No | The type of earn product to filter by. | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | ## Responses ### 200 Earn rewards retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "period": "2024-09-27T02:00:00Z", "rewardAmount": "0.000001", "rate": "0.000001106846", "ratePerYear": "0.0096", "currencySymbol": "SOL", "earnType": "STAKE" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1MarketdataCurrencyPairOrderbookFull.md description: 'GET /v1/marketdata/{currencyPair}/orderbook/full' --- # Get full order book `GET /v1/marketdata/{currencyPair}/orderbook/full` **Tags:** Market Data Returns a list of all the bids and asks in the order book. Ask orders are sorted by price ascending. Bid orders are sorted by price descending. Orders of the same price are NOT aggregated. The LastChange field indicates the timestamp of the last update to the order book. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair for which you would like to query the order book | ## Responses ### 200 Full order book retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | Asks | V1FullOrderForApi\[] | Yes | - | | Bids | V1FullOrderForApi\[] | Yes | - | | LastChange | string | Yes | - | | SequenceNumber | integer (int64) | Yes | - | **`Asks` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | id | string (uuid) | Yes | - | | positionAtPrice | integer (int32) | Yes | - | **`Bids` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | id | string (uuid) | Yes | - | | positionAtPrice | integer (int32) | Yes | - | **Example:** ```json { "Asks": [ { "side": "sell", "quantity": "0.998418", "price": "118000", "currencyPair": "BTCUSDC", "id": "0198187f-528b-7856-a6e0-8349fbc5f607", "positionAtPrice": 1 } ], "Bids": [ { "side": "buy", "quantity": "0.0000043", "price": "117819", "currencyPair": "BTCUSDC", "id": "01981a20-ea17-702f-b0ab-62b4b0526be2", "positionAtPrice": 1 }, { "side": "buy", "quantity": "0.00001", "price": "117819", "currencyPair": "BTCUSDC", "id": "01981a20-ea7b-7dce-bc85-5d3c6f4fc7e6", "positionAtPrice": 2 } ], "LastChange": "2025-08-05T08:51:11.470Z", "SequenceNumber": 2907775 } ``` ### 400 Invalid currency pair **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicCurrencyPairOrderbookFull.md description: 'GET /v1/public/{currencyPair}/orderbook/full' --- # Get full order book `GET /v1/public/{currencyPair}/orderbook/full` **Tags:** Public Returns a list of all the bids and asks in the order book. Ask orders are sorted by price ascending. Bid orders are sorted by price descending. Orders of the same price are NOT aggregated. The LastChange field indicates the timestamp of the last update to the order book. Please note: This is not an authenticated call. More constrained rate-limiting rules will apply than when you use the /marketdata/:currencyPair/orderbook/full route. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Currency pair for which you want to query the order book | ## Responses ### 200 Full order book retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | Asks | V1FullOrderForApi\[] | Yes | - | | Bids | V1FullOrderForApi\[] | Yes | - | | LastChange | string | Yes | - | | SequenceNumber | integer (int64) | Yes | - | **`Asks` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | id | string (uuid) | Yes | - | | positionAtPrice | integer (int32) | Yes | - | **`Bids` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | id | string (uuid) | Yes | - | | positionAtPrice | integer (int32) | Yes | - | **Example:** ```json { "Asks": [ { "side": "sell", "quantity": "0.01293134", "price": "93129", "currencyPair": "BTCUSDT", "id": "01972611-7cd0-7866-a6f3-8bc8f9c4a55a", "positionAtPrice": 1 } ], "Bids": [ { "side": "buy", "quantity": "1.23117023", "price": "81400", "currencyPair": "BTCUSDT", "id": "01966bf8-308b-7fb9-a6db-bf2d6122f08b", "positionAtPrice": 1 }, { "side": "buy", "quantity": "0.00001228", "price": "81400", "currencyPair": "BTCUSDT", "id": "0197f31a-7db7-7e5b-89c5-65337989465f", "positionAtPrice": 2 } ], "LastChange": "2025-07-15T12:19:21.501Z", "SequenceNumber": 282886 } ``` --- --- url: /api-docs/getV1PositionsFundingHistory.md description: GET /v1/positions/funding/history --- # Get Funding History `GET /v1/positions/funding/history` **Tags:** Futures Returns a history of the funding details for an account's positions. If the funding rate is positive, longs paid shorts and vice versa if the rate is negative (i.e. shorts paid longs). ## Filtering by `currencyPair` The `currencyPair` parameter may be used to filter the returned items by the name of the perpetual futures contract expressed as base, quote, PERP, e.g. BTCUSDTPERP. ## Filtering by `startTime` or `endTime` The `startTime` or `endTime` parameters may be used to filter the returned items by the transaction date. The parameters will be interpreted as being in the UTC time zone and must be supplied in the ISO 8601 format (`2023-11-14T22:00:00.000Z`). These two parameters may be used together or separately. When `startTime` is used, transactions that have occurred since `startTime` are returned. When `endTime` is used, transactions that have occurred up to and including `endTime` are returned. When not specified, 30 days worth of transactions are returned by default. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | query | string | Yes | The name of the perpetual futures contract (e.g., BTCUSDTPERP) | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2023-11-14T22:00:00.000Z) | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2023-12-14T22:00:00.000Z) | | skip | query | integer | No | Skip this number of results (default 0) | | limit | query | integer | No | Limit the results to this number (default and max 100) | ## Responses ### 200 Funding history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | side | string | Yes | - | | createdAt | string | Yes | - | | fundingRate | string | Yes | The funding rate that was used for the reported funding period. If the rate is positive, longs paid shorts and vice versa if the rate is negative, i.e. shorts paid longs. | | fundingAmount | string | Yes | The amount actually paid or received at the last funding period, calculated as funding rate multiplied by the position total. | | positionTotal | string | Yes | The value of a position at the time of the previous funding run, calculated as position quantity times mark price. | | positionId | string | No | VALR assigns a unique identifier to track the entire lifecycle of a futures position, from creation and adjustment to the final closure. | **Example:** ```json [ { "currencyPair": "BTCUSDTPERP", "side": "buy", "createdAt": "2025-06-21T12:00:00.491Z", "fundingRate": "-0.001885", "fundingAmount": "0.2545", "positionTotal": "135.0414", "positionId": "237a89ed-b431-df40-28a9-031900d5c4d4" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicFuturesFundingHistory.md description: GET /v1/public/futures/funding/history --- # Get futures funding rate history `GET /v1/public/futures/funding/history` **Tags:** Public Returns the funding rate history for the specified Futures pair. The results of this request may be filtered by currencyPair, startTime and endTime. The skip and limit parameters may be applied to paginate the filtered results. The currencyPair parameter may be used to filter the returned items by the name of the perpetual futures contract expressed as base, quote, PERP, e.g. BTCUSDTPERP. The startTime or endTime parameters may be used to filter the returned items by the funding rate period. The parameters will be interpreted as being in the UTC time zone and must be supplied in the ISO 8601 format (2023-11-14T22:00:00.000Z). These two parameters may be used together or separately. When startTime is used, funding rates that have been active since startTime are returned. When endTime is used, funding rates that have been active up to and including endTime are returned. When not specified, 30 days worth of funding rates are returned by default. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | query | string | Yes | The name of the perpetual futures contract expressed as base, quote, PERP, e.g. BTCUSDTPERP | | skip | query | integer | No | Skip this number of results. Default: 0 | | limit | query | integer | No | Limit the results to this number. Default and Max: 100 | | startTime | query | string | No | Include only funding rates after this ISO 8601 start time | | endTime | query | string | No | Include only funding rates before this ISO 8601 end time | ## Responses ### 200 Funding rate history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | The name of the perpetual futures contract expressed as base, quote, PERP, e.g. BTCUSDTPERP. | | fundingRate | string | Yes | The funding rate that was used for the reported funding period. If the rate is positive, longs paid shorts. Alternatively, if the rate is negative, shorts paid longs. | | fundingTime | string | Yes | The date and time of the funding run. | **Example:** ```json [ { "currencyPair": "BTCUSDTPERP", "fundingRate": "0.000277", "fundingTime": "2025-07-16T11:00:00Z" }, { "currencyPair": "BTCUSDTPERP", "fundingRate": "0.000313", "fundingTime": "2025-07-16T10:00:00Z" } ] ``` --- --- url: /api-docs/getV1PublicFuturesInfo.md description: GET /v1/public/futures/info --- # Get futures information `GET /v1/public/futures/info` **Tags:** Public Returns the futures contracts information for all available perpetual futures pairs on the platform. ## Funding Rate Every hour, each perpetual contract has a funding payment where longs pay shorts if the contract is trading at a premium to the index, and shorts pay longs if the contract is trading at a discount to the index. Funding payments are made in the quote currency of perpetual pairs and are added to/deducted from the account's balance each hour. Positive funding rates denote cases where longs are expected to pay shorts, while negative funding rates denote cases where shorts are expected to pay longs. ## Responses ### 200 Futures information retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | The name of the perpetual futures contract expressed as base, quote, PERP, e.g. `BTCUSDTPERP`. | | estimatedFundingRate | string | Yes | The anticipated funding rate for the next funding run. | | openInterest | string | Yes | The sum of all long positions for a pair, expressed as quantity in base currency. | | nextFundingRun | integer (int64) | Yes | The next scheduled run for funding, scheduled to run at the start of every hour. Expressed as epoch milliseconds. | | nextPnlRun | integer (int64) | Yes | The next scheduled run where unrealised PnL as calculated based on changes in mark price is realised. Profits are added to (and losses deducted from) the account's balances every PnL run in quote currency. Currently PnL runs are scheduled for 4 hourly intervals starting from midnight GMT. Expressed as epoch milliseconds. | **Example:** ```json [ { "currencyPair": "BTCUSDTPERP", "estimatedFundingRate": "-0.000001", "openInterest": "1.8401", "nextFundingRun": 1750165200000, "nextPnlRun": 1750176000000 }, { "currencyPair": "ETHUSDTPERP", "estimatedFundingRate": "0.000072", "openInterest": "69.857", "nextFundingRun": 1750165200000, "nextPnlRun": 1750176000000 } ] ``` --- --- url: /api-docs/getV1PositionsHistory.md description: GET /v1/positions/history --- # Get Futures Positions History `GET /v1/positions/history` **Tags:** Futures Returns a history of futures positions for an account, including update type (New, Increase, Reduce, Adl Reduce, Remove, Pnl), side, quantity, realised PnL, session average entry price, position ID, currency pair, updated timestamp, total session entry quantity, total session value, and average entry price. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | query | string | Yes | The name of the perpetual futures contract (e.g., BTCUSDTPERP) | ## Responses ### 200 Futures positions history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | updateType | string | Yes | - | | currencyPair | string | Yes | - | | side | string | Yes | - | | quantity | string | Yes | - | | realisedPnl | string | Yes | - | | totalSessionEntryQuantity | string | Yes | - | | totalSessionValue | string | Yes | - | | sessionAverageEntryPrice | string | Yes | - | | averageEntryPrice | string | Yes | - | | updatedAt | string | Yes | - | | positionId | string | Yes | - | **Example:** ```json [ { "updateType": "Pnl", "currencyPair": "BTCUSDTPERP", "side": "buy", "quantity": "0.0013", "realisedPnl": "15.22299935", "totalSessionEntryQuantity": "0.0013", "totalSessionValue": "54.2438", "sessionAverageEntryPrice": "41726", "averageEntryPrice": "30001", "updatedAt": "2023-12-05T12:00:00.317Z", "positionId": "237a9503-b32b-5f40-28a9-03fe7ad510d4" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1LoansCredit-history.md description: GET /v1/loans/credit-history --- # Get Interest Earned `GET /v1/loans/credit-history` **Tags:** Lending Returns the history of interest earned on loans for the current account. Each entry represents an interest payment credited from the hourly interest auction. Use the `currencySymbol` query parameter to filter results. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencySymbol | query | string | Yes | The currency symbol to filter by (e.g., BTC, ETH). | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2023-11-14T22:00:00.000Z) | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2023-12-14T22:00:00.000Z) | ## Responses ### 200 Interest earned history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | Currency symbol. | | interestAmount | string | Yes | Interest credited from the interest auction. | | quantity | string | Yes | Amount of the loan offer utilised. | | createdAt | string | Yes | Date and time of the interest auction (UTC). | **Example:** ```json [ { "currency": "USDC", "interestAmount": "0.00004567", "quantity": "10", "createdAt": "2024-10-14T14:00:00.322193Z" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1LoansRates.md description: GET /v1/loans/rates --- # Get Lending Rates `GET /v1/loans/rates` **Tags:** Lending Returns the current lending rates for supported currencies. **Interest Auction** At the start of every hour, the interest engine calculates the total borrow demand for each currency across all users. It then runs an auction by sorting lending offers by minimum rate and selecting the marginal rate that satisfies the total borrowing demand. All lenders receive the same lending rate, which is the highest rate among the loan offers utilised to meet the full borrow demand. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Lending rates retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | Currency symbol. | | previousFundingRate | number (double) | Yes | Interest rate applied during the most recent interest auction. | | estimatedNextRate | number (double) | Yes | Estimated interest rate for the next funding period. | | estimatedNextBorrowRate | string | Yes | Estimated interest rate that will be charged to borrowers in the next funding round. | **Example:** ```json [ { "currency": "ZAR", "previousFundingRate": 0.00001256, "estimatedNextRate": 0.00001427, "estimatedNextBorrowRate": "0.000017124" }, { "currency": "BTC", "previousFundingRate": 0.00000571, "estimatedNextRate": 0.00000685, "estimatedNextBorrowRate": "0.00000822" }, { "currency": "ETH", "previousFundingRate": 0.00000761, "estimatedNextRate": 0.00000761, "estimatedNextBorrowRate": "0.000009132" }, { "currency": "USDT", "previousFundingRate": 0.00001027, "estimatedNextRate": 0.00001027, "estimatedNextBorrowRate": "0.000012324" }, { "currency": "USDC", "previousFundingRate": 0.00000571, "estimatedNextRate": 0.00000571, "estimatedNextBorrowRate": "0.000006852" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1LoansRatesHistory.md description: GET /v1/loans/rates/history --- # Get Lending Rates History `GET /v1/loans/rates/history` **Tags:** Lending Returns rate history and loan book utilisation from previous interest auctions for a specified currency. Use the `currencySymbol` query parameter to filter results. Pagination is supported via `skip` and `limit`, and results can be filtered by `startTime` and `endTime`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencySymbol | query | string | Yes | The currency symbol to filter by (e.g., BTC, ETH). | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2023-11-14T22:00:00.000Z) | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2023-12-14T22:00:00.000Z) | ## Responses ### 200 Lending rates history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | Currency symbol. | | lendingRate | string | Yes | Hourly rate earned by lenders. | | createdAt | integer (int64) | Yes | Timestamp when the hourly rate data was logged (UTC). | | utilization | string | No | Percentage of loan book capacity utilised by borrowers. | | borrowerRate | string | No | Hourly rate charged to borrowers. | **Example:** ```json [ { "currency": "ZAR", "lendingRate": "0.0000114", "createdAt": 1746784800002, "utilization": "6.7", "borrowerRate": "0.00001368" }, { "currency": "ZAR", "lendingRate": "0.0000114", "createdAt": 1746781200001, "utilization": "6.7", "borrowerRate": "0.00001368" } ] ``` ### 400 Bad request - Missing or invalid parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -11, "message": "Invalid Request, please check your request and try again", "validationErrors": { "errors": [ { "field": "currencySymbol", "message": "currencySymbol must be specified" } ] } } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1MarginLeverageCurrencypair.md description: 'GET /v1/margin/leverage/{currencypair}' --- # Get Leverage Information `GET /v1/margin/leverage/{currencypair}` **Tags:** Margin Returns leverage information for the specified currency pair including pair symbol, risk limit, risk limit currency, initial margin fraction, maintenance margin fraction, auto close margin fraction, and leverage multiple. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencypair | path | string | Yes | The currency pair for which to query leverage information (e.g., BTCZARPERP, ETHUSDTPERP) | ## Responses ### 200 Leverage information retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | pairSymbol | string | Yes | The symbol of the pair being queried. | | leverageMultiple | number | Yes | The debt-to-equity ratio, which is also the inverse of margin fraction. | | initialMarginFraction | number | Yes | The initial margin fraction required to place an order. | | maintenanceMarginFraction | number | Yes | The maintenance margin fraction below which stage 1 liquidation is triggered. | | autoCloseMarginFraction | number | Yes | The account margin fraction below which an account's debt and assets are transferred to the insurance fund, leaving the account with no further assets, debt or equity. | | riskLimit | number | Yes | The maximum position size in the chosen leverage tier in `riskLimitCurrency`. | | riskLimitCurrency | string | Yes | The currency symbol that the risk limit is specified in. | **Example:** ```json { "pairSymbol": "ETHUSDTPERP", "leverageMultiple": 10, "initialMarginFraction": 0.1, "maintenanceMarginFraction": 0.05, "autoCloseMarginFraction": 0.03, "riskLimit": 400000, "riskLimitCurrency": "USDT" } ``` ### 400 Bad request - Unsupported currency pair **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -21, "message": "Unsupported Currency Pair" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Returns 404 if margin/futures is not enabled or no leverage is configured for the pair **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1LoansUpdate-history.md description: GET /v1/loans/update-history --- # Get Loan Update History `GET /v1/loans/update-history` **Tags:** Lending Returns historical updates to loan offers, including creations and changes to rates or amounts. Use the `currencySymbol` query parameter to filter results. Pagination is supported via `skip` and `limit`, and results can be filtered by `startTime` and `endTime`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencySymbol | query | string | Yes | The currency symbol to filter by (e.g., BTC, ETH). | | skip | query | integer | No | Number of items to skip before returning results. | | limit | query | integer | No | Maximum number of items to return (max 100). | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2023-11-14T22:00:00.000Z) | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2023-12-14T22:00:00.000Z) | ## Responses ### 200 Loan update history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | loanId | string | Yes | Unique identifier of the loan. | | currency | string | Yes | Currency symbol. | | totalAmount | string | Yes | Total amount of the loan offer. | | availableAmount | string | Yes | Amount available for borrowing. | | usedAmount | string | Yes | Amount currently in use by borrowers. | | hourlyRate | string | Yes | Hourly interest rate, expressed as a percentage. | | createdAt | integer (int64) | Yes | Timestamp when the loan was created (UTC). | | updatedAt | integer (int64) | Yes | Timestamp of the latest update (UTC). | | unlockRequestedAt | integer (int64) | No | Timestamp when an unlock was requested, if applicable. | | unlockRequestedAmount | string | No | Amount requested to unlock, if applicable. | | loanHistoryUpdateType | string (NEW, REMOVE, REDUCE\_AND\_REQUEST\_UNLOCK, RATE\_CHANGE, REQUEST\_UNLOCK, REDUCE, INCREASE, UNLOCK\_CANCELLED, ...) | Yes | Type of update (e.g., CREATE, RATE\_CHANGE, INCREASE, UNLOCK\_REQUESTED). | **Example:** ```json [ { "loanId": "1289055810346737664", "currency": "USDC", "totalAmount": "100", "availableAmount": "100", "usedAmount": "0", "hourlyRate": "0.00001255", "createdAt": 1727401654671, "updatedAt": 1727401654671, "loanHistoryUpdateType": "CREATE" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicCurrencyPairMarkpriceBuckets.md description: 'GET /v1/public/{currencyPair}/markprice/buckets' --- # Get mark price buckets for a currency pair `GET /v1/public/{currencyPair}/markprice/buckets` **Tags:** Public Get the mark price buckets for a given currency pair. A maximum of 300 buckets can be returned per call. This means you cannot specify a startTime and endTime that will contain more buckets than our supported max. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you want to query the mark price buckets. Examples: BTCUSDC, ETHUSDC, XRPUSDC, ADABTC, ADAETH etc. | | periodSeconds | query | integer | No | The bucket period in seconds. Valid values: 60 (default), 300, 900, 1800, 3600, 21600, 86400 | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2025-07-21T08:51:21.604113Z). Default: endTime minus max allowed buckets | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2025-07-21T10:21:21.604113Z). Default: current time | | includeEmpty | query | boolean | No | Include empty buckets in the response | | limit | query | integer | No | Maximum number of buckets to return | | skip | query | integer | No | Number of buckets to skip | ## Responses ### 200 Mark price buckets retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPairSymbol | string | Yes | - | | bucketPeriodInSeconds | integer (int32) | Yes | - | | startTime | string | Yes | - | | open | string | Yes | - | | close | string | Yes | - | | high | string | Yes | - | | low | string | Yes | - | **Example:** ```json [ { "currencyPairSymbol": "BTCUSDT", "bucketPeriodInSeconds": 60, "startTime": "2025-07-16T11:39:00Z", "open": "118834", "close": "118834", "high": "118834", "low": "118834" }, { "currencyPairSymbol": "BTCUSDT", "bucketPeriodInSeconds": 60, "startTime": "2025-07-16T11:38:00Z", "open": "118821", "close": "118821", "high": "118821", "low": "118821" } ] ``` --- --- url: /api-docs/getV1PublicMarketsummary.md description: GET /v1/public/marketsummary --- # Get market summary `GET /v1/public/marketsummary` **Tags:** Public Get the market summary for all supported currency pairs. `markPrice`: A reference price for a trading pair calculated as the median of last traded, best bid and best ask. ## Responses ### 200 List of market summaries for all currency pairs **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | askPrice | string | Yes | - | | bidPrice | string | Yes | - | | lastTradedPrice | string | Yes | - | | previousClosePrice | string | Yes | - | | baseVolume | string | Yes | - | | quoteVolume | string | Yes | - | | highPrice | string | Yes | - | | lowPrice | string | Yes | - | | created | string | Yes | - | | changeFromPrevious | string | Yes | - | | markPrice | string | No | - | **Example:** ```json [ { "currencyPair": "BTCUSDTPERP", "askPrice": "105656", "bidPrice": "105594", "lastTradedPrice": "105611", "previousClosePrice": "106678", "baseVolume": "1.0638", "quoteVolume": "113947.8777", "highPrice": "108840", "lowPrice": "105600", "created": "2025-06-17T12:34:32.069Z", "changeFromPrevious": "-1", "markPrice": "105628" }, { "currencyPair": "USDTUSDC", "askPrice": "1.00046", "bidPrice": "1.00033", "lastTradedPrice": "1.00037", "previousClosePrice": "1.00026", "baseVolume": "757540.1433", "quoteVolume": "757913.592959302", "highPrice": "1.00066", "lowPrice": "1.00023", "created": "2025-06-17T12:34:32.049Z", "changeFromPrevious": "0.01", "markPrice": "1.0003" } ] ``` --- --- url: /api-docs/getV1PublicCurrencyPairMarketsummary.md description: 'GET /v1/public/{currencyPair}/marketsummary' --- # Get market summary for a currency pair `GET /v1/public/{currencyPair}/marketsummary` **Tags:** Public Get the market summary for a given currency pair. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you want to query the market summary. Examples: BTCUSDC, ETHUSDC, XRPUSDC, ETHZAR, ADABTC, ADAETH etc. | ## Responses ### 200 Market summary for the specified currency pair **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | askPrice | string | Yes | - | | bidPrice | string | Yes | - | | lastTradedPrice | string | Yes | - | | previousClosePrice | string | Yes | - | | baseVolume | string | Yes | - | | quoteVolume | string | Yes | - | | highPrice | string | Yes | - | | lowPrice | string | Yes | - | | created | string | Yes | - | | changeFromPrevious | string | Yes | - | | markPrice | string | No | - | **Example:** ```json { "currencyPair": "BTCUSDT", "askPrice": "93129", "bidPrice": "81400", "lastTradedPrice": "93129", "previousClosePrice": "93129", "baseVolume": "0", "quoteVolume": "0", "highPrice": "93129", "lowPrice": "0", "created": "2025-07-17T07:37:05.061Z", "changeFromPrevious": "0", "markPrice": "118156" } ``` --- --- url: /api-docs/getV1PositionsOpen.md description: GET /v1/positions/open --- # Get Open Futures Positions `GET /v1/positions/open` **Tags:** Futures Returns the open futures positions for an account, including pair, side (Buy/Sell), quantity, realised PnL, total session entry quantity, total session value, session average entry price, average entry price, unrealised PnL, and position ID. PnL runs are based on changes in mark price, and additional collateral may be locked for unrealised loss also based on changes in mark price. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | query | string | No | The name of the perpetual futures contract (e.g., BTCUSDTPERP) | | skip | query | integer | No | Skip this number of results (default 0) | | limit | query | integer | No | Limit the results to this number (default and max 100) | ## Responses ### 200 Open futures positions retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | pair | string | Yes | - | | side | string | Yes | - | | quantity | string | Yes | - | | realisedPnl | string | Yes | - | | totalSessionEntryQuantity | string | Yes | - | | totalSessionValue | string | Yes | - | | sessionAverageEntryPrice | string | Yes | - | | averageEntryPrice | string | Yes | - | | unrealisedPnl | string | Yes | - | | updatedAt | string | Yes | - | | createdAt | string | Yes | - | | positionId | string | Yes | - | | leverageTier | number | No | - | **Example:** ```json [ { "pair": "DOGEUSDTPERP", "side": "buy", "quantity": "10", "realisedPnl": "0.58111", "totalSessionEntryQuantity": "10", "totalSessionValue": "2.2823", "sessionAverageEntryPrice": "0.22823", "averageEntryPrice": "0.17", "unrealisedPnl": "0.0283", "updatedAt": "2025-07-24T08:00:00.021Z", "createdAt": "2025-07-23T13:55:24.308Z", "positionId": "a86fb764-cda4-0237-28a9-0361bc8a2334", "leverageTier": 13 } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1LoansOpen.md description: GET /v1/loans/open --- # Get Open Loans `GET /v1/loans/open` **Tags:** Lending Retrieves all loan offers placed by the current account, including details on amounts, rates, and usage. Each entry shows the total amount offered, the amount currently in use by borrowers (accruing interest hourly), and the hourly rate set at loan creation or last modification. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Open loans retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | loanId | string | Yes | Unique identifier of the loan. | | currency | string | Yes | Currency symbol of the loan. | | totalAmount | string | Yes | Total amount currently placed as a loan offer. | | usedAmount | string | Yes | Amount currently in use by borrowers, accruing interest hourly. | | hourlyRate | string | Yes | Hourly rate set at loan creation or last modification, expressed as a percentage. | | createdAt | string | Yes | Date and time the loan offer was created (UTC). | | unlockRequestedAt | string | No | Date and time an unlock was requested, if applicable. | | unlockRequestedAmount | string | No | Amount requested to unlock, if applicable. | | updatedAt | string | Yes | Date and time of the loan offer's latest update (UTC). | **Example:** ```json [ { "loanId": "1289055810346737664", "currency": "USDC", "totalAmount": "100", "usedAmount": "0", "hourlyRate": "0.00001255", "createdAt": "2024-09-27T02:47:34.671Z", "updatedAt": "2024-09-27T02:47:34.671Z" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1MarketdataCurrencyPairOrderbook.md description: 'GET /v1/marketdata/{currencyPair}/orderbook' --- # Get order book `GET /v1/marketdata/{currencyPair}/orderbook` **Tags:** Market Data Returns a list of the top 40 bids and asks in the order book. Ask orders are sorted by price ascending. Bid orders are sorted by price descending. Orders of the same price are aggregated. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair symbol (e.g., BTCZAR, ETHZAR) | ## Responses ### 200 Order book retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | Asks | V1OrderForApi\[] | Yes | - | | Bids | V1OrderForApi\[] | Yes | - | | LastChange | string | Yes | - | | SequenceNumber | integer (int64) | Yes | - | **`Asks` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | orderCount | integer (int32) | Yes | - | **`Bids` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | orderCount | integer (int32) | Yes | - | **Example:** ```json { "Asks": [ { "side": "sell", "quantity": "0.998418", "price": "118000", "currencyPair": "BTCUSDC", "orderCount": 1 } ], "Bids": [ { "side": "buy", "quantity": "0.0001", "price": "117820", "currencyPair": "BTCUSDC", "orderCount": 1 } ], "LastChange": "2025-08-05T08:51:11.470Z", "SequenceNumber": 2907775 } ``` ### 400 Invalid currency pair **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicCurrencyPairOrderbook.md description: 'GET /v1/public/{currencyPair}/orderbook' --- # Get order book `GET /v1/public/{currencyPair}/orderbook` **Tags:** Public Returns a list of the top 40 bids and asks in the order book. Ask orders are sorted by price ascending. Bid orders are sorted by price descending. Orders of the same price are aggregated. Please note: This is not an authenticated call. More constrained rate-limiting rules will apply than when you use the /marketdata/:currencyPair/orderbook route. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Currency pair for which you want to query the order book | ## Responses ### 200 Order book retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | Asks | V1OrderForApi\[] | Yes | - | | Bids | V1OrderForApi\[] | Yes | - | | LastChange | string | Yes | - | | SequenceNumber | integer (int64) | Yes | - | **`Asks` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | orderCount | integer (int32) | Yes | - | **`Bids` properties:** | Property | Type | Required | Description | |---|---|---|---| | side | string (SELL, BUY) | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | orderCount | integer (int32) | Yes | - | **Example:** ```json { "Asks": [ { "side": "sell", "quantity": "0.01293134", "price": "93129", "currencyPair": "BTCUSDT", "orderCount": 1 } ], "Bids": [ { "side": "buy", "quantity": "1.23136671", "price": "81400", "currencyPair": "BTCUSDT", "orderCount": 17 } ], "LastChange": "2025-07-15T12:19:21.501Z", "SequenceNumber": 282886 } ``` --- --- url: /api-docs/getV1OrdersHistory.md description: GET /v1/orders/history --- # Get order history `GET /v1/orders/history` **Tags:** Orders Get historical orders placed by you. Results can be filtered using the following query parameters: * **skip** and **limit** for pagination (default limit is 100). * **startTime** / **endTime** to filter by `orderUpdatedAt` date. Values are interpreted as UTC and must be in ISO 8601 format (e.g., `2023-10-13T17:30:01.000Z`). These may be used together or separately. * **statuses** to filter by a comma-separated list of order statuses: `PLACED`, `FAILED`, `CANCELLED`, `FILLED`, `PARTIALLY_FILLED`, `ACTIVE`, `EXPIRED`, `PARTIALLY_FILLED_DUE_TO_SLIPPAGE`, `ORDER_MODIFIED`. * **currencyPair** to filter by the currency pair symbol (e.g., `BTCZAR`). * **excludeFailures** set to `TRUE` to exclude failed orders from the response. * **showZeroVolumeCancels** set to `TRUE` to include cancelled orders that did not match any volume. The `statusId` values map to the following labels: Placed, Failed, Cancelled, Filled, Partially Filled, Instant Order Completed, Instant Order Reversed, Liquidation Order Filled. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Skip this number of results. Default 0. | | limit | query | integer | No | Limit the results to this number. Default and Max 100. | | startTime | query | string | No | Include only records after this ISO 8601 start time (e.g., 2023-10-13T17:30:01.000Z) | | endTime | query | string | No | Include only records before this ISO 8601 end time (e.g., 2023-10-14T13:30:00.000Z) | | statuses | query | string | No | Comma-separated list of order statuses to filter by | | currencyPair | query | string | No | Filter returned orders by currency pair (e.g., BTCUSDC) | | excludeFailures | query | boolean | No | If TRUE, filter failed orders from the response. Default FALSE. | | showZeroVolumeCancels | query | boolean | No | If TRUE, show cancelled orders that did not match. Default FALSE. | ## Responses ### 200 Order history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | Unique identifier for the order assigned by VALR | | customerOrderId | string | No | - | | orderStatusType | string | Yes | Final status: Filled, Cancelled, Failed, Partially Filled | | currencyPair | string | Yes | The currency pair (e.g., BTCZAR, ETHUSDC) | | averagePrice | string | Yes | Volume-weighted average fill price | | originalPrice | string | Yes | The price specified when the order was placed | | remainingQuantity | string | Yes | - | | originalQuantity | string | Yes | - | | total | string | Yes | Total value of executed fills in quote currency | | totalExecutedQuantity | string | Yes | Total quantity that was filled | | totalFee | string | Yes | Total fees charged for the order | | feeCurrency | string | Yes | Currency in which fees were charged | | orderSide | string | Yes | Order side: buy or sell | | orderType | string | Yes | Order type: limit, market, post-only limit, simple | | failedReason | string | No | - | | orderUpdatedAt | string | Yes | - | | orderCreatedAt | string | Yes | - | | stopPrice | string | No | - | | timeInForce | string | Yes | - | **Example:** ```json [ { "orderId": "612ca8ef-15a3-4a85-b991-cc8d23c0e485", "orderStatusType": "Filled", "currencyPair": "BTCUSDC", "averagePrice": "66395", "originalPrice": "66395", "remainingQuantity": "0", "originalQuantity": "0.00045187", "total": "30.00190865", "totalExecutedQuantity": "0.00045187", "totalFee": "0", "feeCurrency": "BTC", "orderSide": "buy", "orderType": "limit", "failedReason": "", "orderUpdatedAt": "2024-04-24T23:14:34.891Z", "orderCreatedAt": "2024-04-24T23:13:00.280Z", "timeInForce": "GTC" } ] ``` ### 400 Bad request - Invalid query parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersHistoryDetailCustomerorderidCustomerOrderId.md description: 'GET /v1/orders/history/detail/customerorderid/{customerOrderId}' --- # Get order history detail by customer order ID `GET /v1/orders/history/detail/customerorderid/{customerOrderId}` **Tags:** Orders Get a detailed history of an order's statuses. This call returns an array of Order Status objects. The latest and most up-to-date status of this order is the zeroth element in the array. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | customerOrderId | path | string | Yes | The order ID provided by the customer when creating the order | ## Responses ### 200 Order history detail retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | orderStatusType | string | Yes | - | | currencyPair | string | Yes | - | | originalPrice | string | Yes | - | | remainingQuantity | string | Yes | - | | originalQuantity | string | Yes | - | | orderSide | string | Yes | - | | orderType | string | Yes | - | | failedReason | string | No | - | | orderUpdatedAt | string | Yes | - | | orderCreatedAt | string | Yes | - | | customerOrderId | string | No | - | | executedFee | string | No | - | | executedPrice | string | No | - | | executedQuantity | string | No | - | | stopPrice | string | No | - | | timeInForce | string | Yes | - | **Example:** ```json [ { "orderId": "01981766-9288-7624-a5fa-3942fdda6f70", "orderStatusType": "Failed", "currencyPair": "BTCUSDT", "originalPrice": "0", "remainingQuantity": "0.00000786", "originalQuantity": "0.00000786", "orderSide": "sell", "orderType": "market", "failedReason": "Order cancelled as it would have matched outside of slippage price band", "orderUpdatedAt": "2025-07-17T08:00:54.927Z", "orderCreatedAt": "2025-07-17T08:00:54.920Z", "customerOrderId": "1234", "executedFee": "0", "executedPrice": "0", "executedQuantity": "0", "timeInForce": "IOC" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersHistoryDetailOrderidOrderId.md description: 'GET /v1/orders/history/detail/orderid/{orderId}' --- # Get order history detail by order ID `GET /v1/orders/history/detail/orderid/{orderId}` **Tags:** Orders Get a detailed history of an order's statuses. This call returns an array of Order Status objects. The latest and most up-to-date status of this order is the zeroth element in the array. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | orderId | path | string | Yes | The order ID provided by VALR | ## Responses ### 200 Order history detail retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | - | | orderStatusType | string | Yes | - | | currencyPair | string | Yes | - | | originalPrice | string | Yes | - | | remainingQuantity | string | Yes | - | | originalQuantity | string | Yes | - | | orderSide | string | Yes | - | | orderType | string | Yes | - | | failedReason | string | No | - | | orderUpdatedAt | string | Yes | - | | orderCreatedAt | string | Yes | - | | customerOrderId | string | No | - | | executedFee | string | No | - | | executedPrice | string | No | - | | executedQuantity | string | No | - | | stopPrice | string | No | - | | timeInForce | string | Yes | - | **Example:** ```json [ { "orderId": "01981766-9288-7624-a5fa-3942fdda6f70", "orderStatusType": "Failed", "currencyPair": "BTCUSDT", "originalPrice": "0", "remainingQuantity": "0.00000786", "originalQuantity": "0.00000786", "orderSide": "sell", "orderType": "market", "failedReason": "Order cancelled as it would have matched outside of slippage price band", "orderUpdatedAt": "2025-07-17T08:00:54.927Z", "orderCreatedAt": "2025-07-17T08:00:54.920Z", "customerOrderId": "1234", "executedFee": "0", "executedPrice": "0", "executedQuantity": "0", "timeInForce": "IOC" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersHistorySummaryCustomerorderidCustomerOrderId.md description: 'GET /v1/orders/history/summary/customerorderid/{customerOrderId}' --- # Get order history summary by customer order ID `GET /v1/orders/history/summary/customerorderid/{customerOrderId}` **Tags:** Orders An order is considered completed when the Order Status call returns one of the following statuses: Filled, Cancelled or Failed. When this happens, you can get a more detailed summary about this order using this call. Orders that are not completed are invalid for this request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | customerOrderId | path | string | Yes | The order ID provided by the customer when creating the order | ## Responses ### 200 Order history summary retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | Unique identifier for the order assigned by VALR | | customerOrderId | string | No | - | | orderStatusType | string | Yes | Final status: Filled, Cancelled, Failed, Partially Filled | | currencyPair | string | Yes | The currency pair (e.g., BTCZAR, ETHUSDC) | | averagePrice | string | Yes | Volume-weighted average fill price | | originalPrice | string | Yes | The price specified when the order was placed | | remainingQuantity | string | Yes | - | | originalQuantity | string | Yes | - | | total | string | Yes | Total value of executed fills in quote currency | | totalExecutedQuantity | string | Yes | Total quantity that was filled | | totalFee | string | Yes | Total fees charged for the order | | feeCurrency | string | Yes | Currency in which fees were charged | | orderSide | string | Yes | Order side: buy or sell | | orderType | string | Yes | Order type: limit, market, post-only limit, simple | | failedReason | string | No | - | | orderUpdatedAt | string | Yes | - | | orderCreatedAt | string | Yes | - | | stopPrice | string | No | - | | timeInForce | string | Yes | - | **Example:** ```json { "orderId": "0198178f-a957-7684-b650-eb987183f8e5", "customerOrderId": "LimitSell", "orderStatusType": "Filled", "currencyPair": "ETHBTC", "averagePrice": "0.03", "originalPrice": "0.03", "remainingQuantity": "0", "originalQuantity": "0.033333", "total": "0.00099999", "totalExecutedQuantity": "0.033333", "totalFee": "0.000000799992", "feeCurrency": "BTC", "orderSide": "sell", "orderType": "post-only limit", "failedReason": "", "orderUpdatedAt": "2025-07-17T08:53:00.620Z", "orderCreatedAt": "2025-07-17T08:45:47.735Z", "timeInForce": "GTC" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersHistorySummaryOrderidOrderId.md description: 'GET /v1/orders/history/summary/orderid/{orderId}' --- # Get order history summary by order ID `GET /v1/orders/history/summary/orderid/{orderId}` **Tags:** Orders An order is considered completed when the Order Status call returns one of the following statuses: Filled, Cancelled or Failed. When this happens, you can get a more detailed summary about this order using this call. Orders that are not completed are invalid for this request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | orderId | path | string | Yes | The order ID provided by VALR | ## Responses ### 200 Order history summary retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | Unique identifier for the order assigned by VALR | | customerOrderId | string | No | - | | orderStatusType | string | Yes | Final status: Filled, Cancelled, Failed, Partially Filled | | currencyPair | string | Yes | The currency pair (e.g., BTCZAR, ETHUSDC) | | averagePrice | string | Yes | Volume-weighted average fill price | | originalPrice | string | Yes | The price specified when the order was placed | | remainingQuantity | string | Yes | - | | originalQuantity | string | Yes | - | | total | string | Yes | Total value of executed fills in quote currency | | totalExecutedQuantity | string | Yes | Total quantity that was filled | | totalFee | string | Yes | Total fees charged for the order | | feeCurrency | string | Yes | Currency in which fees were charged | | orderSide | string | Yes | Order side: buy or sell | | orderType | string | Yes | Order type: limit, market, post-only limit, simple | | failedReason | string | No | - | | orderUpdatedAt | string | Yes | - | | orderCreatedAt | string | Yes | - | | stopPrice | string | No | - | | timeInForce | string | Yes | - | **Example:** ```json { "orderId": "b47d36bf-adbc-4310-b904-b326a5be9079", "orderStatusType": "Filled", "currencyPair": "ETHZAR", "averagePrice": "8104", "originalPrice": "123", "remainingQuantity": "0", "originalQuantity": "0.01517769", "total": "122.99999976", "totalExecutedQuantity": "0.01517769", "totalFee": "0.000113832675", "feeCurrency": "ETH", "orderSide": "buy", "orderType": "simple", "failedReason": "", "orderUpdatedAt": "2021-02-01T15:57:57.994Z", "orderCreatedAt": "2021-02-01T15:57:57.992Z", "timeInForce": "GTC" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersCurrencyPairCustomerorderidCustomerOrderId.md description: 'GET /v1/orders/{currencyPair}/customerorderid/{customerOrderId}' --- # Get order status by customer order ID `GET /v1/orders/{currencyPair}/customerorderid/{customerOrderId}` **Tags:** Orders Returns the status of an order that was placed on the Exchange queried using customerOrderId. The customer can specify a customerOrderId while placing an order on the Exchange. Use this API to query the order status using that customerOrderId. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair (e.g., BTCUSDT) | | customerOrderId | path | string | Yes | The order ID provided by the customer when creating the order | ## Responses ### 200 Order status retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | Unique identifier for the order assigned by VALR | | orderStatusType | string | Yes | Current status: Placed, Filled, Partially Filled, Failed, Cancelled, Expired | | currencyPair | string | Yes | The currency pair for this order (e.g., BTCZAR, ETHUSDC) | | originalPrice | string | Yes | The price specified when the order was placed | | remainingQuantity | string | Yes | The quantity still to be filled | | originalQuantity | string | Yes | The total quantity specified when the order was placed | | orderSide | string | Yes | Order side: buy or sell | | orderType | string | Yes | Order type: limit, market, post-only limit, simple | | failedReason | string | No | Reason for failure, empty string if not failed | | orderUpdatedAt | string | Yes | Timestamp of the last status update (ISO 8601) | | orderCreatedAt | string | Yes | Timestamp when the order was created (ISO 8601) | | customerOrderId | string | No | Customer-specified order identifier, if provided | | stopPrice | string | No | - | | timeInForce | string | Yes | Time in force policy: GTC (Good Till Cancelled), FOK (Fill or Kill), IOC (Immediate or Cancel) | **Example:** ```json { "orderId": "0198178f-a957-7684-b650-eb987183f8e5", "orderStatusType": "Filled", "currencyPair": "ETHBTC", "originalPrice": "0.03", "remainingQuantity": "0", "originalQuantity": "0.033333", "orderSide": "sell", "orderType": "post-only limit", "failedReason": "", "orderUpdatedAt": "2025-07-17T08:53:00.620Z", "orderCreatedAt": "2025-07-17T08:45:47.735Z", "customerOrderId": "LimitSell", "timeInForce": "GTC" } ``` ### 400 Invalid customer order ID **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -1, "message": "customerOrderId is not valid: must match \"^[0-9a-zA-Z-]{0,50}$\"" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1OrdersCurrencyPairOrderidOrderId.md description: 'GET /v1/orders/{currencyPair}/orderid/{orderId}' --- # Get order status by order ID `GET /v1/orders/{currencyPair}/orderid/{orderId}` **Tags:** Orders Returns the status of an order that was placed on the Exchange queried using the id provided by VALR. VALR provides an id for every order that is placed on the Exchange. Use this id to populate the path variable orderId in this API to query the status of the order. If a customerOrderId was also specified while placing the order, that customerOrderId will be returned as part of the response. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair (e.g., BTCUSDT) | | orderId | path | string | Yes | The order ID provided by VALR | ## Responses ### 200 Order status retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string (uuid) | Yes | Unique identifier for the order assigned by VALR | | orderStatusType | string | Yes | Current status: Placed, Filled, Partially Filled, Failed, Cancelled, Expired | | currencyPair | string | Yes | The currency pair for this order (e.g., BTCZAR, ETHUSDC) | | originalPrice | string | Yes | The price specified when the order was placed | | remainingQuantity | string | Yes | The quantity still to be filled | | originalQuantity | string | Yes | The total quantity specified when the order was placed | | orderSide | string | Yes | Order side: buy or sell | | orderType | string | Yes | Order type: limit, market, post-only limit, simple | | failedReason | string | No | Reason for failure, empty string if not failed | | orderUpdatedAt | string | Yes | Timestamp of the last status update (ISO 8601) | | orderCreatedAt | string | Yes | Timestamp when the order was created (ISO 8601) | | customerOrderId | string | No | Customer-specified order identifier, if provided | | stopPrice | string | No | - | | timeInForce | string | Yes | Time in force policy: GTC (Good Till Cancelled), FOK (Fill or Kill), IOC (Immediate or Cancel) | **Example:** ```json { "orderId": "01981786-c482-7bae-a3da-4a756ef9d12e", "orderStatusType": "Placed", "currencyPair": "ETHBTC", "originalPrice": "0.0355", "remainingQuantity": "0.000565", "originalQuantity": "0.000565", "orderSide": "sell", "orderType": "post-only limit", "failedReason": "", "orderUpdatedAt": "2025-07-17T08:36:04.867Z", "orderCreatedAt": "2025-07-17T08:36:04.866Z", "customerOrderId": "LimitSell", "timeInForce": "GTC" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Order not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicOrdertypes.md description: GET /v1/public/ordertypes --- # Get order types `GET /v1/public/ordertypes` **Tags:** Public Get all the order types supported for all currency pairs. An array of currency pairs is returned along with an array of order types for each currency pair. You can only place an order that is supported by that currency pair. The order types supported are as follows: | Order Type | Description | |------------|-------------| | limit post-only | Place a limit order on the Exchange that will either be added to the order book or, should it match, be cancelled completely. | | limit | Place a limit order on the Exchange. | | market | Place a market order on the Exchange (only crypto-to-ZAR pairs). | | simple | Similar to a market order, but allows for crypto-to-crypto pairs. | | stop-loss limit | Place a limit order on the Exchange that limits the downside of holding a particular asset. | | take-profit limit | Place a limit order on the Exchange to lock in the growth of holding a particular asset. | ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | includeInactivePairs | query | boolean | No | Whether to include inactive currency pairs. Default: true | ## Responses ### 200 List of currency pairs with their supported order types **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | The currency pair symbol (e.g., BTCUSDC, ETHZAR) | | orderTypes | string\[] | Yes | Array of supported order type strings for this currency pair | **Example:** ```json [ { "currencyPair": "BTCUSDC", "orderTypes": [ "LIMIT_POST_ONLY", "LIMIT", "MARKET", "SIMPLE", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT" ] }, { "currencyPair": "ETHZAR", "orderTypes": [ "LIMIT_POST_ONLY", "LIMIT", "MARKET", "SIMPLE", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT" ] } ] ``` --- --- url: /api-docs/getV1PublicCurrencyPairOrdertypes.md description: 'GET /v1/public/{currencyPair}/ordertypes' --- # Get order types for a currency pair `GET /v1/public/{currencyPair}/ordertypes` **Tags:** Public Get the order types supported for a given currency pair. An array of order types is returned. You can only place an order that is listed in this array for this currency pair. The order types supported are as follows: | Order Type | Description | |------------|-------------| | limit post-only | Place a limit order on the Exchange that will either be added to the order book or, should it match, be cancelled completely. | | limit | Place a limit order on the Exchange. | | market | Place a market order on the Exchange. | | simple | Similar to a market order, but allows for crypto-to-crypto pairs. | | stop-loss limit | Place a limit order on the Exchange that limits the downside of holding a particular asset. | | take-profit limit | Place a limit order on the Exchange to lock in the growth of holding a particular asset. | ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you want to query the order types. Examples: BTCUSDC, BTCUSDT, XRPUSDC, SOLUSDC, ADABTC, ADAETH etc. | ## Responses ### 200 Array of supported order type strings for the specified currency pair **Content-Type:** `application/json` **Example:** ```json [ "LIMIT_POST_ONLY", "MARKET", "LIMIT", "SIMPLE", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT" ] ``` --- --- url: /api-docs/getV1PayPayid.md description: GET /v1/pay/payid --- # Get Pay ID `GET /v1/pay/payid` **Tags:** Pay Get your account's unique VALR PayID. Payments made with this reference will be credited to your account. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Pay ID retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | payId | string | Yes | - | **Example:** ```json { "payId": "8KDR68R4NA7HUD63CDCR" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PayIdentifierIdentifier.md description: 'GET /v1/pay/identifier/{identifier}' --- # Get Payment Details by Identifier `GET /v1/pay/identifier/{identifier}` **Tags:** Pay Get the payment details by specifying the payment identifier. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | identifier | path | string | Yes | The unique identifier of the payment | ## Responses ### 200 Payment details retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "identifier": "d2e16dc6-0c83-4f70-a30e-ef958a2b1d5d", "otherPartyIdentifier": "test@gmail.com", "amount": 15, "currency": "ZAR", "status": "COMPLETE", "timestamp": "2021-12-09T12:57:48.488803Z", "senderNote": "Tip", "recipientNote": "Thanks for a great service", "transactionId": "918486592856862720", "anonymous": false, "reversed": false, "type": "DEBIT" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Payment not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PayHistory.md description: GET /v1/pay/history --- # Get Payment History `GET /v1/pay/history` **Tags:** Pay Fetches a list of all payments made from and made to the current user's account. Payments received (incoming) have type = CREDIT and payments sent (outgoing) have type = DEBIT. The results of this request may be filtered by Status i.e. STATUS=COMPLETE,FAILED. Valid statuses are INITIATED, AUTHORISED, COMPLETE, RETURNED, FAILED, EXPIRED. The skip and limit parameters may be applied to paginate the filtered results. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | status | query | string | No | Comma-separated list of statuses to filter by (e.g., COMPLETE,FAILED) | | skip | query | integer | No | Number of records to skip for pagination | | limit | query | integer | No | Maximum number of records to return | ## Responses ### 200 Payment history retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "identifier": "dfd15233-3556-4c53-830a-f5d5253952b7", "otherPartyIdentifier": "John", "amount": 12, "currency": "ZAR", "status": "COMPLETE", "timestamp": "2021-12-09T19:05:45.519279Z", "transactionId": "918579191017975808", "anonymous": false, "reversed": false, "type": "DEBIT" }, { "identifier": "6627cfb5-ea15-4db8-bf2b-c7acb7320b9b", "otherPartyIdentifier": "Oz", "amount": 1800, "currency": "ZAR", "timestamp": "2021-12-09T18:34:23.800109Z", "transactionId": "918570461094293504", "anonymous": false, "reversed": false, "type": "CREDIT" }, { "identifier": "31bcd6e0-c35f-4257-b0ed-f66d6705ba0f", "otherPartyIdentifier": "Amanda", "amount": 128, "currency": "ZAR", "status": "COMPLETE", "timestamp": "2021-12-09T15:08:51.138276Z", "senderNote": "Paid in full", "recipientNote": "Great Service", "transactionId": "918519571587092480", "anonymous": false, "reversed": false, "type": "DEBIT" }, { "identifier": "f7c7f143-dda0-4c21-a5dd-56e1cb78a54d", "otherPartyIdentifier": "Doe", "amount": 5, "currency": "ZAR", "status": "RETURNED", "timestamp": "2021-12-09T15:01:13.867287Z", "recipientNote": "Gift", "transactionId": "918517653670285312", "anonymous": true, "reversed": true, "type": "DEBIT" }, { "identifier": "d2e16dc6-0c83-4f70-a30e-ef958a2b1d5d", "otherPartyIdentifier": "Jim", "amount": 15, "currency": "ZAR", "status": "COMPLETE", "timestamp": "2021-12-09T12:57:48.488803Z", "senderNote": "Tip", "recipientNote": "Thanks for a great service", "transactionId": "918486592856862720", "anonymous": false, "reversed": false, "type": "DEBIT" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PayLimits.md description: GET /v1/pay/limits --- # Get Payment Limits `GET /v1/pay/limits` **Tags:** Pay Retrieves all the payment limits applicable to your account. This will include minimum payment amount, maximum payment amount, payment currency and limit type (currently per transaction). ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | query | string | Yes | The currency shortname in which the limits should be denominated | ## Responses ### 200 Payment limits retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | maxPaymentAmount | number | Yes | - | | minPaymentAmount | number | Yes | - | | paymentCurrency | string | Yes | - | | limitType | string | Yes | - | **Example:** ```json { "maxPaymentAmount": 50000, "minPaymentAmount": 5, "paymentCurrency": "ZAR", "limitType": "per transaction" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PayTransactionidTransactionId.md description: 'GET /v1/pay/transactionid/{transactionId}' --- # Get Payment Status by Transaction ID `GET /v1/pay/transactionid/{transactionId}` **Tags:** Pay Get the status and details of a payment transaction, by specifying a transactionId. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | transactionId | path | string | Yes | The transaction ID of the payment | ## Responses ### 200 Payment status retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "amount": "15", "timestamp": "2021-12-09T12:57:48.488803Z", "transactionId": "918486592856862720", "status": "COMPLETE", "direction": "SEND" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Payment not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicCurrencyPairBuckets.md description: 'GET /v1/public/{currencyPair}/buckets' --- # Get price buckets for a currency pair `GET /v1/public/{currencyPair}/buckets` **Tags:** Public This API returns historical market data aggregated into time-based "buckets" or candles for a specified currency pair and bucket period. Each bucket provides the open, high, low, close, and volume for the defined time interval. **Note:** If no trading activity occurred during a specific bucket period, the `open`, `high`, `low`, and `close` prices will be identical (likely reflecting the last traded price), and `volume` and `quoteVolume` will be zero. A maximum of 300 buckets can be returned per call. This means you cannot specify a startTime and endTime that will contain more buckets than our supported max. Valid inputs for the `periodSeconds` parameter are `60 (default) - 1 Minute`, `300 - 5 Minutes`, `900 - 15 Minutes`, `1800 - 30 Minutes`, `3600 - 1 Hour`, `21600 - 6 Hours` and `86400 - 1 Day (max)`. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you want to query the price buckets. Examples: BTCUSDC, ETHUSDC, XRPUSDC, ADABTC, ADAETH etc. | | periodSeconds | query | integer | No | The bucket period in seconds. Valid values: 60 (default), 300, 900, 1800, 3600, 21600, 86400 | | startTime | query | string | No | Start time in epoch seconds (e.g., 1753102597). Default: endTime minus max allowed buckets | | endTime | query | string | No | End time in epoch seconds (e.g., 1753188997). Default: current time | | includeEmpty | query | boolean | No | Include empty buckets in the response | | limit | query | integer | No | Maximum number of buckets to return | | skip | query | integer | No | Number of buckets to skip | ## Responses ### 200 Price buckets retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPairSymbol | string | Yes | - | | bucketPeriodInSeconds | integer (int32) | Yes | - | | startTime | string | Yes | - | | open | string | Yes | - | | high | string | Yes | - | | low | string | Yes | - | | close | string | Yes | - | | volume | string | Yes | - | | quoteVolume | string | Yes | - | **Example:** ```json [ { "currencyPairSymbol": "BTCUSDC", "bucketPeriodInSeconds": 60, "startTime": "2025-07-22T12:56:00Z", "open": "119350", "high": "119350", "low": "119350", "close": "119350", "volume": "0", "quoteVolume": "0" }, { "currencyPairSymbol": "BTCUSDC", "bucketPeriodInSeconds": 60, "startTime": "2025-07-22T12:55:00Z", "open": "119350", "high": "119350", "low": "119350", "close": "119350", "volume": "0", "quoteVolume": "0" } ] ``` --- --- url: /api-docs/getV1PublicTime.md description: GET /v1/public/time --- # Get server time `GET /v1/public/time` **Tags:** Public Get the server time. Please note: The server time is returned in seconds. ## Responses ### 200 Server time with epochTime (Long, seconds since Unix epoch) and time (String, ISO 8601 format) **Content-Type:** `application/json` **Example:** ```json { "epochTime": 1750165361, "time": "2009-01-03T18:15:05.000Z" } ``` --- --- url: /api-docs/getV1WalletCryptoService-providers.md description: GET /v1/wallet/crypto/service-providers --- # Get service providers `GET /v1/wallet/crypto/service-providers` **Tags:** Crypto Wallet Returns the list of known service providers for use when performing a new crypto withdrawal. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Service providers retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "id": "672b1ff8a1ff8a027906ff39", "name": "Bybit" }, { "id": "676d1c189ef2fd542e5bbf33", "name": "Binance" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1SimpleOrderOrderId.md description: 'GET /v1/simple/order/{orderId}' --- # Get Simple Buy/Sell order status `GET /v1/simple/order/{orderId}` **Tags:** Simple Buy/Sell Get the status of a Simple Buy/Sell order. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | orderId | path | string | Yes | Order Id of the order for which you are querying the status | ## Responses ### 200 Order status retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | success | boolean | Yes | - | | processing | boolean | Yes | - | | failureReason | string | No | - | | paidAmount | string | No | - | | paidCurrency | string | No | - | | receivedAmount | string | No | - | | receivedCurrency | string | No | - | | feeAmount | string | No | - | | feeCurrency | string | No | - | | orderExecutedAt | string | Yes | - | | averagePrice | string | No | - | **Example:** ```json { "orderId": "9fed72b4-5d59-4bd7-b4fc-26cf43d27c94", "success": true, "processing": false, "paidAmount": "0.0008", "paidCurrency": "BTC", "receivedAmount": "54.49553877", "receivedCurrency": "ADA", "feeAmount": "0.000006", "feeCurrency": "BTC", "orderExecutedAt": "2019-04-20T13:57:56.618" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1SimpleCurrencyPairOrderOrderId.md description: 'GET /v1/simple/{currencyPair}/order/{orderId}' --- # Get Simple Buy/Sell order status (deprecated) `GET /v1/simple/{currencyPair}/order/{orderId}` **Tags:** Simple Buy/Sell Get the status of a Simple Buy/Sell order. This path is deprecated — use `GET /v1/simple/{orderId}/status` instead. The `currencyPair` path parameter is not required and is ignored. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Currency pair (ignored, kept for backwards compatibility) | | orderId | path | string | Yes | Order Id of the order for which you are querying the status | ## Responses ### 200 Order status retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | success | boolean | Yes | - | | processing | boolean | Yes | - | | failureReason | string | No | - | | paidAmount | string | No | - | | paidCurrency | string | No | - | | receivedAmount | string | No | - | | receivedCurrency | string | No | - | | feeAmount | string | No | - | | feeCurrency | string | No | - | | orderExecutedAt | string | Yes | - | | averagePrice | string | No | - | **Example:** ```json { "orderId": "9fed72b4-5d59-4bd7-b4fc-26cf43d27c94", "success": true, "processing": false, "paidAmount": "0.0008", "paidCurrency": "BTC", "receivedAmount": "54.49553877", "receivedCurrency": "ADA", "feeAmount": "0.000006", "feeCurrency": "BTC", "orderExecutedAt": "2019-04-20T13:57:56.618" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1SimpleCurrencyPairQuote.md description: 'POST /v1/simple/{currencyPair}/quote' --- # Get Simple Buy/Sell quote `POST /v1/simple/{currencyPair}/quote` **Tags:** Simple Buy/Sell Get a quote to buy or sell instantly using Simple Buy. Example usage of `payInCurrency` and `side` for the `BTCUSDC` currency pair: If you want to sell `BTC` for `USDC`, `payInCurrency` will be `BTC` and the side would be `SELL`. If you want to buy `BTC` with `USDC`, `payInCurrency` will be `USDC` and the side would be `BUY`. Example usage for the `ETHBTC` currency pair: If you want to sell `ETH` for `BTC`, `payInCurrency` will be `ETH` and the side would be `SELL`. If you want to buy `ETH` with `BTC`, `payInCurrency` will be `BTC` and the side would be `BUY`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair to get a simple quote for. Any currency pair that supports the "simple" order type can be specified. | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | payInCurrency | string | Yes | The currency you are paying with. | | payAmount | string | Yes | The amount you are paying. | | side | string | Yes | The side of the order: `BUY` or `SELL`. | ## Responses ### 200 Quote retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | payAmount | string | Yes | - | | receiveAmount | string | Yes | - | | fee | string | Yes | - | | feeCurrency | string | Yes | - | | createdAt | string | Yes | - | | id | string | Yes | - | | ordersToMatch | QuoteItemForDisplay\[] | Yes | - | | slippagePercentage | string | No | - | **`ordersToMatch` properties:** | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | | quantity | string | Yes | - | **Example:** ```json { "currencyPair": "BTCUSDC", "payAmount": "0.78546761", "receiveAmount": "90970.3614988", "fee": "1479.19286989", "feeCurrency": "USDC", "createdAt": "2025-08-08T08:23:39.782984109", "id": "019888c7-4e07-7bbc-9319-f925f931828f", "ordersToMatch": [ { "price": "117819", "quantity": "0.0000043" }, { "price": "117819", "quantity": "0.00001" }, { "price": "117818", "quantity": "0.00001" }, { "price": "117818", "quantity": "0.00001" }, { "price": "117817", "quantity": "0.00001" }, { "price": "117817", "quantity": "0.00001" }, { "price": "117816", "quantity": "0.00001" }, { "price": "117816", "quantity": "0.00001" }, { "price": "117815", "quantity": "0.00001" }, { "price": "117815", "quantity": "0.00001" }, { "price": "117814", "quantity": "0.00001" }, { "price": "117814", "quantity": "0.00001" }, { "price": "117814", "quantity": "0.00001" }, { "price": "117813", "quantity": "0.00001" }, { "price": "117810", "quantity": "0.00001" }, { "price": "117700", "quantity": "0.78532331" } ] } ``` ### 400 Bad request - Unable to fulfil or invalid parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -39, "message": "Please decrease your amount. The maximum is 0.78546762 BTC" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV2BrokerageHistoryOrderId.md description: 'GET /v2/brokerage/history/{orderId}' --- # Get single brokerage instruction `GET /v2/brokerage/history/{orderId}` **Tags:** Brokerage Get a single brokerage instruction record using the orderId of the simple order / simple swap. The response is returned as an array containing a single record. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | orderId | path | string | Yes | The unique id of the simple order or simple swap | ## Responses ### 200 Brokerage instruction retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | identifier | string | Yes | Unique identifier for the brokerage instruction. | | orderId | string | Yes | Order id for the simple swap or the simple order placed as part of the brokerage instruction. | | transferId | string | No | The id of the internal transfer used to sweep the brokerage fee into the fee account. | | accountId | integer (int64) | Yes | Account on which the simple order / simple swap took place. `0` indicates the main account was used. | | feeAccountId | integer (int64) | Yes | The account to which the brokerage fee was transferred. | | requestedPayAmount | string | Yes | The total value of the brokerage instruction as specified in the request's `payAmount`. | | actualPayAmount | string | No | The total amount the simple order or swap was placed for. | | payCurrency | string | Yes | The currency for the amount specified in `payAmount`. | | receiveCurrency | string | Yes | The currency received after the simple order / swap completed. | | receiveAmount | string | No | The amount received in `receiveCurrency` after the simple order / swap completed. | | feeRate | string | Yes | The rate of the brokerage fee levied. | | feeCurrency | string | Yes | The currency in which the brokerage fee was collected. | | feeAmount | string | No | The total amount of the brokerage fee collected. | | customerOrderId | string | No | The custom order id specified in the request. | | createdAt | integer (int64) | Yes | Timestamp when the brokerage instruction was created (UTC). | | status | string | Yes | The status of the brokerage instruction. | | leg1TradeFeeAmount | string | No | Trade fees levied by VALR for the simple order or the first of two trades in a simple swap. | | leg1TradeFeeCurrency | string | No | The currency in which `leg1TradeFeeAmount` was levied. | | leg2TradeFeeAmount | string | No | Trade fees levied by VALR for the second of two trades in a simple swap. Not included if a simple order was used. | | leg2TradeFeeCurrency | string | No | The currency in which `leg2TradeFeeAmount` was levied. Not included if a simple order was used. | **Example:** ```json [ { "identifier": "48657a89-5ff6-483c-a8d4-e8a1d0648fb4", "orderId": "de689cf3-f667-4104-905b-2fdb439618bc", "transferId": "377573", "accountId": 0, "feeAccountId": 1311349150067826700, "requestedPayAmount": "100", "actualPayAmount": "99.99857355", "payCurrency": "ZAR", "receiveCurrency": "XRP", "receiveAmount": "75.544", "feeRate": "0.01", "feeCurrency": "XRP", "feeAmount": "0.75544", "customerOrderId": "brokerage-order-01", "createdAt": 1739378546678, "status": "COMPLETED", "leg1TradeFeeAmount": "0.0314130", "leg1TradeFeeCurrency": "USDT", "leg2TradeFeeAmount": "0.456", "leg2TradeFeeCurrency": "XRP" } ] ``` ### 401 Unauthorised - requires API key with view permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Brokerage instruction not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicSlippage.md description: GET /v1/public/slippage --- # Get slippage configurations `GET /v1/public/slippage` **Tags:** Public Returns all slippage configurations for every currency pair available on the platform, including both Spot and Futures markets. ## Responses ### 200 Slippage configurations retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | currencyPairType | string | Yes | - | | limitSlippagePercent | string | Yes | - | | marketSlippagePercent | string | Yes | - | **Example:** ```json [ { "currencyPair": "XRPZAR", "currencyPairType": "SPOT", "limitSlippagePercent": "5", "marketSlippagePercent": "5" }, { "currencyPair": "BTCUSDT", "currencyPairType": "SPOT", "limitSlippagePercent": "5", "marketSlippagePercent": "5" } ] ``` --- --- url: /api-docs/getV1AccountSubaccountAccountPublicId.md description: 'GET /v1/account/subaccount/{accountPublicId}' --- # Get subaccount `GET /v1/account/subaccount/{accountPublicId}` **Tags:** Subaccounts Returns the subaccount and its KYC info, if available, for the provided `id` path variable. ## Subaccount Info | Field | Description | |-------|-------------| | id | The `id` of the subaccount. | | label | The name given to the subaccount. | ## KYC Info The sensitive subaccount KYC data is encrypted at rest. | Field | Description | |-------|-------------| | firstName | The first name of the subaccount holder. | | lastName | The last name of the subaccount holder. | | dateOfBirth | The date of birth of the subaccount holder. | | residentialCountry | The residential country of the subaccount holder, which refers to the country where the account holder currently resides. | | identityIssuingCountry | The identity issuing country of the subaccount holder, which refers to the country as verified by an official ID document (such as an ID card, driver's license, or passport). | | identityType | The identity type refers to the type of ID document used to verify the subaccount holder's identity. | | identityNumber | The identity number of the subaccount holder. | | identityExpiryDate | The date on which the ID of the subaccount holder expires. | | cellNumber | The cell phone number of the subaccount holder. | | email | The email address of the subaccount holder. | | purpose | The purpose of the subaccount. | | employmentStatus | The employment status of the subaccount holder. | | sourceOfFunds | The source of funds for the subaccount. | ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | accountPublicId | path | string | Yes | The id of the subaccount | ## Responses ### 200 Subaccount retrieved successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string | Yes | - | | label | string | Yes | - | | firstName | string | No | - | | lastName | string | No | - | | dateOfBirth | string | No | - | | residentialCountry | string | No | - | | identityIssuingCountry | string | No | - | | identityType | string | No | - | | identityNumber | string | No | - | | identityExpiryDate | string | No | - | | cellNumber | string | No | - | | email | string | No | - | | gender | string | No | - | | purpose | string | No | - | | employmentStatus | string | No | - | | sourceOfFunds | string | No | - | **Example:** ```json { "id": "903671169785507840", "label": "SubAccountWithKyc", "firstName": "John", "lastName": "Doe", "dateOfBirth": "1985-06-15", "residentialCountry": "ZA", "identityIssuingCountry": "ZA", "identityType": "PASSPORT", "identityNumber": "A123456789", "identityExpiryDate": "2030-12-31", "cellNumber": "+12345678901234", "email": "johndoe@example.com", "purpose": "TRADING", "employmentStatus": "EMPLOYED_FULL_TIME", "sourceOfFunds": "ALLOWANCE" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 404 Subaccount not found **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletFiatCurrencyAuto-buy.md description: 'GET /v1/wallet/fiat/{currency}/auto-buy' --- # Get supported auto-buy currencies `GET /v1/wallet/fiat/{currency}/auto-buy` **Tags:** Fiat Wallet Get a list of currencies supported for auto-buying with the `currencyCode` currency. Returns a flat array of currency short name strings. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the fiat currency (e.g., ZAR, USD) | ## Responses ### 200 Supported auto-buy currencies retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ "BTC", "ETH", "SOL" ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicLoansInfo.md description: GET /v1/public/loans/info --- # Get supported loan currencies `GET /v1/public/loans/info` **Tags:** Public Returns a list of currencies supported for lending, including minimum and maximum rates and amounts for each currency. ## Responses ### 200 Supported loan currencies retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | lendingSupported | boolean | Yes | - | | shortName | string | Yes | - | | minimumRate | string | No | - | | maximumRate | string | No | - | | minimumAmount | string | No | - | | maximumAmount | string | No | - | **Example:** ```json [ { "lendingSupported": true, "shortName": "ZAR", "minimumRate": "0.00000685", "maximumRate": "0.00036", "minimumAmount": "500", "maximumAmount": "100000000" }, { "lendingSupported": true, "shortName": "BTC", "minimumRate": "0.0000005", "maximumRate": "0.00036", "minimumAmount": "0.008", "maximumAmount": "1000" } ] ``` --- --- url: /api-docs/getV1AccountFeesTrade.md description: GET /v1/account/fees/trade --- # Get trade fees `GET /v1/account/fees/trade` **Tags:** Account Returns the list of all currency pairs and their respective fees per order type maker, taker and simple. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Trade fees retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | currencyPair | string | Yes | - | | makerPercentage | string | No | - | | takerPercentage | string | No | - | | simplePercentage | string | No | - | **Example:** ```json [ { "currencyPair": "ETHBTC", "makerPercentage": "0.08", "takerPercentage": "0.1", "simplePercentage": "1.6" }, { "currencyPair": "BTCUSDT", "makerPercentage": "0.08", "takerPercentage": "0.1", "simplePercentage": "1.6" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1AccountTradehistory.md description: GET /v1/account/tradehistory --- # Get trade history `GET /v1/account/tradehistory` **Tags:** Account Fetch the most recent trades on your account. The beforeId parameter may be used to paginate the trade history - only trades which occurred before the given ID will be included in the result. This allows backwards traversal of trade history by increments of limit. The startTime or endTime parameters may be used to filter the returned items by the traded date, interpreted as being in the UTC time zone and must be supplied in ISO 8601 format (2020-02-29T22:00:00.000Z). These two parameters may be used together or separately. When startTime is used, trades that have occurred since startTime are returned. When endTime is used, trades that have occurred up to and including endTime are returned. Note: The startTime and endTime parameters are optional filters. However, omitting these parameters may result in slower response times. To mitigate this, a default time window such as the most recent 30 days may be automatically applied to the request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Number of records to skip for pagination | | limit | query | integer | No | Maximum number of records to return | | startTime | query | string | No | Start time in ISO 8601 format (e.g., 2020-02-29T22:00:00.000Z). When used, trades that have occurred since startTime are returned. | | endTime | query | string | No | End time in ISO 8601 format (e.g., 2020-02-29T22:00:00.000Z). When used, trades that have occurred up to and including endTime are returned. | | beforeId | query | string | No | Return trades before this ID for cursor-based pagination. Allows backwards traversal of trade history by increments of limit. | ## Responses ### 200 Trade history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | Execution price per unit | | quantity | string | Yes | Traded quantity in base currency | | currencyPair | string | Yes | Currency pair symbol (e.g., BTCZAR) | | tradedAt | string | Yes | ISO 8601 timestamp when the trade executed | | side | string | Yes | Trade side: buy or sell | | sequenceId | integer (int64) | Yes | Monotonically increasing sequence identifier | | id | string | Yes | Unique trade identifier (UUID) | | orderId | string | Yes | The order identifier that resulted in this trade | | fee | string | No | Fee charged for this trade | | feeCurrency | string | No | Currency in which the fee was charged | | makerReward | string | No | - | | makerRewardCurrency | string | No | - | | customerOrderId | string | No | - | **Example:** ```json [ { "price": "49.89", "quantity": "0.2004", "currencyPair": "XRPZAR", "tradedAt": "2025-07-04T08:38:13.407Z", "side": "buy", "sequenceId": 1368928567986638000, "id": "0197d496-0e9f-7230-9aa1-4699655e7230", "orderId": "0197d496-0e4e-7453-ae5b-1d930e8f3a81", "fee": "0.0032064", "feeCurrency": "XRP" } ] ``` ### 400 Bad request - Invalid query parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1MarketdataCurrencyPairTradehistory.md description: 'GET /v1/marketdata/{currencyPair}/tradehistory' --- # Get trade history `GET /v1/marketdata/{currencyPair}/tradehistory` **Tags:** Market Data Get the trade history for a given currency pair. The results of this request may be filtered by datetime. The skip and limit parameters may be applied to paginate the filtered results. The startTime or endTime parameters may be used to filter the returned items by the trade date. The parameters will be interpreted as being in the UTC time zone and must be supplied in the ISO 8601 format (2020-02-29T22:00:00.000Z). These two parameters may be used together or separately. When startTime is used, trades that have occurred since startTime are returned. When endTime is used, trades that have occurred up to and including endTime are returned. Trade history may be paginated by supplying a trade ID in the beforeId parameter. Only trades which occurred before the given ID will be included in the result. This allows backwards traversal of trade history by increments of limit. NOTE: The startTime and endTime parameters are optional filters. However, omitting these parameters may result in slower response times. To mitigate this, a default time window such as the most recent 30 days may be automatically applied to the request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you want to query the trade history | | skip | query | integer | No | Skip this number of results. Default: 0 | | limit | query | integer | No | Limit the results to this number. Default and Max: 100 | | startTime | query | string | No | Include only trades after this ISO 8601 start time | | endTime | query | string | No | Include only trades before this ISO 8601 end time | | beforeId | query | string | No | Only include trades before this trade ID. Use for backwards pagination. | ## Responses ### 200 Trade history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | | quantity | string | Yes | - | | currencyPair | string | Yes | - | | tradedAt | string | Yes | - | | takerSide | string | Yes | - | | sequenceId | integer (int64) | Yes | - | | id | string | Yes | - | | quoteVolume | string | Yes | - | **Example:** ```json [ { "price": "118000", "quantity": "0.00058147", "currencyPair": "BTCUSDC", "tradedAt": "2025-08-04T12:38:10.282Z", "takerSide": "buy", "sequenceId": 1368928567986639400, "id": "01987516-e06a-756c-825d-82ada5ded56c", "quoteVolume": "68.61346" }, { "price": "118000", "quantity": "0.00000847", "currencyPair": "BTCUSDC", "tradedAt": "2025-07-31T12:04:27.246Z", "takerSide": "buy", "sequenceId": 1368928567986639400, "id": "0198605e-91ee-7219-9f45-bdced9b23219", "quoteVolume": "0.99946" } ] ``` ### 400 Invalid currency pair or query parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicCurrencyPairTrades.md description: 'GET /v1/public/{currencyPair}/trades' --- # Get trade history `GET /v1/public/{currencyPair}/trades` **Tags:** Public Get the trade history for a given currency pair. Please note: This is not an authenticated call. More constrained rate-limiting rules will apply than when you use /marketdata/:currencyPair/tradehistory route. The results of this request may be filtered by datetime. The skip and limit parameters may be applied to paginate the filtered results. The startTime or endTime parameters may be used to filter the returned items by the trade date. The parameters will be interpreted as being in the UTC time zone and must be supplied in the ISO 8601 format (2020-02-29T22:00:00.000Z). These two parameters may be used together or separately. When startTime is used, trades that have occurred since startTime are returned. When endTime is used, trades that have occurred up to and including endTime are returned. Trade history may be paginated by supplying a trade ID in the beforeId parameter. Only trades which occurred before the given ID will be included in the result. This allows backwards traversal of trade history by increments of limit. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | Specify the currency pair for which you want to query the trade history | | skip | query | integer | No | Skip this number of results. Default: 0 | | limit | query | integer | No | Limit the results to this number. Default and Max: 100 | | startTime | query | string | No | Include only trades after this ISO 8601 start time (e.g. 2020-02-29T22:00:00.000Z) | | endTime | query | string | No | Include only trades before this ISO 8601 end time (e.g. 2020-02-29T22:00:00.000Z) | | beforeId | query | string | No | Only include trades before this trade ID. Use for backwards pagination. | ## Responses ### 200 Trade history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | | quantity | string | Yes | - | | currencyPair | string | Yes | - | | tradedAt | string | Yes | - | | takerSide | string | Yes | - | | sequenceId | integer (int64) | Yes | - | | id | string | Yes | - | | quoteVolume | string | Yes | - | **Example:** ```json [ { "price": "93129", "quantity": "0.00119363", "currencyPair": "BTCUSDT", "tradedAt": "2025-07-15T12:19:21.501Z", "takerSide": "buy", "sequenceId": 1368928567986638800, "id": "01980e06-771d-73f1-aec8-b2fe69d943f1", "quoteVolume": "111.16156827" }, { "price": "93129", "quantity": "0.0004428", "currencyPair": "BTCUSDT", "tradedAt": "2025-07-14T05:22:52.344Z", "takerSide": "buy", "sequenceId": 1368928567986638800, "id": "01980762-cd38-719d-b7ea-d75c1872719d", "quoteVolume": "41.2375212" } ] ``` --- --- url: /api-docs/getV1AccountCurrencyPairTradehistory.md description: 'GET /v1/account/{currencyPair}/tradehistory' --- # Get trade history for a currency pair `GET /v1/account/{currencyPair}/tradehistory` **Tags:** Account Get the last 100 recent trades for a given currency pair for your account. You can limit the number of trades returned by specifying the limit parameter, and the skip parameter to exclude a specified number of the latest trades from the results. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair symbol (e.g., BTCUSDC, ETHUSDT) | | skip | query | integer | No | Skip this number of results. (Default 0) | | limit | query | integer | No | Limit the results to this number. (Default and Max 100) | ## Responses ### 200 Trade history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | Execution price per unit | | quantity | string | Yes | Traded quantity in base currency | | currencyPair | string | Yes | Currency pair symbol (e.g., BTCZAR) | | tradedAt | string | Yes | ISO 8601 timestamp when the trade executed | | side | string | Yes | Trade side: buy or sell | | sequenceId | integer (int64) | Yes | Monotonically increasing sequence identifier | | id | string | Yes | Unique trade identifier (UUID) | | orderId | string | Yes | The order identifier that resulted in this trade | | fee | string | No | Fee charged for this trade | | feeCurrency | string | No | Currency in which the fee was charged | | makerReward | string | No | - | | makerRewardCurrency | string | No | - | | customerOrderId | string | No | - | **Example:** ```json [ { "price": "93129", "quantity": "0.0001", "currencyPair": "BTCUSDT", "tradedAt": "2025-06-13T09:21:48.393Z", "side": "buy", "sequenceId": 1368928567986636000, "id": "01976898-6969-7c30-b002-bb021d376c30", "orderId": "01976898-6967-7d63-88c1-8223d40cc39e", "fee": "0.0000001", "feeCurrency": "BTC" } ] ``` ### 400 Bad request - Invalid query parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1AccountTransactionhistorySubaccounts.md description: GET /v1/account/transactionhistory/subaccounts --- # Get transaction history for all subaccounts `GET /v1/account/transactionhistory/subaccounts` **Tags:** Subaccounts Transaction history for all your sub accounts. The results of this request may be filtered by transaction types, currency and start and end time. The `skip` and `limit` parameters may be applied to paginate the filtered results. Please note that all transactions that are returned using the provided filter criteria will be ordered by the date the transactions were created in **descending** order. ## Filtering by `skip` or `limit` Paginate the query results by skipping the `skip` newest results, and limiting the results to `limit` records. The default value of `skip`, if omitted, is `0`, and the default value of `limit` is `100`. The maximum allowed value of limit is `200`. ## Filtering by `startTime` or `endTime` The `startTime` or `endTime` parameters may be used to filter the returned items by the transaction date. The parameters will be interpreted as being in the UTC time zone and must be supplied in the ISO 8601 format (`2020-02-29T22:00:00.000Z`). These two parameters may be used together or separately. **Possible Scenarios:** * When `startTime` and `endTime` are not provided the `startTime` will be defaulted to 1 day before current time and `endTime` will be defaulted to current time. * When `startTime` is specified and `endTime` is not specified, `endTime` will be defaulted to 7 days after `startTime`, to a maximum of current time. * When `startTime` is not specified and `endTime` is specified, `startTime` will be defaulted to 7 days prior to `endTime`. * `startTime` and `endTime` may not differ by more than 7 days. **Note:** The `startTime` and `endTime` parameters are optional filters. However, omitting these parameters may result in slower response times. To mitigate this, a default time window such as the most recent 30 days may be automatically applied to the request. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Skip this number of results. (Default 0) | | limit | query | integer | No | Limit the results to this number. (Default and Max 100) | | transactionTypes | query | string | No | Comma-separated list of transaction types to include | | currency | query | string | No | Include only transactions in this currency (e.g., USDC, BTC) | | startTime | query | string | No | Include only transactions after this ISO 8601 start time. When not provided with endTime, defaults to 1 day before current time. | | endTime | query | string | No | Include only transactions before this ISO 8601 end time. startTime and endTime may not differ by more than 7 days. | ## Responses ### 200 Subaccount transaction history retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | id | string | Yes | - | | label | string | Yes | - | | transactions | V1APIUserTransactionRecord\[] | Yes | - | **`transactions` properties:** | Property | Type | Required | Description | |---|---|---|---| | transactionType | object | Yes | - | | debitCurrency | string | No | - | | debitValue | string | No | - | | creditCurrency | string | No | - | | creditValue | string | No | - | | feeCurrency | string | No | - | | feeValue | string | No | - | | eventAt | string | Yes | - | | additionalInfo | object | No | - | | id | string (uuid) | Yes | - | **`transactionType` properties:** | Property | Type | Required | Description | |---|---|---|---| | type | string | Yes | - | | description | string | Yes | - | **`additionalInfo` properties:** | Property | Type | Required | Description | |---|---|---|---| **Example:** ```json [ { "id": "1306231494450782208", "label": "Margin Trading", "transactions": [ { "transactionType": { "type": "SPOT_BORROW_INTEREST_CHARGE", "description": "Spot Borrow Interest Charge" }, "debitCurrency": "AVAX", "debitValue": "0.00000184", "eventAt": "2025-07-03T08:00:00.461Z", "additionalInfo": { "borrowAmount": "3.0520996", "hourlyRate": "6.00E-7" }, "id": "0197cf4c-b5cd-7f4a-8c32-7f183d3f2f4a" }, { "transactionType": { "type": "INTERNAL_TRANSFER", "description": "Transfer" }, "debitCurrency": "USDC", "debitValue": "83241.870104015439", "eventAt": "2025-07-03T07:19:01.245Z", "additionalInfo": { "reason": "SUB_ACCOUNT", "reasonDescription": "Transfer between subaccounts", "additional": "Transfer from API key test to Primary", "transferId": "443661" }, "id": "0197cf27-2f7d-7ac8-9d29-578d356d7ac8" } ] } ] ``` ### 400 Bad request - Invalid query parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1PublicStatus.md description: GET /v1/public/status --- # Get VALR status `GET /v1/public/status` **Tags:** Public Get the current status of VALR. May be "online" when all functionality is available, or "read-only" when only GET and OPTIONS requests are accepted. All other requests in read-only mode will respond with a 503 error code. ## Responses ### 200 Current VALR status **Content-Type:** `application/json` **Example:** ```json { "status": "online" } ``` --- --- url: /api-docs/getV1WalletCryptoAddress-book.md description: GET /v1/wallet/crypto/address-book --- # Get whitelisted withdrawal address book `GET /v1/wallet/crypto/address-book` **Tags:** Crypto Wallet Returns all the withdrawal addresses whitelisted for this account. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Address book entries retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "id": "2a22433a-1548-11eb-adc1-0242ac120002", "label": "My Secure Address", "currency": "BTC", "address": "2N5jUhwzndtTUXspDGJkAvP7WCCRLQkgMfX", "networkType": "Bitcoin", "createdAt": "2020-11-30T10:18:54.994930Z", "beneficiaryName": "Satoshi Nakamoto", "isCorporate": false, "isSelfHosted": false, "serviceProviderName": "Binance" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletCryptoAddress-bookCurrency.md description: 'GET /v1/wallet/crypto/address-book/{currency}' --- # Get whitelisted withdrawal address book for a currency `GET /v1/wallet/crypto/address-book/{currency}` **Tags:** Crypto Wallet Returns all the withdrawal addresses whitelisted for this account and the currency specified in the path variable `:currencyCode`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | Specify the currency for which you want to query the address book (e.g., BTC, ETH) | ## Responses ### 200 Address book entries retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "id": "a5ea4e3b-2002-4f17-8580-00e61aeae8f8", "label": "My Secure Address", "currency": "BTC", "address": "2N5jUhwzndtTUXspDGJkAvP7WCCRLQkgMfX", "networkType": "Bitcoin", "createdAt": "2020-11-30T10:18:54.994930Z", "beneficiaryName": "Satoshi Nakamoto", "isCorporate": false, "isSelfHosted": true } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletCryptoCurrencyWithdraw.md description: 'GET /v1/wallet/crypto/{currency}/withdraw' --- # Get withdrawal config info `GET /v1/wallet/crypto/{currency}/withdraw` **Tags:** Crypto Wallet Get all the information about withdrawing a given currency from your VALR account. That will include withdrawal costs, minimum withdrawal amount etc. If `networkType` is not specified, it will be defaulted based on the configuration for the currency that can be found at `/v1/public/currencies`. Please also consult the supporting documentation for the `/v1/public/currencies` api which illustrates different scenarios by example. The `withdrawalDecimalPlaces` specified is the maximum scale of the value that will be submitted to the network and will be rounded down to that scale if a value with a larger scale is provided. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code of the currency you want withdrawal information about (e.g., BTC, ETH, XRP, ADA) | | networkType | query | string | No | The network type to use when retrieving the currency config for the specified currency. If not specified, it will be defaulted based on the currency configuration. | ## Responses ### 200 Withdrawal configuration info retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "currency": "BTC", "minimumWithdrawAmount": "0.0002", "withdrawalDecimalPlaces": "8", "isActive": true, "withdrawCost": "0.00013", "supportsPaymentReference": false, "networkType": "Bitcoin" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletCryptoWithdrawHistory.md description: GET /v1/wallet/crypto/withdraw/history --- # Get withdrawal history `GET /v1/wallet/crypto/withdraw/history` **Tags:** Crypto Wallet Get Withdrawal History records for a given currency. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | skip | query | integer | No | Skip this number of results. (Default 0) | | limit | query | integer | No | Limit the results to this number. (Default and Max 100) | | currency | query | string | No | Currency Code (e.g., BTC, ETH, XRP, ADA). Leave empty to retrieve records for all currencies. | | startTime | query | string | No | ISO 8601 string (e.g., 2025-01-01T00:00:00Z) for the start of the time range. Defaults to the earliest available date if not provided. | | endTime | query | string | No | ISO 8601 string (e.g., 2025-01-31T23:59:59Z) for the end of the time range. Defaults to the latest date if not provided. | ## Responses ### 200 Withdrawal history retrieved successfully **Content-Type:** `application/json` **Example:** ```json [ { "currency": "USDC", "address": "0x388C818CA8B9251b393131C08a736A67ccB11297", "amount": "10", "feeAmount": "20", "transactionHash": "0xbf21b35945b41aeab5a081a878b0ed6c317639018718a56b0446a6747b3407a5", "confirmations": 6, "lastConfirmationAt": "2025-01-07T14:22:32.419194", "uniqueId": "e1221de5-c494-4b75-bd0d-63e106879c08", "createdAt": "2025-01-07T14:19:17.861765Z", "verified": true, "status": "Complete", "networkType": "Ethereum" }, { "currency": "ETH", "address": "0x388C818CA8B1251b393131C08a736A67ccB19297", "amount": "0.001", "feeAmount": "0.0018", "transactionHash": "0xae971c7f1bc35f53203c14f289e80ba4c30c4f1591e3be19fbc6bffbcd5d46aa", "confirmations": 6, "lastConfirmationAt": "2025-01-07T14:12:55.543998", "uniqueId": "ff9614bb-78f4-44ca-9694-7d8cfd341633", "createdAt": "2025-01-07T14:11:06.482998Z", "verified": true, "status": "Complete", "networkType": "Ethereum" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1WalletCryptoCurrencyWithdrawId.md description: 'GET /v1/wallet/crypto/{currency}/withdraw/{id}' --- # Get withdrawal status `GET /v1/wallet/crypto/{currency}/withdraw/{id}` **Tags:** Crypto Wallet Check the status of a withdrawal. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currency | path | string | Yes | The currency code for the currency you have withdrawn (e.g., BTC, ETH, XRP, ADA) | | id | path | string | Yes | The unique id that represents your withdrawal request. This is provided as a response to the API call to withdraw. | ## Responses ### 200 Withdrawal status retrieved successfully **Content-Type:** `application/json` **Example:** ```json { "currency": "BTC", "address": "mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt", "amount": "0.001", "feeAmount": "0.0002", "transactionHash": "1558363779645", "confirmations": 2, "lastConfirmationAt": "2019-05-20T14:49:59.659675", "uniqueId": "b8e2e6c0-5215-4f6b-80b4-a664b2b6ef94", "createdAt": "2019-05-20T14:49:39.609Z", "verified": true, "status": "Processing", "networkType": "Bitcoin" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /guides/getting-started.md description: >- Getting started with the VALR API — overview, prerequisites, and request conventions --- # VALR API VALR provides a set of REST endpoints and a complementary WebSocket service which enables you to programmatically access your account on VALR. Usage of the API is governed by our [Terms of Service](https://www.valr.com/terms-of-use). With the API you can: * Access real-time and historical market data * Place and manage trade orders * Buy and sell 60+ cryptocurrencies * Withdraw crypto and fiat currencies ## Getting Started ### Base URL All API requests are made to: ``` https://api.valr.com ``` ### Enable Two-Factor Authentication Two-Factor Authentication (2FA) must be enabled on your VALR account before you can generate API keys. You can enable 2FA from your account security settings. ### Content Type All REST API requests must use `application/json` as the content type. Requests are only accepted over HTTPS. Sending a `POST`, `PUT`, or `PATCH` request without the `Content-Type: application/json` header will result in a `401 Unauthorized` response. ### Response Format Successful responses return HTTP status codes in the `200–299` range unless there is a server or infrastructure error. Results are wrapped in a JSON result object. A `202 Accepted` response means the request has been accepted for processing but is not yet complete. You should check the order status via the Order Status REST API or subscribe to WebSocket events for real-time updates. ### Authentication All non-public endpoints require API key authentication. Requests without a valid API key will receive a `403 Forbidden` response. Public endpoints under `/v1/public/*` do not require authentication — these include market data such as order books, trade history, and currency information. See the [Authentication](/guides/authentication) guide for full details on generating API keys and signing requests. --- --- url: /api-docs/putV1LoansIncrease.md description: PUT /v1/loans/increase --- # Increase Loan Amount `PUT /v1/loans/increase` **Tags:** Lending Amends a specific loan offer by increasing the amount. The `increaseLoanAmountBy` field specifies the additional amount to be offered — it does not represent the total amount to which a user wishes to increase the loan. The decimal places in `increaseLoanAmountBy` are limited to the `withdrawalDecimalPlaces` of the offered currency, up to a maximum of four. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | Symbol of the currency to be loaned. | | loanId | string | Yes | Unique identifier of the loan to increase. | | increaseLoanAmountBy | string | Yes | Additional amount to add to the loan offer. This is not the total target amount. | ## Responses ### 202 Loan amount increased successfully ### 400 Bad request - Invalid adjustment **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendInstantOrderCompleted.md description: WebSocket SEND — /ws/account --- # Instant order completed `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a simple buy/sell (instant) order has been completed. Includes the amounts paid and received, fees, and whether the order was successful. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `INSTANT_ORDER_COMPLETED` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | success | boolean | Yes | - | | paidAmount | string | No | - | | paidCurrency | string | No | - | | receivedAmount | string | No | - | | receivedCurrency | string | No | - | | feeAmount | string | No | - | | feeCurrency | string | No | - | | orderStatusType | string | No | - | | failedReason | string | No | - | ### Example ```json "{\n \"type\": \"INSTANT_ORDER_COMPLETED\",\n \"data\": {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"success\": true,\n \"paidAmount\": \"10000.00\",\n \"paidCurrency\": \"ZAR\",\n \"receivedAmount\": \"0.01050000\",\n \"receivedCurrency\": \"BTC\",\n \"feeAmount\": \"100.00\",\n \"feeCurrency\": \"ZAR\",\n \"orderStatusType\": \"Filled\",\n \"failedReason\": null\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV1AccountSubaccountsTransfer.md description: POST /v1/account/subaccounts/transfer --- # Internal transfer between subaccounts `POST /v1/account/subaccounts/transfer` **Tags:** Subaccounts Transfer funds between 2 accounts. The primary API key can transfer from and to any subaccount. The subaccount API key can only transfer from itself. The transfer process is asynchronous, to verify completion listen for balance changes or TX updates on the Account WebSocket. Use the allowBorrow option to borrow funds against assets in your account. Collateral is locked while the loan is outstanding. Interest accrues hourly and is capitalised into the loan. Crypto Loans are only available in margin-enabled Subaccounts. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | fromId | integer (int64) | Yes | The `id` of the source account. Use `0` for the primary account. | | toId | integer (int64) | Yes | The `id` of the destination account. Use `0` for the primary account. | | currencyCode | string | Yes | The currency code of the currency being transferred. | | amount | string | Yes | The total amount being transferred. | | allowBorrow | boolean | Yes | Set to `true` to borrow funds against assets in your account. Default `false`. Only available in margin-enabled subaccounts. | ## Responses ### 202 Transfer accepted ### 400 Bad request - Invalid transfer parameters or margin not enabled **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -19213, "message": "Margin not enabled for account" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendObL1Diff.md description: WebSocket SEND — /ws/trade --- # L1 aggregated order book diff (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book incremental update. Sent after the initial OB\_L1\_SNAPSHOT with changes. Uses the same compressed wire format. A quantity of "0" at a price level means that level should be removed. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_DIFF" } ] } ``` ## Message **Event type:** `OB_L1_DIFF` ### Example ```json "{\n \"type\": \"OB_L1_DIFF\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301610000,\n \"a\": [\n [\"45363\", \"0\"]\n ],\n \"b\": [\n [\"45148\", \"0.025\"]\n ],\n \"sq\": 6,\n \"cs\": 2345678901\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 aggregated order book snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot. Sent once on subscription, followed by OB\_L1\_DIFF messages for incremental updates. Uses a compressed wire format with shortened keys for efficiency. **Compressed key mapping:** * `ps` = currencyPairSymbol * `d` = data * `lc` = LastChange * `a` = Asks (array of \[price, quantity] arrays) * `b` = Bids (array of \[price, quantity] arrays) * `sq` = SequenceNumber * `cs` = Checksum ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"],\n [\"45364\", \"0.00200000\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"],\n [\"45100\", \"0.5\"]\n ],\n \"sq\": 5,\n \"cs\": 1234567890\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1D1Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 order book depth-1 snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot truncated to a depth of 1 per side. Unlike OB\_L1\_SNAPSHOT, no diff messages are sent — a full snapshot is sent on every update. Uses the same compressed wire format as OB\_L1\_SNAPSHOT but without SequenceNumber or Checksum fields. Available depth variants: OB\_L1\_D1\_SNAPSHOT, OB\_L1\_D10\_SNAPSHOT, OB\_L1\_D20\_SNAPSHOT, OB\_L1\_D40\_SNAPSHOT, OB\_L1\_D60\_SNAPSHOT, OB\_L1\_D80\_SNAPSHOT. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_D1_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_D1_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_D1_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"]\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1D10Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 order book depth-10 snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot truncated to a depth of 10 per side. Unlike OB\_L1\_SNAPSHOT, no diff messages are sent — a full snapshot is sent on every update. Uses the same compressed wire format as OB\_L1\_SNAPSHOT but without SequenceNumber or Checksum fields. Available depth variants: OB\_L1\_D1\_SNAPSHOT, OB\_L1\_D10\_SNAPSHOT, OB\_L1\_D20\_SNAPSHOT, OB\_L1\_D40\_SNAPSHOT, OB\_L1\_D60\_SNAPSHOT, OB\_L1\_D80\_SNAPSHOT. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_D10_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_D10_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_D10_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"]\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1D20Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 order book depth-20 snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot truncated to a depth of 20 per side. Unlike OB\_L1\_SNAPSHOT, no diff messages are sent — a full snapshot is sent on every update. Uses the same compressed wire format as OB\_L1\_SNAPSHOT but without SequenceNumber or Checksum fields. Available depth variants: OB\_L1\_D1\_SNAPSHOT, OB\_L1\_D10\_SNAPSHOT, OB\_L1\_D20\_SNAPSHOT, OB\_L1\_D40\_SNAPSHOT, OB\_L1\_D60\_SNAPSHOT, OB\_L1\_D80\_SNAPSHOT. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_D20_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_D20_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_D20_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"]\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1D40Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 order book depth-40 snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot truncated to a depth of 40 per side. Unlike OB\_L1\_SNAPSHOT, no diff messages are sent — a full snapshot is sent on every update. Uses the same compressed wire format as OB\_L1\_SNAPSHOT but without SequenceNumber or Checksum fields. Available depth variants: OB\_L1\_D1\_SNAPSHOT, OB\_L1\_D10\_SNAPSHOT, OB\_L1\_D20\_SNAPSHOT, OB\_L1\_D40\_SNAPSHOT, OB\_L1\_D60\_SNAPSHOT, OB\_L1\_D80\_SNAPSHOT. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_D40_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_D40_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_D40_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"]\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1D60Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 order book depth-60 snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot truncated to a depth of 60 per side. Unlike OB\_L1\_SNAPSHOT, no diff messages are sent — a full snapshot is sent on every update. Uses the same compressed wire format as OB\_L1\_SNAPSHOT but without SequenceNumber or Checksum fields. Available depth variants: OB\_L1\_D1\_SNAPSHOT, OB\_L1\_D10\_SNAPSHOT, OB\_L1\_D20\_SNAPSHOT, OB\_L1\_D40\_SNAPSHOT, OB\_L1\_D60\_SNAPSHOT, OB\_L1\_D80\_SNAPSHOT. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_D60_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_D60_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_D60_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"]\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendObL1D80Snapshot.md description: WebSocket SEND — /ws/trade --- # L1 order book depth-80 snapshot (Alpha) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` (Alpha) Level 1 aggregated order book snapshot truncated to a depth of 80 per side. Unlike OB\_L1\_SNAPSHOT, no diff messages are sent — a full snapshot is sent on every update. Uses the same compressed wire format as OB\_L1\_SNAPSHOT but without SequenceNumber or Checksum fields. Available depth variants: OB\_L1\_D1\_SNAPSHOT, OB\_L1\_D10\_SNAPSHOT, OB\_L1\_D20\_SNAPSHOT, OB\_L1\_D40\_SNAPSHOT, OB\_L1\_D60\_SNAPSHOT, OB\_L1\_D80\_SNAPSHOT. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "OB_L1_D80_SNAPSHOT" } ] } ``` ## Message **Event type:** `OB_L1_D80_SNAPSHOT` ### Example ```json "{\n \"type\": \"OB_L1_D80_SNAPSHOT\",\n \"ps\": \"BTCUSDC\",\n \"d\": {\n \"lc\": 1644301604645,\n \"a\": [\n [\"45363\", \"0.01102078\"]\n ],\n \"b\": [\n [\"45147\", \"0.011\"]\n ]\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendLeverageUpdated.md description: WebSocket SEND — /ws/account --- # Leverage settings updated `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when the leverage settings for a futures pair have been updated. Includes the new leverage multiple, margin fractions, and risk limit. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `LEVERAGE_UPDATED` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | pairSymbol | string | Yes | - | | leverageMultiple | integer (int32) | Yes | - | | initialMarginFraction | number (double) | Yes | - | | maintenanceMarginFraction | number (double) | Yes | - | | autoCloseMarginFraction | number (double) | Yes | - | | riskLimit | integer (int64) | Yes | - | | riskLimitCurrency | string | Yes | - | ### Example ```json "{\n \"type\": \"LEVERAGE_UPDATED\",\n \"data\": {\n \"pairSymbol\": \"BTCUSDTPERP\",\n \"leverageMultiple\": 25,\n \"initialMarginFraction\": 0.04,\n \"maintenanceMarginFraction\": 0.0125,\n \"autoCloseMarginFraction\": 0.0083,\n \"riskLimit\": 250000,\n \"riskLimitCurrency\": \"USDT\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV1StakingStake.md description: POST /v1/staking/stake --- # Lock Amount `POST /v1/staking/stake` **Tags:** Staking / DeFi Lending Lock the specified currency to start earning yield. Subsequent calls to this endpoint for the same currency will increase the total locked amount by the provided value. Use `earnType` in the request body to specify staking (`STAKE`) or DeFi lending (`LEND`). ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | The symbol of the currency to unlock. | | amount | string | Yes | The amount that will be unlocked. | | earnType | string | Yes | The earn type: `STAKE` for staking or `LEND` for DeFi lending. | ## Responses ### 200 Amount locked successfully ### 400 Bad request - Invalid lock request **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -1, "message": "Unsupported Currency" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendMarkPriceUpdate.md description: WebSocket SEND — /ws/trade --- # Mark price updated `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent approximately every 5 seconds with the current mark price for futures (perpetual) pairs. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "MARK_PRICE_UPDATE" } ] } ``` ## Message **Event type:** `MARK_PRICE_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | ### Example ```json "{\n \"type\": \"MARK_PRICE_UPDATE\",\n \"currencyPairSymbol\": \"BTCUSDTPERP\",\n \"data\": {\n \"price\": \"33000\"\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendMarketSummaryUpdate.md description: WebSocket SEND — /ws/trade --- # Market summary updated `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when the market summary for a currency pair is updated. Includes the current ask/bid prices, last traded price, 24-hour volume, high/low prices, and percentage change from the previous close. Subscribe with specific currency pairs to filter updates. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "MARKET_SUMMARY_UPDATE" } ] } ``` ## Message **Event type:** `MARKET_SUMMARY_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | currencyPairSymbol | string | Yes | - | | askPrice | string | Yes | - | | bidPrice | string | Yes | - | | lastTradedPrice | string | Yes | - | | previousClosePrice | string | Yes | - | | baseVolume | string | Yes | - | | highPrice | string | Yes | - | | lowPrice | string | Yes | - | | created | string | Yes | - | | changeFromPrevious | string | Yes | - | | markPrice | string | No | - | ### Example ```json "{\n \"type\": \"MARKET_SUMMARY_UPDATE\",\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"data\": {\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"askPrice\": \"297357\",\n \"bidPrice\": \"297205\",\n \"lastTradedPrice\": \"297161\",\n \"previousClosePrice\": \"296596\",\n \"baseVolume\": \"244.33584689486\",\n \"highPrice\": \"300180\",\n \"lowPrice\": \"281930\",\n \"created\": \"2022-11-14T08:30:26.037Z\",\n \"changeFromPrevious\": \"0.19\",\n \"markPrice\": \"297205\"\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/receiveModifyOrder.md description: WebSocket RECEIVE — /ws/account --- # Modify an order via WebSocket `RECEIVE` **Client to Server** on `wss://api.valr.com/ws/account` Modify the price and/or quantity of an existing open order through the WebSocket connection. The server responds with a `MODIFY_ORDER_WS_RESPONSE` message. If the request is invalid, an `INVALID_MODIFY_WS_REQUEST` message is returned. **Request format:** ```json { "type": "MODIFY_ORDER", "clientMsgId": "unique-correlation-id", "payload": { ... } } ``` ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `MODIFY_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | pair | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | customerOrderId | string | No | - | ### Example ```json "{\n \"type\": \"MODIFY_ORDER\",\n \"clientMsgId\": \"d4e5f6a1-correlation-id\",\n \"payload\": {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"pair\": \"BTCZAR\",\n \"quantity\": \"0.02\",\n \"price\": \"960000\",\n \"customerOrderId\": \"my-modified-order-1\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/putV1OrdersConditionalsModify.md description: PUT /v1/orders/conditionals/modify --- # Modify conditional order `PUT /v1/orders/conditionals/modify` **Tags:** Conditional Orders Modify conditional orders. The following values of a conditional order can be modified: Price, Quantity, Take Profit Trigger Price, Take Profit Order Price, Stop Loss Trigger Price, Stop Loss Order Price. Adding a missing Stop Loss (SL) or Take Profit (TP) trigger turns the conditional order into a one-cancel-other (OCO) conditional order. If the trigger already exists, the price will be modified. Modified conditional orders retain their original orderId. | Parameter | Description | | --- | --- | | orderId (optional) | Placed order Id provided by VALR. Required if customerOrderId isn't used. | | customerOrderId (optional) | Alphanumeric value. Required if orderId isn't used. | | pair (required) | Currency pair for the orderId. | | newQuantity (optional) | The value in base amount | | newTakeProfitTriggerPrice (optional) | New take profit trigger price | | newTakeProfitOrderPrice (optional) | New take profit order price | | newStopLossTriggerPrice (optional) | New stop loss trigger price | | newStopLossOrderPrice (optional) | New stop loss order price | The `orderId` and `pair` fields are required to identify the conditional order. All other fields are optional — only the fields you want to modify need to be included in the request body. When the response is `202 Accepted`, this means that the modify request has been submitted. Use the Order Status REST API or WebSocket API to receive the final status. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | pair | string | Yes | - | | customerOrderId | string | No | - | | orderId | string | No | - | | newQuantity | string | No | - | | newTakeProfitTriggerPrice | string | No | - | | newTakeProfitOrderPrice | string | No | - | | newStopLossTriggerPrice | string | No | - | | newStopLossOrderPrice | string | No | - | ## Responses ### 202 Modify conditional order request accepted **Content-Type:** `application/json` **Example:** ```json { "id": "e281eb8e-c315-4372-a7b6-8c5e5f5eb971", "customerOrderId": "ConditionalByLastTraded" } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/putV1OrdersModify.md description: PUT /v1/orders/modify --- # Modify order `PUT /v1/orders/modify` **Tags:** Orders Modify Open and Partially Filled Limit Orders. The following values of an open or partially filled limit order can be modified: Price, Total Quantity, Remaining Quantity. | Parameter | Description | | --- | --- | | orderId (required) | Placed order Id provided by VALR | | pair (required) | Currency pair for the orderId. | | modifyMatchStrategy (required) | `RETAIN_ORIGINAL` which keeps the original order or `CANCEL_ORIGINAL` to cancel the original order or `REPRICE` which adjusts the order price to avoid immediate match | | newRemainingQuantity (optional) | New base quantity to be executed | | newTotalQuantity (optional) | New total base quantity for the order | | newPrice (optional) | Requested new price in base currency | | customerOrderId (optional) | Placed order ID provided by customer | Either newRemainingQuantity or newTotalQuantity can be specified in the same request, but not both. Modified orders retain their original orderId. When the response is `202 Accepted`, this means that the Modify Order request has been submitted. ## Important Notes * Only the original order account's API key can modify the order. * A `202 Accepted` response means the modify order request has been submitted; use the Order Status REST API or WebSocket API to receive the final status. * Modified orders retain their original `orderId`. * The modify order request will fail if the new values are the same as the current values. * When using `REPRICE`, the system adjusts the order price to avoid an immediate match whilst keeping the order active. * **`modifyMatchStrategy`**: Controls what happens when the modified order would immediately match: * `RETAIN_ORIGINAL`: Keeps the original order unchanged if the modification would cause an immediate match. * `CANCEL_ORIGINAL`: Cancels the original order if the modification would cause an immediate match. * `REPRICE`: Adjusts the order price to avoid immediate match whilst keeping the order active. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | newRemainingQuantity | string | No | - | | newTotalQuantity | string | No | - | | newPrice | string | No | - | | pair | string | Yes | - | | customerOrderId | string | No | - | | orderId | string | No | - | | modifyMatchStrategy | string | No | - | ## Responses ### 202 Modify order request accepted **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "019817f6-da14-70f5-acc9-d7b4e71eadb2" } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/putV2OrdersModify.md description: PUT /v2/orders/modify --- # Modify order `PUT /v2/orders/modify` **Tags:** Orders Modify Open and Partially Filled Limit Orders. The following values of an open or partially filled limit order can be modified: * Price * Total Quantity * Remaining Quantity **Queue position behaviour:** * Reducing the Total quantity or Remaining quantity will maintain the modified order's position in the order queue. * Increasing the Total quantity or Remaining quantity will move the modified order to the back of the order queue. * Modifying the price up or down will move the modified order to the back of the order queue. Modified orders retain their original `orderId` and the audit trail can be viewed in the Detailed Order History API call. When the response is `201 Created`, this means that the Modify Order request has been submitted and processed successfully. | Parameter | Description | |-----------|-------------| | orderId (required) | Placed order Id provided by VALR | | pair (required) | Currency pair for the `orderId` | | modifyMatchStrategy (required) | `RETAIN_ORIGINAL` keeps the original order, `CANCEL_ORIGINAL` cancels it, or `REPRICE` adjusts the order price to avoid immediate match | | newRemainingQuantity (optional) | New base quantity to be executed, irrespective of any existing quantity on the order book at the time of processing the request | | newTotalQuantity (optional) | New total base quantity for the order. If `newTotalQuantity` is less than the filled quantity, the order is cancelled. Otherwise, `newTotalQuantity` minus filled quantity becomes the new remaining quantity. | | newPrice (optional) | Requested new price in quote currency | | customerOrderId (optional) | Placed order ID provided by customer. Alphanumeric with no special characters, limit of 50 characters. | Either `newRemainingQuantity` or `newTotalQuantity` can be specified in the same request, but not both. ## Important Notes * Only the original order account's API key can modify the order. * A `201 Created` response means the modify order request has been submitted and processed; use the Order Status REST API or WebSocket API to receive the final status. * The modify order request will fail if the new values are the same as the current values. * **`modifyMatchStrategy`**: Controls what happens when the modified order would immediately match: * `RETAIN_ORIGINAL`: Keeps the original order unchanged if the modification would cause an immediate match. * `CANCEL_ORIGINAL`: Cancels the original order if the modification would cause an immediate match. * `REPRICE`: Adjusts the order price to avoid immediate match whilst keeping the order active. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | newRemainingQuantity | string | No | - | | newTotalQuantity | string | No | - | | newPrice | string | No | - | | pair | string | Yes | - | | customerOrderId | string | No | - | | orderId | string | Yes | - | | modifyMatchStrategy | string | No | - | ## Responses ### 201 Order modified successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "4b6458b6-92b4-11ee-894e-894ac6bb1906" } ``` ### 400 Invalid request parameters or modification failed **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "modifyOrderId": "d1e05e7e-7cd3-11ee-8c68-417193a135ba", "orderId": "d1d1130d-6c26-49a4-8637-3a6ba2463ae5", "code": -21303, "message": "Modify order would not have modified anything and was cancelled" } ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/putV1AccountSubaccount.md description: PUT /v1/account/subaccount --- # Modify subaccount `PUT /v1/account/subaccount` **Tags:** Subaccounts Updates an existing subaccount. Can only be called by a primary account API key with `Trade` permissions. ## Query Parameter `isProprietarySubAccount` A boolean value indicating whether to update a proprietary subaccount (label only) or a customer subaccount (including KYC data). Existing proprietary sub-accounts (label only) can be converted to customer sub-accounts (including KYC data) by making an update request with `isProprietarySubAccount` set to `false` and providing the necessary KYC information. Note that `label`, `identityNumber` and `cellNumber` should be unique per subaccount. **Note:** Registering subaccounts with KYC information is not available to all clients and will not work unless VALR has specifically enabled this for your account. Please contact help@valr.com if you have already been enabled to utilise these endpoints but are having technical difficulty using them. Please contact business@valr.com if you believe these endpoints are required for your use case. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | isProprietarySubAccount | query | boolean | No | A boolean value indicating whether to update a proprietary subaccount (label only) or a customer subaccount (including KYC data). | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | integer (int64) | Yes | - | | label | string | Yes | - | | firstName | string | Yes | - | | lastName | string | Yes | - | | dateOfBirth | string | Yes | - | | residentialCountry | string | Yes | - | | identityIssuingCountry | string | Yes | - | | identityType | string | Yes | - | | identityNumber | string | Yes | - | | identityExpiryDate | string | No | - | | cellNumber | string | Yes | - | | email | string | No | - | | purpose | string | Yes | - | | employmentStatus | string | Yes | - | | sourceOfFunds | string | Yes | - | ## Responses ### 202 Subaccount update accepted ### 400 Bad request - Invalid parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Forbidden - Duplicate label **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -11132, "message": "A subaccount with that label already exists" } ``` --- --- url: /api-docs/postV1Pay.md description: POST /v1/pay --- # New Payment `POST /v1/pay` **Tags:** Pay Initiate an instant payment using VALR Pay by specifying the recipient email, recipient cellphone number or their account payment reference (VALR PayID). To initiate a payment, your balance in the payment currency should be equal to, or greater than the minimum Payment limit. Successful requests return 202 - Accepted with an identifier and transactionId in the body. | Parameter | Description | | --- | --- | | currency (required) | The currency for the payment (e.g., ZAR) | | amount (required) | The amount to send | | recipientEmail (conditional) | Recipient's email address. One of recipientEmail, recipientCellNumber, or recipientPayId is required. | | recipientCellNumber (conditional) | Recipient's cellphone number. One of recipientEmail, recipientCellNumber, or recipientPayId is required. | | recipientPayId (conditional) | Recipient's VALR PayID. One of recipientEmail, recipientCellNumber, or recipientPayId is required. | | recipientNote (optional) | A note visible to the recipient | | senderNote (optional) | A note visible to the sender | | anonymous (optional) | If true, sender identity is hidden. Default false. | ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | amount | string | Yes | Value of the currency to be paid. | | currency | string | Yes | The currency in which payment is made. | | recipientEmail | string | No | Recipient's email address. Exactly one of recipientEmail, recipientCellNumber, or recipientPayId is required. | | recipientCellNumber | string | No | Recipient's cellphone number. Exactly one of recipientEmail, recipientCellNumber, or recipientPayId is required. | | recipientPayId | string | No | Recipient's VALR PayID. Exactly one of recipientEmail, recipientCellNumber, or recipientPayId is required. | | recipientNote | string | No | A note visible to the recipient. | | senderNote | string | No | A note visible to the sender. | | anonymous | boolean | Yes | If true, sender identity is hidden. Default false. | ## Responses ### 202 Payment accepted **Content-Type:** `application/json` **Example:** ```json { "identifier": "d2e16dc6-0c83-4f70-a30e-ef958a2b1d5d", "transactionId": "918486592856862720" } ``` ### 400 Bad request - Invalid payment details **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -15417, "message": "Payment has too many recipient identifiers" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendNewPendingReceive.md description: WebSocket SEND — /ws/account --- # New pending cryptocurrency deposit `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when an incoming cryptocurrency deposit is detected on the blockchain but has not yet been confirmed. Includes the transaction hash, amount, and confirmation count. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `NEW_PENDING_RECEIVE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | - | | receiveAddress | string | Yes | - | | transactionHash | string | Yes | - | | amount | string | Yes | - | | createdAt | string | Yes | - | | confirmations | integer (int32) | Yes | - | | confirmed | boolean | Yes | - | | confirmedAt | string | No | - | ### Example ```json "{\n \"type\": \"NEW_PENDING_RECEIVE\",\n \"data\": {\n \"currency\": \"BTC\",\n \"receiveAddress\": \"bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh\",\n \"transactionHash\": \"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2\",\n \"amount\": \"0.50000000\",\n \"createdAt\": \"2024-09-27T12:00:00.000Z\",\n \"confirmations\": 1,\n \"confirmed\": false,\n \"confirmedAt\": null\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendNewPendingSend.md description: WebSocket SEND — /ws/account --- # New pending cryptocurrency withdrawal `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when an outgoing cryptocurrency withdrawal has been submitted to the blockchain. Includes the destination address, amount, fees, and transaction hash when available. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `NEW_PENDING_SEND` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | currency | string | Yes | - | | sendAddress | string | Yes | - | | amount | string | Yes | - | | feeAmount | string | Yes | - | | transactionHash | string | No | - | | confirmations | integer (int32) | Yes | - | | lastConfirmationAt | string | No | - | | uniqueId | string | Yes | - | | createdAt | string | Yes | - | ### Example ```json "{\n \"type\": \"NEW_PENDING_SEND\",\n \"data\": {\n \"currency\": \"BTC\",\n \"sendAddress\": \"bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh\",\n \"amount\": \"0.10000000\",\n \"feeAmount\": \"0.00005000\",\n \"transactionHash\": \"d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5\",\n \"confirmations\": 0,\n \"lastConfirmationAt\": null,\n \"uniqueId\": \"c3d4e5f6-a1b2-1234-5678-90abcdef1234\",\n \"createdAt\": \"2024-09-27T12:05:00.000Z\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendNewTradeBucket.md description: WebSocket SEND — /ws/trade --- # New trade bucket (OHLC candle) `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when a new 60-second OHLC trade bucket (candle) is available. Contains open, high, low, close prices and volume for the period. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "NEW_TRADE_BUCKET" } ] } ``` ## Message **Event type:** `NEW_TRADE_BUCKET` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | currencyPairSymbol | string | Yes | - | | bucketPeriodInSeconds | integer (int32) | Yes | - | | startTime | string | Yes | - | | open | string | Yes | - | | high | string | Yes | - | | low | string | Yes | - | | close | string | Yes | - | | volume | string | Yes | - | ### Example ```json "{\n \"type\": \"NEW_TRADE_BUCKET\",\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"data\": {\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"bucketPeriodInSeconds\": 60,\n \"startTime\": \"2019-04-25T19:41:00Z\",\n \"open\": \"9500\",\n \"high\": \"9500\",\n \"low\": \"9500\",\n \"close\": \"9500\",\n \"volume\": \"0\"\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendNewTrade.md description: WebSocket SEND — /ws/trade --- # New trade occurred `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when a new trade occurs on the exchange. Includes the trade price, quantity, currency pair, timestamp, and taker side (buy or sell). Subscribe with specific currency pairs to filter updates. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "NEW_TRADE" } ] } ``` ## Message **Event type:** `NEW_TRADE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | | quantity | string | Yes | - | | currencyPair | string | Yes | - | | tradedAt | string | Yes | - | | takerSide | string | Yes | - | | id | string | Yes | - | ### Example ```json "{\n \"type\": \"NEW_TRADE\",\n \"currencyPairSymbol\": \"BTCUSDT\",\n \"data\": {\n \"price\": \"9500\",\n \"quantity\": \"0.001\",\n \"currencyPair\": \"BTCUSDT\",\n \"tradedAt\": \"2019-04-25T19:51:55.393Z\",\n \"takerSide\": \"buy\"\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /ws-docs/sendNewAccountTrade.md description: WebSocket SEND — /ws/account --- # New trade on your account `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a trade occurs on your account via the order book. This is not sent for instant (simple buy/sell) orders. Includes trade price, quantity, currency pair, and side. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `NEW_ACCOUNT_TRADE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | | quantity | string | Yes | - | | currencyPair | string | Yes | - | | tradedAt | string | Yes | - | | side | string | Yes | - | ### Example ```json "{\n \"type\": \"NEW_ACCOUNT_TRADE\",\n \"data\": {\n \"price\": \"950000\",\n \"quantity\": \"0.01000000\",\n \"currencyPair\": \"BTCZAR\",\n \"tradedAt\": \"2024-09-27T12:01:00.000Z\",\n \"side\": \"BUY\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendNewAccountHistoryRecord.md description: WebSocket SEND — /ws/account --- # New transaction history record `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a new transaction history record is created on your account. This includes any event that affects your balances such as trades, deposits, withdrawals, fees, and rewards. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `NEW_ACCOUNT_HISTORY_RECORD` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | transactionType | object | Yes | - | | debitCurrency | string | Yes | - | | debitValue | string | Yes | - | | creditCurrency | string | Yes | - | | creditValue | string | Yes | - | | feeCurrency | string | Yes | - | | feeValue | string | Yes | - | | eventAt | string | Yes | - | ### Example ```json "{\n \"type\": \"NEW_ACCOUNT_HISTORY_RECORD\",\n \"data\": {\n \"transactionType\": {\n \"type\": \"LIMIT_BUY\",\n \"description\": \"Limit Buy\"\n },\n \"debitCurrency\": \"ZAR\",\n \"debitValue\": \"9500.00\",\n \"creditCurrency\": \"BTC\",\n \"creditValue\": \"0.01000000\",\n \"feeCurrency\": \"BTC\",\n \"feeValue\": \"0.00001000\",\n \"eventAt\": \"2024-09-27T12:01:00.000Z\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendOpenPositionUpdate.md description: WebSocket SEND — /ws/account --- # Open futures position updated `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when a futures position on your account has been updated. Includes position details such as side, quantity, PnL, average entry price, and leverage tier. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `OPEN_POSITION_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | pair | string | Yes | - | | side | string | Yes | - | | quantity | string | Yes | - | | realisedPnl | string | Yes | - | | totalSessionEntryQuantity | string | Yes | - | | totalSessionValue | string | Yes | - | | sessionAverageEntryPrice | string | Yes | - | | averageEntryPrice | string | Yes | - | | unrealisedPnl | string | Yes | - | | updatedAt | string | Yes | - | | createdAt | string | Yes | - | | positionId | string | Yes | - | | leverageTier | integer (int32) | Yes | - | ### Example ```json "{\n \"type\": \"OPEN_POSITION_UPDATE\",\n \"data\": {\n \"pair\": \"BTCUSDTPERP\",\n \"side\": \"buy\",\n \"quantity\": \"0.0003\",\n \"realisedPnl\": \"0.08067945\",\n \"totalSessionEntryQuantity\": \"0.0003\",\n \"totalSessionValue\": \"10.9272\",\n \"sessionAverageEntryPrice\": \"36424\",\n \"averageEntryPrice\": \"36137\",\n \"unrealisedPnl\": \"-0.0567\",\n \"updatedAt\": \"2023-11-16T18:57:38.013Z\",\n \"createdAt\": \"2023-11-15T11:34:38.186Z\",\n \"positionId\": \"08dea401-ba23-ded0-28a9-03d6d59c32a4\",\n \"leverageTier\": 27\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendOpenOrdersUpdate.md description: WebSocket SEND — /ws/account --- # Open orders updated `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when your open orders change. Contains the full list of currently open orders on your account. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `OPEN_ORDERS_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | accountId | string | Yes | - | | orders | WsOpenOrderEntry\[] | Yes | - | #### orders (WsOpenOrderEntry) | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | side | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | currencyPair | string | Yes | - | | createdAt | string | Yes | - | | originalQuantity | string | Yes | - | | filledPercentage | string | Yes | - | | customerOrderId | string | No | - | | stopPrice | string | No | - | | updatedAt | string | Yes | - | | status | string | Yes | - | | type | string | Yes | - | | timeInForce | string | Yes | - | ### Example ```json "{\n \"type\": \"OPEN_ORDERS_UPDATE\",\n \"data\": {\n \"accountId\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n \"orders\": [\n {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"side\": \"BUY\",\n \"quantity\": \"0.01000000\",\n \"price\": \"950000\",\n \"currencyPair\": \"BTCZAR\",\n \"createdAt\": \"2024-09-27T12:00:00.000Z\",\n \"originalQuantity\": \"0.01000000\",\n \"filledPercentage\": \"0.00\",\n \"customerOrderId\": \"my-order-1\",\n \"stopPrice\": null,\n \"updatedAt\": \"2024-09-27T12:00:00.000Z\",\n \"status\": \"Placed\",\n \"type\": \"limit\",\n \"timeInForce\": \"GTC\"\n }\n ]\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendFailedCancelOrder.md description: WebSocket SEND — /ws/account --- # Order cancellation failed `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when an attempt to cancel an order on the exchange has failed. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `FAILED_CANCEL_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | message | string | Yes | - | ### Example ```json "{\n \"type\": \"FAILED_CANCEL_ORDER\",\n \"data\": {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"message\": \"Order not found or already filled\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendModifyOrderOutcome.md description: WebSocket SEND — /ws/account --- # Order modification result `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when an order modification request has been processed. Indicates whether the modification was successful and includes the modification request ID for correlation with the original MODIFY\_ORDER command. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `MODIFY_ORDER_OUTCOME` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | success | boolean | Yes | - | | orderId | string | Yes | - | | customerOrderId | string | No | - | | modifyRequestId | string | Yes | - | ### Example ```json "{\n \"type\": \"MODIFY_ORDER_OUTCOME\",\n \"data\": {\n \"success\": true,\n \"orderId\": \"019a29d0-4362-7dc9-a51d-3533a4bdcf2d\",\n \"customerOrderId\": \"testWS\",\n \"modifyRequestId\": \"019a2a0f-1216-737b-9065-8138dae1e874\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendFailedOrder.md description: WebSocket SEND — /ws/account --- # Order placement failed `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when an order has failed to be placed on the exchange. Includes an error message describing why the order failed. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `FAILED_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | No | - | | message | string | Yes | - | ### Example ```json "{\n \"type\": \"FAILED_ORDER\",\n \"data\": {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"message\": \"Insufficient balance\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendOrderProcessed.md description: WebSocket SEND — /ws/account --- # Order processing result `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent after an order has been processed by the exchange. Indicates whether the order was placed successfully or failed, along with the failure reason if applicable. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `ORDER_PROCESSED` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | success | boolean | Yes | - | | failureReason | string | No | - | ### Example ```json "{\n \"type\": \"ORDER_PROCESSED\",\n \"data\": {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"success\": true,\n \"failureReason\": null\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/sendOrderStatusUpdate.md description: WebSocket SEND — /ws/account --- # Order status changed `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when an open order on the exchange has had a status change event. Includes the order ID, current status, remaining quantity, and other order details. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "ORDER_STATUS_UPDATE" } ] } ``` ## Message **Event type:** `ORDER_STATUS_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | orderId | string | Yes | - | | orderStatusType | string | Yes | - | | currencyPair | string | Yes | - | | originalPrice | string | Yes | - | | remainingQuantity | string | Yes | - | | originalQuantity | string | Yes | - | | orderSide | string | Yes | - | | orderType | string | Yes | - | | failedReason | string | No | - | | orderUpdatedAt | string | Yes | - | | orderCreatedAt | string | Yes | - | | customerOrderId | string | No | - | ### Example ```json "{\n \"type\": \"ORDER_STATUS_UPDATE\",\n \"data\": {\n \"orderId\": \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n \"orderStatusType\": \"Filled\",\n \"currencyPair\": \"BTCZAR\",\n \"originalPrice\": \"950000\",\n \"remainingQuantity\": \"0\",\n \"originalQuantity\": \"0.01000000\",\n \"orderSide\": \"BUY\",\n \"orderType\": \"limit\",\n \"failedReason\": null,\n \"orderUpdatedAt\": \"2024-09-27T12:01:00.000Z\",\n \"orderCreatedAt\": \"2024-09-27T12:00:00.000Z\",\n \"customerOrderId\": \"my-order-1\"\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/putV1PayTransactionidTransactionIdPartial-reverse.md description: 'PUT /v1/pay/transactionid/{transactionId}/partial-reverse' --- # Partially Reverse Payment `PUT /v1/pay/transactionid/{transactionId}/partial-reverse` **Tags:** Pay Partially reverse an instant payment using VALR Pay by specifying the payment transaction id. An anonymous payment will be made back to the original sender's VALR Pay ID with the exact amount and identical currency. Only a recipient of a payment can perform the partial reversal. Successful requests return 202 - Accepted with an `identifier` and `transactionId` in the body. The `amountToReverse` must be greater than zero and can have up to 8 decimal places. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | transactionId | path | string | Yes | The transaction id of the payment that is to be partially reversed | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | amountToReverse | string | Yes | The specific amount to be reversed. Must be greater than zero and can have up to 8 decimal places. | ## Responses ### 202 Partial reversal accepted ### 400 Bad request - Invalid transaction ID or amount **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /guides/performance.md description: >- Optimising API performance with WebSockets, order book feeds, and real-time execution --- # Performance Considerations ## WebSocket Efficiency WebSocket connections maintain a persistent TCP socket, making them inherently faster than repeated HTTP requests. With WebSockets, the benefits of batching are less pronounced since the connection is already established and the overhead per message is minimal. ## Optimal Order Book Updates For rapid order book changes, use the `OB_L1_DIFF` WebSocket feed. This feed sends only the differences (deltas) rather than the full order book snapshot, resulting in significantly smaller data packets and lower latency. ## Real-Time Order Execution WebSocket is the fastest method for receiving order execution status updates. While HTTP endpoints serve order status from memory, the WebSocket feed delivers updates as they happen, making it the superior choice for time-sensitive trading applications. ## Estimated Latency A rough estimate for WebSocket order placement to outcome is approximately **8ms** round trip. This is an approximate figure and actual latency will vary based on network conditions, server load, and order complexity. --- --- url: /ws-docs/receivePlaceLimitOrder.md description: WebSocket RECEIVE — /ws/account --- # Place a limit order via WebSocket `RECEIVE` **Client to Server** on `wss://api.valr.com/ws/account` Submit a limit order through the WebSocket connection for lower-latency order placement. The server responds with a `PLACE_LIMIT_WS_RESPONSE` message containing the result. If the request is invalid, an `INVALID_PLACE_LIMIT_REQUEST` message is returned instead. **Request format:** ```json { "type": "PLACE_LIMIT_ORDER", "clientMsgId": "unique-correlation-id", "payload": { ... } } ``` ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `PLACE_LIMIT_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | pair | string | Yes | - | | postOnly | boolean | No | - | | reduceOnly | boolean | No | - | | customerOrderId | string | No | - | | timeInForce | string | No | - | | allowMargin | boolean | No | - | ### Example ```json "{\n \"type\": \"PLACE_LIMIT_ORDER\",\n \"clientMsgId\": \"a1b2c3d4-correlation-id\",\n \"payload\": {\n \"side\": \"BUY\",\n \"quantity\": \"0.01\",\n \"price\": \"950000\",\n \"pair\": \"BTCZAR\",\n \"postOnly\": false,\n \"reduceOnly\": false,\n \"customerOrderId\": \"my-limit-order-1\",\n \"timeInForce\": \"GTC\",\n \"allowMargin\": false\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /ws-docs/receivePlaceMarketOrder.md description: WebSocket RECEIVE — /ws/account --- # Place a market order via WebSocket `RECEIVE` **Client to Server** on `wss://api.valr.com/ws/account` Submit a market order through the WebSocket connection. Specify either `baseAmount` or `quoteAmount` but not both. The server responds with a `PLACE_MARKET_WS_RESPONSE` message. If the request is invalid, an `INVALID_PLACE_MARKET_REQUEST` message is returned. **Request format:** ```json { "type": "PLACE_MARKET_ORDER", "clientMsgId": "unique-correlation-id", "payload": { ... } } ``` ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `PLACE_MARKET_ORDER` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | baseAmount | string | No | - | | quoteAmount | string | No | - | | pair | string | Yes | - | | customerOrderId | string | No | - | | allowMargin | boolean | No | - | | timeInForce | string | No | - | | reduceOnly | boolean | No | - | ### Example ```json "{\n \"type\": \"PLACE_MARKET_ORDER\",\n \"clientMsgId\": \"b2c3d4e5-correlation-id\",\n \"payload\": {\n \"side\": \"BUY\",\n \"baseAmount\": \"0.01\",\n \"quoteAmount\": null,\n \"pair\": \"BTCZAR\",\n \"customerOrderId\": \"my-market-order-1\",\n \"allowMargin\": false,\n \"timeInForce\": \"FOK\",\n \"reduceOnly\": false\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV1BatchOrders.md description: POST /v1/batch/orders --- # Place batch orders `POST /v1/batch/orders` **Tags:** Batch Orders Create a batch of multiple create, cancel or modify orders in a single request. The data parameter supports the same fields as in the non batch order for the relevant request. When the response is `200 OK`, this means that the Batch Order has been submitted. However, this does not mean that all the orders in the Batch have been executed. In the response body will be the outcomes of each of the orders in the batch. Values are `true` with an orderId for accepted orders, or `false` with a failure message for failed orders. | Parameter | Description | | --- | --- | | type (required) | For each order in the batch, order type being placed. Can be `PLACE_MARKET`, `PLACE_LIMIT`, `PLACE_STOP_LIMIT`, `CANCEL_ORDER` or `MODIFY_ORDER` | | data (required) | Contains the order parameters matching the individual order endpoint (see data fields per type below) | | customerBatchId (optional) | Alphanumeric value for tracking the batch. Supports alphanumeric characters and dashes, 50-character limit. | A maximum of 20 orders may be submitted in a single Batch Orders request. Responses for the orders will be returned in the same sequence that they are submitted in the request. ## Supported Request Types | Type | Description | |------|-------------| | `PLACE_LIMIT` | Place a new limit order | | `PLACE_MARKET` | Place a new market order | | `PLACE_STOP_LIMIT` | Place a new stop limit order | | `CANCEL_ORDER` | Cancel an existing order | | `MODIFY_ORDER` | Modify an existing order | ## Data Fields Per Type **`PLACE_LIMIT`**: `pair`, `side`, `quantity`, `price`, `timeInForce` (optional, default GTC), `postOnly` (optional, default false), `customerOrderId` (optional). **`PLACE_MARKET`**: `pair`, `side`, `baseAmount` or `quoteAmount` (provide one, not both), `customerOrderId` (optional). **`PLACE_STOP_LIMIT`**: `pair`, `side`, `quantity`, `price`, `stopPrice`, `type` (`TAKE_PROFIT_LIMIT` or `STOP_LOSS_LIMIT`), `timeInForce` (optional, default GTC), `customerOrderId` (optional). **`CANCEL_ORDER`**: `orderId` or `customerOrderId` (provide one, not both), `pair`. **`MODIFY_ORDER`**: `orderId`, `pair`, `modifyMatchStrategy` (`RETAIN_ORIGINAL`, `CANCEL_ORIGINAL`, or `REPRICE`), `newPrice` (optional), `newRemainingQuantity` or `newTotalQuantity` (optional, provide one, not both), `customerOrderId` (optional). Each request in the batch is processed independently. If one request fails, the others are still processed. The response contains the result for each request in the same order as the input. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | customerBatchId | string | No | - | | requests | IncomingBatchOrderRequest\[] | Yes | - | **`requests` properties:** | Property | Type | Required | Description | |---|---|---|---| | type | string | Yes | - | | data | object | Yes | - | **`data` properties:** | Property | Type | Required | Description | |---|---|---|---| ## Responses ### 200 Batch order outcomes **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | outcomes | BatchOrderRequestOutcome\[] | Yes | - | | batchId | integer (int64) | Yes | - | **`outcomes` properties:** | Property | Type | Required | Description | |---|---|---|---| | accepted | boolean | Yes | - | | orderId | string | No | - | | error | object | No | - | | customerOrderId | string | No | - | | requestType | string | No | - | **`error` properties:** | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | - | | message | string | Yes | - | | validationErrors | object | No | - | **`validationErrors` properties:** | Property | Type | Required | Description | |---|---|---|---| | errors | ValidationError\[] | Yes | - | **Example:** ```json { "outcomes": [ { "accepted": true, "orderId": "019817e7-a109-7924-9269-90a1296d0ffd", "customerOrderId": "1234", "requestType": "PLACE_MARKET" }, { "accepted": true, "orderId": "019817e7-a10b-70d0-b8c9-4f76be471825", "requestType": "PLACE_LIMIT" }, { "accepted": true, "orderId": "019817e7-a10b-7a44-aef7-fbb52b6b8f30", "requestType": "PLACE_LIMIT" }, { "accepted": true, "orderId": "019817e7-a10b-7c90-bf3a-594ba91e9cea", "requestType": "PLACE_STOP_LIMIT" }, { "accepted": true, "orderId": "019817e7-a113-73df-8bcd-7e29fdcde48d", "requestType": "PLACE_STOP_LIMIT" }, { "accepted": false, "error": { "code": -12007, "message": "Minimum order size not met . Minimum amount: 0.00000786 BTC, minimum total: 0.52 USDT" } }, { "accepted": true, "orderId": "e5886f2d-191b-4330-a221-c7b41b0bc553", "requestType": "CANCEL_ORDER" } ], "batchId": 1395349783381500000 } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/receiveBatchOrders.md description: WebSocket RECEIVE — /ws/account --- # Place batch orders via WebSocket `RECEIVE` **Client to Server** on `wss://api.valr.com/ws/account` Submit multiple orders in a single batch through the WebSocket connection. Each order in the batch can be one of: PLACE\_LIMIT, PLACE\_MARKET, MODIFY\_ORDER, or CANCEL\_ORDER. **Request format:** ```json { "type": "BATCH_ORDERS", "clientMsgId": "unique-correlation-id", "payload": { ... } } ``` ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `BATCH_ORDERS` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | requests | WsBatchOrderEntry\[] | Yes | - | #### requests (WsBatchOrderEntry) | Property | Type | Required | Description | |---|---|---|---| | type | string | Yes | - | | side | string | Yes | - | | quantity | string | Yes | - | | price | string | No | - | | pair | string | Yes | - | | customerOrderId | string | No | - | ### Example ```json "{\n \"type\": \"BATCH_ORDERS\",\n \"clientMsgId\": \"123456789abcd\",\n \"payload\": {\n \"requests\": [\n {\n \"type\": \"PLACE_LIMIT\",\n \"data\": {\n \"pair\": \"BTCUSDC\",\n \"side\": \"SELL\",\n \"quantity\": \"0.0021\",\n \"price\": \"60000\",\n \"timeInForce\": \"GTC\"\n }\n },\n {\n \"type\": \"PLACE_MARKET\",\n \"data\": {\n \"pair\": \"BTCUSDT\",\n \"side\": \"SELL\",\n \"baseAmount\": \"0.0001\",\n \"timeInForce\": \"GTC\"\n }\n },\n {\n \"type\": \"CANCEL_ORDER\",\n \"data\": {\n \"customerOrderId\": \"WS-JSON-2938586967831375\",\n \"pair\": \"BTCUSDT\"\n }\n }\n ]\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account` --- --- url: /api-docs/postV2Brokerage.md description: POST /v2/brokerage --- # Place brokerage instruction `POST /v2/brokerage` **Tags:** Brokerage Place a new brokerage instruction order. This endpoint creates and immediately executes a brokerage instruction to convert one currency to another. The system places automated market orders to convert your specified pay amount from the pay currency into the receive currency, intelligently routing through available currency pairs if necessary. ## Multi-Leg Conversions * **Direct pair** (e.g., BTC/ZAR): Single market order * **Indirect pair** (e.g., ZAR→XRP): Routed through intermediate currency (ZAR→USDT→XRP) * Each leg incurs separate trading fees in addition to the brokerage fee ## Fee Structure * **feeRate**: Your brokerage fee percentage (0.0 to 0.999) * **feeCurrency**: Deducted in either pay or receive currency. If `feeCurrency` matches `payCurrency`, the fee is calculated from `payAmount` before the order. If it matches `receiveCurrency`, the fee is a percentage of the received amount. * **feeAccountId**: Account that receives the brokerage fee (cannot be the same as the trading account) * Each trade leg also incurs standard exchange trading fees ## Important Notes * The account on which the trade is performed can be specified using the HTTP header. Please see our Subaccounts section for more information. Not including the header will result in the order being placed against your main account. * Executes immediately at market prices (no limit orders) * Subject to market slippage and liquidity * Cannot be cancelled once submitted * Requires API key with both trade and internal transfer permissions ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | payAmount | string | Yes | The total amount to be traded. The trade and brokerage fees should be included in this amount. | | payCurrency | string | Yes | The currency for the amount specified in `payAmount`. | | receiveCurrency | string | Yes | The currency that will be received after the simple order / swap completes. | | feeRate | number | Yes | The brokerage fee levied. `0.000` to `0.999` allowed. Fees are specified as a fraction, e.g. a 10% brokerage fee is `0.1`. | | feeCurrency | string | Yes | The currency in which the brokerage fee is to be collected. This should match either `payCurrency` or `receiveCurrency`. | | feeAccountId | integer (int64) | Yes | The account id to which the brokerage fee will be transferred. Set to `0` for the main account. Defaults to `0`. | | customerOrderId | string | No | Custom order id for tracking. Alphanumeric with a 50-character limit. | ## Responses ### 200 Brokerage instruction created and executed **Content-Type:** `application/json` **Example:** ```json { "id": "de689cf3-f667-4104-905b-2fdb439618bc" } ``` ### 400 Invalid request parameters or validation failure **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - requires API key with trade and internal transfer permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Insufficient funds, insufficient fee balance, or fee account access denied **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 409 Duplicate customer order ID **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 503 Service unavailable - trading temporarily disabled **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1OrdersConditionals.md description: POST /v1/orders/conditionals --- # Place conditional order `POST /v1/orders/conditionals` **Tags:** Conditional Orders For users wishing to manage futures exposure, VALR offers conditional orders that can be added to an existing position as a Take Profit and Stop Loss (TPSL). | Parameter | Description | | --- | --- | | quantity (required) | The value in base amount (truncated to baseDecimalPlaces of the currency pair). `0` closes the entire open position. `> 0` places a reduce-only order. `-1` closes only the quantity added by the new order. | | triggerType (required) | Can either be `LAST_TRADED` or `MARK_PRICE` | | pair (required) | A valid currency pair (e.g., BTCUSDTPERP for futures, BTCZAR for spot) | | takeProfitTriggerPrice (required for TP) | The mark price or last traded price to trigger the conditional order. | | takeProfitOrderPrice (required for TP) | The price at which the conditional order will be placed. Use `-1` for a market order. | | stopLossTriggerPrice (required for SL) | The mark price or last traded price to trigger the conditional order. | | stopLossOrderPrice (required for SL) | The price at which the conditional order will be placed. Use `-1` for a market order. | | customerOrderId (optional) | Alphanumeric value. Must be unique across all open orders. | If both TP and SL are specified, the order is handled as OCO (One-Cancels-the-Other). Once one side triggers, the other is cancelled. **Note:** The response uses `takeProfitPlacePrice` for the value submitted as `takeProfitOrderPrice`, and `stopLossPlacePrice` for the value submitted as `stopLossOrderPrice`. When you receive a response with an id, it does not always mean that the order has been placed. When the response is `202 Accepted`, you can use the Order Status REST API or WebSocket API to receive the status of this order. On spot, it can be used to construct a take profit, stop loss as well as ordinary conditional orders. It can also be used with margin. On futures, a conditional order can be used to specify Take Profit and Stop Loss (TPSL) together in one request. When one of the TPSL orders is triggered, the other is automatically cancelled. A full list of conditional order request formats is available in the Postman collection. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | quantity | string | Yes | - | | pair | string | No | - | | triggerType | string | Yes | - | | customerOrderId | string | No | - | | takeProfitTriggerPrice | string | No | - | | takeProfitOrderPrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossOrderPrice | string | No | - | | linkedOrderId | string | No | - | | side | string | No | - | | allowMargin | boolean | No | - | ## Responses ### 202 Conditional order accepted **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "7a19f5a1-afad-4138-bb9a-65a136e6c507" } ``` ### 400 Invalid request parameters or order would trigger immediately **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -21403, "message": "Could not place conditional order as it would have triggered immediately" } ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1OrdersLimit.md description: POST /v1/orders/limit --- # Place limit order `POST /v1/orders/limit` **Tags:** Orders Create a new limit order. | Parameter | Description | | --- | --- | | side (required) | `BUY` or `SELL` | | quantity (required) | Base amount (the amount submitted will be truncated to `baseDecimalPlaces` of the currency pair) | | price (required) | Price in quote Currency | | pair (required) | Can be any supported currency pair e.g. `BTCUSDC`, `ETHUSDC` or `BTCUSDT` | | postOnly (optional) | `postOnly=true` will place a Maker order and cause it to fail if matched immediately. Default value is `false` | | customerOrderId (optional) | Alphanumeric value. Must be unique across all open orders. Supports alphanumeric characters and dashes, 50-character limit. | | timeInForce (optional) | Can be `GTC`, `FOK` or `IOC`. Default value is `GTC`. | | allowMargin (optional) | `true` or `false`. Default value is `false`. Set to `true` for margin/leverage trades. | | reduceOnly (optional) | `true` or `false`. Default value is `false`. Set to `true` for Perpetual Futures orders that should only reduce a position. | **Fee currency** depends on maker/taker role and trade side: | Role | BUY | SELL | | --- | --- | --- | | Maker | Quote currency | Base currency | | Taker | Base currency | Quote currency | **Failure reasons** (delivered asynchronously via WebSocket): * Insufficient balance * Non-unique customerOrderId * postOnly order would have matched immediately * Self-trade prevention * Insufficient liquidity (FOK/IOC) V1 order endpoints return `202 Accepted`. Validation errors such as insufficient balance are delivered asynchronously via WebSocket, not as HTTP error responses. Use the Order Status REST API or WebSocket API to receive the status of this order. **Optional parameters**: postOnly (true to place a Maker order that fails if matched immediately, default false), customerOrderId (alphanumeric value for tracking, must be unique across all open orders), timeInForce (GTC/FOK/IOC, default GTC), allowMargin (true/false for margin/leverage trades, default false), reduceOnly (true/false for orders that should only reduce a position, default false). * **`customerOrderId`**: Supports alphanumeric characters and dashes ("-"), with a 50-character limit. Must be unique across all open orders for a given account. Reusing an id from an active order will prevent the new order from being placed. * **`timeInForce`**: Defines how long an order remains active: * `GTC` (Good Till Cancelled): Remains active until fully filled or explicitly cancelled. * `FOK` (Fill or Kill): Must be fully filled immediately or cancelled entirely. No partial fills. * `IOC` (Immediate or Cancel): Fills as much as possible immediately; any unfilled portion is cancelled. * **`allowMargin`**: Set to `true` for margin/leverage trades. Only subaccounts can trade on margin, and each must be enabled individually via the account/status API. * **`reduceOnly`**: Set to `true` for Perpetual Futures orders that should only reduce an existing position, preventing the order from opening a new position or increasing the size of an existing one. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | pair | string | Yes | - | | postOnly | boolean | No | - | | reduceOnly | boolean | No | - | | customerOrderId | string | No | - | | timeInForce | string | No | - | | allowMargin | boolean | No | - | | postOnlyReprice | boolean | No | - | | postOnlyRepriceTicks | string | No | - | | conditionalOrderData | object | No | - | **`conditionalOrderData` properties:** | Property | Type | Required | Description | |---|---|---|---| | quantity | string | Yes | - | | pair | string | No | - | | triggerType | string | Yes | - | | customerOrderId | string | No | - | | takeProfitTriggerPrice | string | No | - | | takeProfitOrderPrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossOrderPrice | string | No | - | | linkedOrderId | string | No | - | | side | string | No | - | | allowMargin | boolean | No | - | ## Responses ### 202 Limit order accepted **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "14ed7fbc-272e-4bac-a4f9-7ec8df36df34" } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Forbidden - Account not authorised for trading **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV2OrdersLimit.md description: POST /v2/orders/limit --- # Place limit order `POST /v2/orders/limit` **Tags:** Orders Create a new limit order. Limit orders are only executed at the specified price or better. When you receive a 201 Created response with an id, it means that the order has been successfully placed. You can use the Order Status REST API or WebSocket API to receive the status of this order. **Required parameters**: side (BUY/SELL), quantity (base amount), price (per coin in quote currency), pair (currency pair). **Optional parameters**: postOnly (true to place a Maker order that fails if matched immediately, default false), customerOrderId (alphanumeric value for tracking, must be unique across all open orders), timeInForce (GTC/FOK/IOC, default GTC), allowMargin (true/false for margin/leverage trades, default false), reduceOnly (true/false for orders that should only reduce a position, default false). **Notes**: The customerOrderId supports alphanumeric characters with a 50-character limit (no special characters). It must be unique across all open orders for a given account. Fee currency depends on maker/taker role and trade side. When placement fails synchronously, the endpoint returns `201 Created` with `{orderId, code, message}` instead of `{id}`. Check the response body structure to distinguish success from failure. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | pair | string | Yes | - | | postOnly | boolean | No | - | | reduceOnly | boolean | No | - | | customerOrderId | string | No | - | | timeInForce | string | No | - | | allowMargin | boolean | No | - | | postOnlyReprice | boolean | No | - | | postOnlyRepriceTicks | string | No | - | | conditionalOrderData | object | No | - | **`conditionalOrderData` properties:** | Property | Type | Required | Description | |---|---|---|---| | quantity | string | Yes | - | | pair | string | No | - | | triggerType | string | Yes | - | | customerOrderId | string | No | - | | takeProfitTriggerPrice | string | No | - | | takeProfitOrderPrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossOrderPrice | string | No | - | | linkedOrderId | string | No | - | | side | string | No | - | | allowMargin | boolean | No | - | ## Responses ### 201 Limit order created successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "14ed7fbc-272e-4bac-a4f9-7ec8df36df34" } ``` ### 400 Invalid request parameters or order failed during placement **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "orderId": "99ded62e-26ff-407c-98d5-cd24b4e56179", "code": -6, "message": "Insufficient Balance" } ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Forbidden - Account not authorised for trading **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1OrdersMarket.md description: POST /v1/orders/market --- # Place market order `POST /v1/orders/market` **Tags:** Orders Create a new market order. When the response is `202 Accepted`, you can either use the Order Status REST API or WebSocket API to receive updates about this order. | Parameter | Description | | --- | --- | | side (required) | `BUY` or `SELL` | | baseAmount / quoteAmount (required) | Either the `baseAmount` or `quoteAmount` must be provided. If `quoteAmount` is specified for a SELL order, your account will be credited with `quoteAmount` minus taker fees. If `baseAmount` is specified for a BUY order, your account will be credited with `baseAmount` minus taker fees. If `baseAmount` is provided, it will be truncated to `baseDecimalPlaces` of the currency pair. | | pair (required) | Can be any supported currency pair. | | timeInForce (optional) | Can be `FOK` or `IOC` (must be uppercase). If not specified, `IOC` is used by default. | | customerOrderId (optional) | Alphanumeric value. Must be unique across all open orders. Supports alphanumeric characters and dashes ("-"), 50-character limit. | | allowMargin (optional) | `true` or `false`. Default value is `false`. Set to `true` for margin/leverage trades. | | reduceOnly (optional) | `true` or `false`. Default value is `false`. Set to `true` for Perpetual Futures orders that should only reduce a position. | | conditionalOrderData (optional) | Used on futures pairs to manage exposure through adding a Take Profit and/or Stop Loss (TPSL) to the order. | **Fee currency** (market orders are always taker): | Side | Fee Currency | | --- | --- | | BUY | Base currency | | SELL | Quote currency | V1 order endpoints return `202 Accepted`. Validation errors such as insufficient balance are delivered asynchronously via WebSocket, not as HTTP error responses. Use the Order Status REST API or WebSocket API to receive the status of this order. **Notes** * **`timeInForce`**: `IOC` (Immediate or Cancel): Fills as much of the order as possible within the allowed slippage, then cancels the remainder. `FOK` (Fill or Kill): The entire order must fill within the allowed slippage or it is cancelled completely. * **`customerOrderId`**: Optional field for tracking orders using your internal system. It supports alphanumeric characters and dashes ("-"), with a 50-character limit. Special characters are not allowed. The `customerOrderId` must be unique across all open orders for a given account. Reusing an id from an active order will prevent the new order from being placed (use the order status API to check an order's status). * **`allowMargin`**: Set to `true` for margin/leverage trades. Only subaccounts can trade on margin, and each must be enabled individually via the account/status API. * **`reduceOnly`**: Set to `true` for Perpetual Futures orders that should only reduce an existing position, preventing the order from opening a new position or increasing the size of an existing one. * **`conditionalOrderData`**: Used on futures pairs to manage exposure by attaching a Take Profit and/or Stop Loss (TPSL) to the order. A `conditionalOrderId` is returned in the response when a conditional order is attached. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | baseAmount | string | No | - | | quoteAmount | string | No | - | | pair | string | Yes | - | | customerOrderId | string | No | - | | allowMargin | boolean | No | - | | timeInForce | string | No | - | | reduceOnly | boolean | No | - | | conditionalOrderData | object | No | - | | slippagePrice | string | No | - | **`conditionalOrderData` properties:** | Property | Type | Required | Description | |---|---|---|---| | quantity | string | Yes | - | | pair | string | No | - | | triggerType | string | Yes | - | | customerOrderId | string | No | - | | takeProfitTriggerPrice | string | No | - | | takeProfitOrderPrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossOrderPrice | string | No | - | | linkedOrderId | string | No | - | | side | string | No | - | | allowMargin | boolean | No | - | ## Responses ### 202 Market order accepted **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "14ed7fbc-272e-4bac-a4f9-7ec8df36df34" } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Forbidden - Account not authorised for trading **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV2OrdersMarket.md description: POST /v2/orders/market --- # Place market order `POST /v2/orders/market` **Tags:** Orders Create a new market order. Market orders are executed immediately at current market prices. When you receive a 201 Created response with an id, it means that the order has been successfully placed. You can use the Order Status REST API or WebSocket API to receive the status of this order. **Required parameters**: side (BUY/SELL), either baseAmount or quoteAmount (but not both), pair (currency pair). **Amount specification**: Either baseAmount or quoteAmount must be provided. If quoteAmount is specified for a SELL order, your account will be credited with quoteAmount minus taker fees. If baseAmount is specified for a BUY order, your account will be credited with baseAmount minus taker fees. If baseAmount is provided, it will be truncated to baseDecimalPlaces of the currency pair. **Optional parameters**: timeInForce (FOK/IOC, default IOC), customerOrderId (alphanumeric value for tracking, must be unique across all open orders), allowMargin (true/false for margin/leverage trades, default false), reduceOnly (true/false for orders that should only reduce a position, default false). **Notes**: The customerOrderId supports alphanumeric characters with a 50-character limit (no special characters). Market orders are charged the Taker fee. Fee currency depends on trade side (charged in the currency you receive). timeInForce for market orders can be FOK (Fill or Kill) or IOC (Immediate or Cancel). If not specified, IOC is used by default. When placement fails synchronously, the endpoint returns `201 Created` with `{orderId, code, message}` instead of `{id}`. Check the response body structure to distinguish success from failure. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | baseAmount | string | No | - | | quoteAmount | string | No | - | | pair | string | Yes | - | | customerOrderId | string | No | - | | allowMargin | boolean | No | - | | timeInForce | string | No | - | | reduceOnly | boolean | No | - | | conditionalOrderData | object | No | - | | slippagePrice | string | No | - | **`conditionalOrderData` properties:** | Property | Type | Required | Description | |---|---|---|---| | quantity | string | Yes | - | | pair | string | No | - | | triggerType | string | Yes | - | | customerOrderId | string | No | - | | takeProfitTriggerPrice | string | No | - | | takeProfitOrderPrice | string | No | - | | stopLossTriggerPrice | string | No | - | | stopLossOrderPrice | string | No | - | | linkedOrderId | string | No | - | | side | string | No | - | | allowMargin | boolean | No | - | ## Responses ### 201 Market order created successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "fd7c947c-9022-4457-a1a8-2ecc7e3d5518" } ``` ### 400 Invalid request parameters or order failed during placement **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "orderId": "99ded62e-26ff-407c-98d5-cd24b4e56179", "code": -6, "message": "Insufficient Balance" } ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 403 Forbidden - Account not authorised for trading **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1SimpleCurrencyPairOrder.md description: 'POST /v1/simple/{currencyPair}/order' --- # Place Simple Buy/Sell order `POST /v1/simple/{currencyPair}/order` **Tags:** Simple Buy/Sell Submit an order to buy or sell instantly using Simple Buy/Sell. Example usage of `payInCurrency` and `side` for the `BTCUSDC` currency pair: If you want to sell `BTC` for `USDC`, `payInCurrency` will be `BTC` and the side would be `SELL`. If you want to buy `BTC` with `USDC`, `payInCurrency` will be `USDC` and the side would be `BUY`. Example usage for the `ETHBTC` currency pair: If you want to sell ETH for BTC, `payInCurrency` will be `ETH` and the side would be `SELL`. If you want to buy ETH with BTC, `payInCurrency` will be `BTC` and the side would be `BUY`. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencyPair | path | string | Yes | The currency pair to place a simple order for. Any currency pair that supports the "simple" order type can be specified. | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | payInCurrency | string | Yes | The currency you are paying with. | | payAmount | string | Yes | The amount you are paying. | | side | string | Yes | The side of the order: `BUY` or `SELL`. | ## Responses ### 202 Order accepted **Content-Type:** `application/json` **Example:** ```json { "id": "9fed72b4-5d59-4bd7-b4fc-26cf43d27c94" } ``` ### 400 Bad request - Invalid parameters or currency pair not supported **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -12005, "message": "Selected order type is not allowed for the currency pair." } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1OrdersStopLimit.md description: POST /v1/orders/stop/limit --- # Place stop limit order `POST /v1/orders/stop/limit` **Tags:** Orders Create a new Stop Loss Limit or Take Profit Limit order. When the response is `202 Accepted`, you can either use the Order Status REST API or WebSocket API to receive updates about this order. | Parameter | Description | | --- | --- | | side (required) | `BUY` or `SELL` | | quantity (required) | Amount in Base Currency must be provided. | | price (required) | The Limit Price at which the BUY or SELL order will be placed. | | pair (required) | Can be any supported currency pair. | | stopPrice (required) | The target price for the trade to trigger. Cannot be equal to last traded price. | | type (required) | Can be `TAKE_PROFIT_LIMIT` or `STOP_LOSS_LIMIT`. | | customerOrderId (optional) | Alphanumeric value. Must be unique across all open orders. | | timeInForce (optional) | Can be `GTC`, `FOK` or `IOC`. Default value is `GTC`. | Stop limit order support varies by currency pair. Use `GET /v1/public/{pair}/ordertypes` to verify support. V1 order endpoints return `202 Accepted`. Validation errors are delivered asynchronously via WebSocket. Use the Order Status REST API or WebSocket API to receive the status of this order. * **`customerOrderId`**: Supports alphanumeric characters and dashes ("-"), with a 50-character limit. Must be unique across all open orders for a given account. * **`timeInForce`**: Defines how long an order remains active: * `GTC` (Good Till Cancelled): Remains active until fully filled or explicitly cancelled. * `FOK` (Fill or Kill): Must be fully filled immediately or cancelled entirely. * `IOC` (Immediate or Cancel): Fills as much as possible immediately; any unfilled portion is cancelled. * **`allowMargin`**: Set to `true` for margin/leverage trades. Only subaccounts can trade on margin, and each must be enabled individually via the account/status API. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | type | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | stopPrice | string | Yes | - | | pair | string | Yes | - | | postOnly | boolean | No | - | | customerOrderId | string | No | - | | timeInForce | string | No | - | ## Responses ### 202 Stop limit order accepted **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "0198176c-df21-794a-99bc-ea7683efe371", "customerOrderId": "556789" } ``` ### 400 Invalid request parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV2OrdersStopLimit.md description: POST /v2/orders/stop/limit --- # Place stop limit order `POST /v2/orders/stop/limit` **Tags:** Orders Create a new Stop Loss Limit or Take Profit Limit order. When you receive a `201 Created` response with an id, it means that the order has been successfully placed. You can use the Order Status REST API or WebSocket API to receive the status of this order. | Parameter | Description | | --- | --- | | side (required) | `BUY` or `SELL` | | quantity (required) | Amount in Base Currency must be provided. | | price (required) | The Limit Price in Quote Currency at which the BUY or SELL order will be placed. | | pair (required) | Any pair that supports stop limit orders. Please see Public/Order Types. | | stopPrice (required) | The target price for the trade to trigger. Cannot be equal to last traded price. | | type (required) | Can be `TAKE_PROFIT_LIMIT` or `STOP_LOSS_LIMIT`. | | customerOrderId (optional) | Alphanumeric value. Must be unique across all open orders. | | timeInForce (optional) | Can be `GTC`, `FOK` or `IOC`. Default value is `GTC`. | When an order fails during the order placement process you can expect to receive an orderId, code and message in the response body. **Notes** * **`customerOrderId`**: Optional field for tracking orders using your internal system. It supports alphanumeric characters and dashes ("-"), with a 50-character limit. Special characters are not allowed. The `customerOrderId` must be unique across all open orders for a given account. Reusing an id from an active order will prevent the new order from being placed (use the order status API to check an order's status). * **`allowMargin`**: Set to `true` for margin/leverage trades. Only subaccounts can trade on margin, and each must be enabled individually via the account/status API. * **`timeInForce`**: Defines how long an order remains active: * `GTC` (Good Till Cancelled): Remains active until fully filled or explicitly cancelled. * `FOK` (Fill or Kill): Must be fully filled immediately or cancelled entirely. No partial fills. * `IOC` (Immediate or Cancel): Fills as much as possible immediately; any unfilled portion is cancelled. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | side | string | Yes | - | | type | string | Yes | - | | quantity | string | Yes | - | | price | string | Yes | - | | stopPrice | string | Yes | - | | pair | string | Yes | - | | postOnly | boolean | No | - | | customerOrderId | string | No | - | | timeInForce | string | No | - | ## Responses ### 201 Stop limit order created successfully **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | id | string (uuid) | Yes | - | **Example:** ```json { "id": "95603118-2f14-4da3-93c4-2b8c25850d8d" } ``` ### 400 Invalid request parameters or order failed during placement **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "orderId": "99ded62e-26ff-407c-98d5-cd24b4e56179", "code": -6, "message": "Insufficient Balance" } ``` ### 401 Unauthorised - API key missing or has insufficient permissions **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-docs/sendPnlRunCompleted.md description: WebSocket SEND — /ws/trade --- # PnL run completed `SEND` **Server to Client** on `wss://api.valr.com/ws/trade` Sent when a PnL (profit and loss) calculation run has completed for a futures pair. Contains the settlement price used for the PnL calculation. ## Subscription This event requires an explicit subscription. Send a `SUBSCRIBE` message after connecting: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "PNL_RUN_COMPLETED" } ] } ``` ## Message **Event type:** `PNL_RUN_COMPLETED` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | price | string | Yes | - | ### Example ```json "{\n \"type\": \"PNL_RUN_COMPLETED\",\n \"currencyPairSymbol\": \"BTCUSDTPERP\",\n \"data\": {\n \"price\": \"116048\"\n }\n}" ``` ## Channel **Channel:** trade **Address:** `wss://api.valr.com/ws/trade` --- --- url: /guides/rate-limiting.md description: 'API rate limits, per-second trading limits, and WebSocket rate limits' --- # Rate Limiting ## General Limits The VALR API enforces two rate limits simultaneously: * **Per API key**: 2000 calls per minute * **Per IP address**: 1200 calls per minute If either limit is exceeded, the API returns `429 Too Many Requests` with the header `x-valr-ratelimited: true`. ## Reset Behaviour The rate limit counter resets at the start of each minute. **Example 1**: If 2000 API calls are made between 12:00:00 and 12:00:30, additional calls will be rejected until 12:01:00. **Example 2**: If 1500 API calls are made between 12:00:00 and 12:00:59, a further 2000 calls can be made starting at 12:01:00. ## Per-Second Rate Limits High-frequency trading routes have additional per-second rate limits: | Route | Method | Rate Limit | |---|---|---| | `/v1/public/*` | GET | 30/m | | `/v1/public/time` | GET | 20/s | | `/v1/public/status` | GET | 20/s | | `/v1/public/*/buckets` | GET | 20/s | | `/v1/batch/orders` | POST | 400/s | | `/v1/orders` | DELETE | 450/s | | `/v1/orders` | POST | 400/s | | `/v2/orders/modify` | PUT | 400/s | | `/v1/loans/*` | POST, PUT, DELETE | 1/s | | `/v1/account/subaccount` | POST | 1/s | | `/v1/account/subaccount/transfer` | POST | 20/s | ## WebSocket Rate Limits **New connections**: The `/ws` endpoint allows a maximum of 60 new client connections per minute. **Write operations on `/ws/account`**: | Operation | Rate Limit | |---|---| | Place order | 400/s | | Cancel order | 450/s | | Batch orders | 400/s | | Modify order | 400/s | ::: warning ⚠️ WARNING We may reduce limits when the system is under severe pressure. ::: --- --- url: /api-docs/postV1AccountSubaccount.md description: POST /v1/account/subaccount --- # Register subaccount `POST /v1/account/subaccount` **Tags:** Subaccounts Creates a new subaccount. These endpoints can only be called by a primary account API key with `Trade` permissions. ## Query Parameter `isProprietarySubAccount` An **optional** boolean value indicating whether to create a proprietary subaccount (label only) or a customer subaccount (including KYC data). If not provided, the default is `false`. ## Create Proprietary Subaccount (Label Only) Set `isProprietarySubAccount` to `true`. Only the `label` field is required in the request body. ## Create Customer Subaccount (With KYC Info) Set `isProprietarySubAccount` to `false`. Note that `label`, `identityNumber`, and `cellNumber` should be unique per subaccount. **Note:** Registering subaccounts with KYC information is not available to all clients and will not work unless VALR has specifically enabled this for your account. Please contact help@valr.com if you have already been enabled to utilise these endpoints but are having technical difficulty using them. Please contact business@valr.com if you believe these endpoints are required for your use case. Currently the number of subaccounts per primary account is limited to a maximum of 2000. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | isProprietarySubAccount | query | boolean | No | A boolean value indicating whether to create a proprietary subaccount (label only) or a customer subaccount (including KYC data). Defaults to false. | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | label | string | Yes | - | | firstName | string | Yes | - | | lastName | string | Yes | - | | dateOfBirth | string | Yes | - | | residentialCountry | string | Yes | - | | identityIssuingCountry | string | Yes | - | | identityType | string | Yes | - | | identityNumber | string | Yes | - | | identityExpiryDate | string | No | - | | cellNumber | string | Yes | - | | email | string | No | - | | purpose | string | Yes | - | | employmentStatus | string | Yes | - | | sourceOfFunds | string | Yes | - | | accountTags | string\[] | No | - | ## Responses ### 200 Subaccount created successfully **Content-Type:** `application/json` **Example:** ```json { "id": "903671169785507840" } ``` ### 400 Bad request - Invalid parameters **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/putV1LoansUnlock.md description: PUT /v1/loans/unlock --- # Request Loan Unlock `PUT /v1/loans/unlock` **Tags:** Lending Removes a loan offer or reduces its amount by the specified `unlockAmount`. Loan offer unlocking may take at least one hour, depending on current fund usage and availability to replace the requested offer. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | Symbol of the currency to be unlocked. | | unlockAmount | string | Yes | The amount to be unlocked. | | loanId | string | Yes | Unique identifier of the loan to unlock. | ## Responses ### 202 Loan unlock requested successfully ### 400 Bad request - Invalid unlock request **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/getV1AccountSubaccounts.md description: GET /v1/account/subaccounts --- # Retrieve subaccounts `GET /v1/account/subaccounts` **Tags:** Subaccounts Returns the list of all subaccounts that belong to a primary account, with each subaccount's label and id. Can only be called by a primary account API key. ## Authentication This endpoint requires API key authentication. ## Responses ### 200 Subaccounts retrieved successfully **Content-Type:** `application/json` Array of objects: | Property | Type | Required | Description | |---|---|---|---| | label | string | Yes | - | | id | string | Yes | - | | accountTags | string\[] | No | - | | autoPayoutLinkedBankAccountId | string | No | - | **Example:** ```json [ { "label": "Arbitrage Acc 001", "id": "903671169785507840" }, { "label": "Another Test Arbitrage Acc From API", "id": "903670867401564160" }, { "label": "Test Trade Acc From API", "id": "903267690654658560" }, { "label": "Test Arbitrage Acc From API", "id": "903260643187945472" }, { "label": "Trading", "id": "902529770612256768" }, { "label": "Primary", "id": "0" } ] ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/putV1PayTransactionidTransactionIdReverse.md description: 'PUT /v1/pay/transactionid/{transactionId}/reverse' --- # Reverse Payment `PUT /v1/pay/transactionid/{transactionId}/reverse` **Tags:** Pay Reverse an instant payment using VALR Pay by specifying the payment transaction id. An anonymous payment will be made back to the original sender's VALR Pay ID with the exact amount and identical currency. Only a recipient of a payment can perform the reversal. Successful requests return 202 - Accepted with an identifier and transactionId in the body. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | transactionId | path | string | Yes | The transaction id of the payment that is to be reversed | ## Responses ### 202 Reversal accepted **Content-Type:** `application/json` **Example:** ```json { "identifier": "d2e16dc6-0c83-4f70-a30e-ef958a2b1d5d", "transactionId": "918486592856862720" } ``` ### 400 Bad request - Invalid transaction ID **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /api-docs/postV1BundlesSell.md description: POST /v1/bundles/sell --- # Sell Bundle `POST /v1/bundles/sell` **Tags:** Bundles Sell a cryptocurrency bundle. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | amount | string | Yes | The amount of the bundle to sell. | | receiveCurrency | string | Yes | The currency to receive from the sale (e.g., USDT). | | bundleSymbol | string | Yes | The symbol of the bundle to sell (e.g., VALR3, VALR10). | ## Responses ### 200 Bundle sale initiated successfully **Content-Type:** `application/json` **Example:** ```json { "success": true, "id": "0199ffe6-c82f-70f2-88f0-65ef198a41f3", "payAmount": "0.01", "payCurrency": "VALR3", "receiveAmount": "0.97015723", "receiveCurrency": "USDT" } ``` ### 400 Bad request - Invalid bundle sale request **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "error": "Invalid fund" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /websockets/trade.md description: WebSocket channel for real-time market data --- # Trade Channel ``` wss://api.valr.com/ws/trade ``` The Trade WebSocket channel provides real-time market data including order book updates, trades, and market summaries. ## Authentication The Trade channel supports both authenticated and unauthenticated connections. Unauthenticated connections can receive all market data events but are automatically disconnected after 15 minutes. To authenticate (optional): ### Connection Headers Authentication is performed by passing HTTP headers during the WebSocket handshake. The following headers are required: | Header | Description | |---|---| | `X-VALR-API-KEY` | Your API key | | `X-VALR-SIGNATURE` | HMAC-SHA512 signature (see below) | | `X-VALR-TIMESTAMP` | Current Unix timestamp in milliseconds | The signature is computed as: ``` Signature = HMAC-SHA512(API_SECRET, TIMESTAMP + "GET" + "/ws/trade") ``` Example connection: ```javascript const WebSocket = require('ws'); const headers = { 'X-VALR-API-KEY': 'YOUR_API_KEY', 'X-VALR-SIGNATURE': signature, 'X-VALR-TIMESTAMP': timestamp }; const ws = new WebSocket('wss://api.valr.com/ws/trade', { headers }); ``` ## Subscribing to Events All Trade channel events require an explicit subscription. You can optionally filter by currency pairs: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "AGGREGATED_ORDERBOOK_UPDATE", "pairs": ["BTCZAR", "ETHZAR"] }, { "event": "NEW_TRADE", "pairs": ["BTCZAR"] }, { "event": "MARKET_SUMMARY_UPDATE" } ] } ``` If `pairs` is omitted, you receive events for all available currency pairs. To unsubscribe from an event, send a `SUBSCRIBE` message with an empty `pairs` array for that event. This removes all pair subscriptions, effectively unsubscribing you: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "AGGREGATED_ORDERBOOK_UPDATE", "pairs": [] } ] } ``` ## Events | Event | Description | |---|---| | `AGGREGATED_ORDERBOOK_UPDATE` | Full order book aggregated by price level | | `NEW_TRADE` | New trades with price, quantity, and taker side | | `MARKET_SUMMARY_UPDATE` | Market statistics including bid/ask, volume, and 24-hour change | ## Message Format Trade events include the currency pair in the message: ```json { "type": "EVENT_TYPE", "currencyPairSymbol": "BTCZAR", "data": { ... } } ``` For full payload schemas, see the individual operation pages in the sidebar. --- --- url: /api-docs/postV1StakingUn-stake.md description: POST /v1/staking/un-stake --- # Unlock Amount `POST /v1/staking/un-stake` **Tags:** Staking / DeFi Lending Unlock the specified currency. Use `earnType` in the request body to specify staking (`STAKE`) or DeFi lending (`LEND`). Unlocking may be subject to a cooldown period depending on the currency and earn type. ## Authentication This endpoint requires API key authentication. ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | currencySymbol | string | Yes | The symbol of the currency to unlock. | | amount | string | Yes | The amount that will be unlocked. | | earnType | string | Yes | The earn type: `STAKE` for staking or `LEND` for DeFi lending. | ## Responses ### 200 Amount unlocked successfully ### 400 Bad request - Invalid unlock request **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -1, "message": "Unsupported Currency" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /ws-operations/sendBalanceUpdate.md --- --- --- url: /ws-operations/sendOpenOrdersUpdate.md --- --- --- url: /ws-operations/sendOrderStatusUpdate.md --- --- --- url: /ws-operations/sendOrderProcessed.md --- --- --- url: /ws-operations/sendFailedOrder.md --- --- --- url: /ws-operations/sendFailedCancelOrder.md --- --- --- url: /ws-operations/sendNewAccountTrade.md --- --- --- url: /ws-operations/sendNewAccountHistoryRecord.md --- --- --- url: /ws-operations/sendInstantOrderCompleted.md --- --- --- url: /ws-operations/sendNewPendingReceive.md --- --- --- url: /ws-operations/sendNewPendingSend.md --- --- --- url: /ws-operations/sendSendStatusUpdate.md --- --- --- url: /ws-operations/sendMarginInfo.md --- --- --- url: /ws-operations/sendOpenPositionUpdate.md --- --- --- url: /ws-operations/sendReducePosition.md --- --- --- url: /ws-operations/sendPositionClosed.md --- --- --- url: /ws-operations/sendAddConditionalOrder.md --- --- --- url: /ws-operations/sendRemoveConditionalOrder.md --- --- --- url: /ws-operations/sendModifyOrderOutcome.md --- --- --- url: /ws-operations/sendLeverageUpdated.md --- --- --- url: /ws-operations/receivePlaceLimitOrder.md --- --- --- url: /ws-operations/receivePlaceMarketOrder.md --- --- --- url: /ws-operations/receiveCancelLimitOrder.md --- --- --- url: /ws-operations/receiveModifyOrder.md --- --- --- url: /ws-operations/receiveBatchOrders.md --- --- --- url: /ws-operations/receiveCancelOnDisconnect.md --- --- --- url: /ws-operations/sendAggregatedOrderbookUpdate.md --- --- --- url: /ws-operations/sendFullOrderbookSnapshot.md --- --- --- url: /ws-operations/sendFullOrderbookUpdate.md --- --- --- url: /ws-operations/sendObL1Snapshot.md --- --- --- url: /ws-operations/sendObL1Diff.md --- --- --- url: /ws-operations/sendNewTrade.md --- --- --- url: /ws-operations/sendMarketSummaryUpdate.md --- --- --- url: /ws-operations/sendNewTradeBucket.md --- --- --- url: /ws-operations/sendMarkPriceUpdate.md --- --- --- url: /ws-operations/sendPnlRunCompleted.md --- --- --- url: /ws-operations/sendFundingRunCompleted.md --- --- --- url: /ws-operations/sendAllowedOrderTypesUpdated.md --- --- --- url: /ws-operations/sendObL1D1Snapshot.md --- --- --- url: /ws-operations/sendObL1D10Snapshot.md --- --- --- url: /ws-operations/sendObL1D20Snapshot.md --- --- --- url: /ws-operations/sendObL1D40Snapshot.md --- --- --- url: /ws-operations/sendObL1D60Snapshot.md --- --- --- url: /ws-operations/sendObL1D80Snapshot.md --- --- --- url: /api-docs/putV1MarginLeverageCurrencypair.md description: 'PUT /v1/margin/leverage/{currencypair}' --- # Update Leverage `PUT /v1/margin/leverage/{currencypair}` **Tags:** Margin Allows the user to update their leverage for a specified currency pair, to one of the available leverage options. ## Authentication This endpoint requires API key authentication. ## Parameters | Name | In | Type | Required | Description | |---|---|---|---|---| | currencypair | path | string | Yes | The currency pair for which to update the leverage (e.g., BTCZARPERP, ETHUSDTPERP) | ## Request Body **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | leverageMultiple | string | Yes | The desired leverage multiple. Must be greater than one with a maximum of two decimal places. | ## Responses ### 202 Leverage update accepted ### 400 Bad request - Unsupported currency pair or invalid leverage **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | **Example:** ```json { "code": -21, "message": "Unsupported Currency Pair" } ``` ### 401 Unauthorised - Invalid or missing API key **Content-Type:** `application/json` | Property | Type | Required | Description | |---|---|---|---| | code | integer (int32) | Yes | Negative integer error code uniquely identifying the error type | | message | string | Yes | Human-readable error description | | validationErrors | object | No | Optional validation error details for 400 Bad Request responses | --- --- url: /websockets.md description: Real-time WebSocket API for the VALR cryptocurrency exchange --- # WebSocket API VALR provides real-time WebSocket APIs for streaming account updates and market data. WebSocket connections offer lower latency than polling REST endpoints and enable bidirectional communication for order placement. ## Channels VALR operates two WebSocket channels, each serving a distinct purpose: ### Account Channel ``` wss://api.valr.com/ws/account ``` The [Account channel](/websockets/account) provides authenticated, account-specific events and commands: * **Balance updates** — real-time notification when any currency balance changes * **Order lifecycle events** — order status changes, processing results, and failures * **Trade notifications** — new trades on your account * **Transaction history** — deposits, withdrawals, fees, and rewards * **Order commands** — place, cancel, and modify orders via WebSocket for lower latency ::: info 🔐 Authentication Required The Account channel requires authentication. All events and commands require a valid API key. ::: ### Trade Channel ``` wss://api.valr.com/ws/trade ``` The [Trade channel](/websockets/trade) provides real-time market data: * **Order book updates** — aggregated order book with price levels * **New trades** — live trade feed with price, quantity, and taker side * **Market summaries** — bid/ask prices, volume, and 24-hour statistics ::: tip 💡 No Auth Needed The Trade channel supports unauthenticated connections. You can receive market data without API credentials. Note that unauthenticated connections are automatically disconnected after 15 minutes. ::: ## Authentication WebSocket connections are authenticated using HMAC-based API key credentials. Two methods are available: ### Header-based Authentication Authentication is performed by passing HTTP headers during the WebSocket handshake. The following headers are required: | Header | Description | |---|---| | `X-VALR-API-KEY` | Your API key | | `X-VALR-SIGNATURE` | HMAC-SHA512 signature | | `X-VALR-TIMESTAMP` | Unix timestamp in milliseconds | The signature is computed as: ``` Signature = HMAC-SHA512(API_SECRET, TIMESTAMP + "GET" + "/ws/account") ``` **NodeJS example:** ```javascript const crypto = require('crypto'); const WebSocket = require('ws'); function signRequest(apiSecret, timestamp, verb, path) { return crypto .createHmac('sha512', apiSecret) .update(timestamp + verb + path) .digest('hex'); } function getAuthHeaders(apiKey, apiSecret, path) { const timestamp = Date.now().toString(); const signature = signRequest(apiSecret, timestamp, 'GET', path); return { 'X-VALR-API-KEY': apiKey, 'X-VALR-SIGNATURE': signature, 'X-VALR-TIMESTAMP': timestamp, }; } const headers = getAuthHeaders('YOUR_API_KEY', 'YOUR_API_SECRET', '/ws/account'); const ws = new WebSocket('wss://api.valr.com/ws/account', { headers }); ws.on('open', () => { console.log('Connected and authenticated'); }); ws.on('message', (data) => { console.log('Received:', JSON.parse(data)); }); ``` ### In-band Authentication (Alternative) Alternatively, you can connect first and then send an authentication message in-band: ```json { "type": "AUTHENTICATE", "payload": { "apiKey": "YOUR_API_KEY", "signature": "SIGNATURE", "timestamp": 1234567890123 } } ``` The signature is computed the same way as for header-based authentication. For detailed authentication instructions and code examples, see the [Authentication guide](/guides/authentication). ## Ping-Pong Keepalive To maintain an active connection, clients must send a `PING` message at least every 30 seconds. VALR will respond with a `PONG` message. **Send:** ```json { "type": "PING" } ``` **Response:** ```json { "type": "PONG" } ``` ::: tip On the Trade WebSocket, the PONG response body will be `"NO_SUBSCRIPTIONS"` if you are not currently subscribed to any message types. ::: ## Subscribing to Events Some events on the Account channel are automatically delivered upon connection. Others require explicit subscription, as do all Trade channel events. To subscribe, send a message with the event names you wish to receive: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "ORDER_STATUS_UPDATE" }, { "event": "AGGREGATED_ORDERBOOK_UPDATE", "pairs": ["BTCZAR", "ETHZAR"] } ] } ``` The optional `pairs` filter limits Trade channel events to specific currency pairs. If omitted, you receive events for all pairs. ### Unsubscribing **Account channel** — send an `UNSUBSCRIBE` message: ```json { "type": "UNSUBSCRIBE", "requests": [ { "event": "ORDER_STATUS_UPDATE" } ] } ``` **Trade channel** — send a `SUBSCRIBE` message with an empty `pairs` array for the event you wish to unsubscribe from: ```json { "type": "SUBSCRIBE", "subscriptions": [ { "event": "AGGREGATED_ORDERBOOK_UPDATE", "pairs": [] } ] } ``` ## Message Format All server-to-client messages follow an envelope structure: **Account channel:** ```json { "type": "EVENT_TYPE", "data": { ... } } ``` **Trade channel:** ```json { "type": "EVENT_TYPE", "currencyPairSymbol": "BTCZAR", "data": { ... } } ``` --- --- url: /ws-docs/sendSendStatusUpdate.md description: WebSocket SEND — /ws/account --- # Withdrawal status updated `SEND` **Server to Client** on `wss://api.valr.com/ws/account` Sent when there is a status update on a pending cryptocurrency withdrawal. Includes updated confirmation count, transaction hash, and any failure reason. ## Authentication This operation requires API key authentication (HMAC-SHA512 via query parameters or in-band AUTHENTICATE message). ## Message **Event type:** `SEND_STATUS_UPDATE` ### Payload Schema | Property | Type | Required | Description | |---|---|---|---| | uniqueId | string | Yes | - | | status | string | Yes | - | | transactionHash | string | No | - | | confirmations | integer (int32) | Yes | - | | failureReason | string | No | - | ### Example ```json "{\n \"type\": \"SEND_STATUS_UPDATE\",\n \"data\": {\n \"uniqueId\": \"c3d4e5f6-a1b2-1234-5678-90abcdef1234\",\n \"status\": \"CONFIRMED\",\n \"transactionHash\": \"d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5\",\n \"confirmations\": 6,\n \"failureReason\": null\n }\n}" ``` ## Channel **Channel:** account **Address:** `wss://api.valr.com/ws/account`