Trading API · v1.0.0
Trading API
The client-level REST API: a trader's own software reads prices and trades their own accounts with a key they create in the trader. Same guards, same prices and same history as the web trader.
#Basics
| Base URL | https://api.your-brand.com/api/open/v1 |
|---|---|
| Auth | X-API-Key: qk_… or Authorization: Bearer qk_…. Created by the client in the trader under API access (Pro mode). Details → |
| Enabled by | The broker, per brand. Otherwise 403 open_api_disabled with details.reason. |
| Rate limit | 1 200 requests / min per key, 10 order actions / s; X-RateLimit-* headers on every answer. Details → |
| Errors | { "error": { "code", "message", "details" } }. All codes → |
| Prices | Trading quotes - the bid / ask orders fill at, including the account type's spread. Chart bars are the platform's own history. |
First call: GET /account
curl "https://api.your-brand.com/api/open/v1/account" \
-H "X-API-Key: $OCTOLIT_API_KEY"const res = await fetch("https://api.your-brand.com/api/open/v1/account", {
method: "GET",
headers: {
"X-API-Key": process.env.OCTOLIT_API_KEY,
},
});
if (!res.ok) throw new Error(`GET failed: ${res.status} ${await res.text()}`);
const data = await res.json();
console.log(data);import os, requests
r = requests.request(
"GET",
"https://api.your-brand.com/api/open/v1/account",
headers={"X-API-Key": os.environ["OCTOLIT_API_KEY"]},
timeout=10,
)
r.raise_for_status()
print(r.json())<?php
$ch = curl_init("https://api.your-brand.com/api/open/v1/account");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: " . getenv("OCTOLIT_API_KEY"),
],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);using var http = new HttpClient();
using var req = new HttpRequestMessage(HttpMethod.Get, "https://api.your-brand.com/api/open/v1/account");
req.Headers.Add("X-API-Key", Environment.GetEnvironmentVariable("OCTOLIT_API_KEY"));
using var res = await http.SendAsync(req);
res.EnsureSuccessStatusCode();
Console.WriteLine(await res.Content.ReadAsStringAsync());var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://api.your-brand.com/api/open/v1/account"))
.header("X-API-Key", System.getenv("OCTOLIT_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var res = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.statusCode() + " " + res.body());var body io.Reader
req, err := http.NewRequest("GET", "https://api.your-brand.com/api/open/v1/account", body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("X-API-Key", os.Getenv("OCTOLIT_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.StatusCode, string(out))var req = URLRequest(url: URL(string: "https://api.your-brand.com/api/open/v1/account")!)
req.httpMethod = "GET"
req.setValue(ProcessInfo.processInfo.environment["OCTOLIT_API_KEY"], forHTTPHeaderField: "X-API-Key")
let (data, response) = try await URLSession.shared.data(for: req)
print((response as! HTTPURLResponse).statusCode, String(decoding: data, as: UTF8.self))val client = OkHttpClient()
val req = Request.Builder()
.url("https://api.your-brand.com/api/open/v1/account")
.header("X-API-Key", System.getenv("OCTOLIT_API_KEY"))
.get()
.build()
client.newCall(req).execute().use { res ->
println("${res.code} ${res.body?.string()}")
} #All operations
#Account
The key, its client, limits and trading accounts.
#Market
Symbols and the trading quotes orders fill at, chart bars and trending instruments.
GET
/symbols Symbols of a trading account (spread, leverage, contract size) GET /symbols/{id} One symbol GET /quotes Trading quotes snapshot (the prices orders fill at) GET /bars Chart history: the newest OHLCV bars of one symbol up to `to` (any chart timeframe) GET /trending Trending instruments: the symbols this brand's clients traded the most (live, prop / bot / demo trades not counted; 403 trending_disabled unless the brand offers it) #Trading
Orders, positions and history. Writes need the trade scope and a client_order_id.
GET
/positions Open positions GET /positions/{id} A position, order or closed trade of this key's accounts PATCH /positions/{id} Set / remove stop loss and take profit of an open position POST /positions/{id}/close Close an open position (the whole of it) GET /history Closed trades, newest id first (cursor: next_before_id) GET /orders Pending orders POST /orders Place a market, limit or stop order GET /orders/lookup The order this key placed with a client_order_id GET /orders/{id} An order, position or closed trade of this key's accounts PATCH /orders/{id} Move a pending order / set its stop loss and take profit DELETE /orders/{id} Cancel a pending order #Stream
Short-lived tickets for the WebSocket stream (quotes + account / execution events).
#Meta
This document and the reference page, served by your broker.
#Orders & idempotency
- Every order action carries a
client_order_id(body) or anIdempotency-Keyheader: 1-64 characters, letters, digits,_ - : .. Repeating it returns the same order with200instead of placing a second one. - Market orders fill at once and answer
201with the position; limit and stop orders answer201pending and fill later (accountevent on the stream). - Quantity is
lotsorunits(lots × contract size).sl/tpare absolute prices;0removes them on modify. - On a timeout,
500 unknown_outcomeor500 not_placed: callGET /orders/lookup?client_order_id=…before anything else. - MetaTrader accounts are not traded through this API (
409 mt_account) - their orders are placed in MetaTrader.
#Scopes
readAccount, symbols, quotes, bars, trending, positions, orders, history, stream tickets. Every key has it.tradePlace, change, close and cancel orders. Chosen when the key is created; the broker can stop API trading at any time.fixLog on over FIX 4.4 with the same key (QUOTE and TRADE sessions).#Limits
| Requests per minute, per key | 1 200 (broker-set, 10 - 12 000) |
| Requests per minute, per client | 2 x the key limit, across all keys |
| Order actions per second, per key | 10 (broker-set, 1 - 50) |
| Order actions per second, per trading account | 10 (broker-set, 1 - 50) |
| Keys per client | 5 (broker-set, 1 - 20) |
| Wrong keys per minute, per address | 60, then 429 too_many_invalid_keys |
| Symbols per GET /quotes | 100 |
| Bars per GET /bars | 5 000 |
| Stream ticket | single use, 60 s |
Brokers tune these per brand.
GET /account returns the limits that apply to your key.