API reference

REST + WebSocket core, FIX 4.4 gateway and signal webhooks · v1 · https://api.kalks.com/v1

REST
api.kalks.com/v1
JSON · HMAC-SHA256
WebSocket
stream.kalks.com/v1
Quotes, orders, positions
FIX 4.4
fix.kalks.com:9880
TLS 1.3 · LD4
Webhooks
hooks.kalks.com/v1
TradingView-ready
Getting started

Authentication

Every request is signed with your API key's secret. Keys are bound to one trading account, carry read and/or trade scopes and are IP-whitelisted. There is no withdraw scope — funds can never leave via the API.
HeaderValueNotes
X-KALKS-KEYkk_live_EXAMPLE1Public key id from API keys page
X-KALKS-TIMESTAMP1790261892184Unix ms; rejected if more than 5s from server time
X-KALKS-SIGNATUREhex(HMAC_SHA256(secret, ts+method+path+body))Path includes /v1 and the query string
Signing a request
1# Signature = HMAC_SHA256(secret, timestamp + method + path + body)
2TS=$(date +%s%N)
3SIG=$(printf "%s" "$TS""GET""/v1/accounts" \
4 | openssl dgst -sha256 -hmac "$KALKS_SECRET" | cut -d' ' -f2)
5
6curl "https://api.kalks.com/v1/accounts" \
7 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
8 -H "X-KALKS-TIMESTAMP: $TS" \
9 -H "X-KALKS-SIGNATURE: $SIG"
Order responses always include source:manualapiwebhookstrategycopy
REST

Accounts

Read balances, equity and margin for the account bound to your key.
GET/accounts
scope: read

List trading accounts

Returns every trading account the key can access, with live balance, equity and margin.

ParameterInTypeDescription
typequerystringFilter by live or demo
Request
1curl -X GET "https://api.kalks.com/v1/accounts?type=live" \
2 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
3 -H "X-KALKS-TIMESTAMP: 1790261892184" \
4 -H "X-KALKS-SIGNATURE: $SIG"
200 OK · application/json
1{
2 "data": [
3 {
4 "login": "80412337",
5 "type": "live",
6 "group": "Pro",
7 "currency": "USD",
8 "balance": 25000,
9 "equity": 26204.18,
10 "margin": 2041.1,
11 "leverage": 500
12 }
13 ]
14}
GET/accounts/{login}
scope: read

Get account

Detailed snapshot of one account, including free margin, margin level and server.

ParameterInTypeDescription
loginrequiredpathstringTrading account login, e.g. 80412337
Request
1curl -X GET "https://api.kalks.com/v1/accounts/80412337" \
2 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
3 -H "X-KALKS-TIMESTAMP: 1790261892184" \
4 -H "X-KALKS-SIGNATURE: $SIG"
200 OK · application/json
1{
2 "login": "80412337",
3 "server": "Kalks-Live01",
4 "equity": 26204.18,
5 "free_margin": 24163.08,
6 "margin_level": 1283.8
7}
REST

Orders

Requires the trade scope. Use client_id for idempotent retries — a duplicate returns 409 with the original order.
POST/orders
scope: trade

Place an order

Places a market or pending order. Every order is tagged with source=api and your key id for reporting.

ParameterInTypeDescription
loginrequiredbodystringTarget trading account
symbolrequiredbodystringInstrument, e.g. XAUUSD
siderequiredbodyenumbuy | sell
typerequiredbodyenummarket | limit | stop
volumerequiredbodynumberLots, min 0.01, step 0.01
pricebodynumberRequired for limit / stop
slbodynumberStop loss price
tpbodynumberTake profit price
client_idbodystringIdempotency key, max 64 chars
Request
1curl -X POST "https://api.kalks.com/v1/orders" \
2 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
3 -H "X-KALKS-TIMESTAMP: 1790261892184" \
4 -H "X-KALKS-SIGNATURE: $SIG" \
5 -H "Content-Type: application/json" \
6 -d '{"login":"80412337","symbol":"XAUUSD","side":"buy","type":"market","volume":0.5,"sl":2638,"tp":2690,"client_id":"gold-bo-0924-01"}'
200 OK · application/json
1{
2 "id": "ord_8f21c0",
3 "ticket": 51298844,
4 "status": "filled",
5 "price": 2654.48,
6 "volume": 0.5,
7 "source": "api",
8 "filled_at": "2026-09-24T14:58:12.184Z"
9}
DELETE/orders/{id}
scope: trade

Cancel a pending order

Cancels a pending limit or stop order. Filled orders cannot be cancelled — close the position instead.

ParameterInTypeDescription
idrequiredpathstringOrder id returned by POST /orders
Request
1curl -X DELETE "https://api.kalks.com/v1/orders/ord_8f21c0" \
2 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
3 -H "X-KALKS-TIMESTAMP: 1790261892184" \
4 -H "X-KALKS-SIGNATURE: $SIG"
200 OK · application/json
1{
2 "id": "ord_8f21c0",
3 "status": "cancelled"
4}
REST

Positions

Open positions update on every tick. Closing requires the trade scope.
GET/positions
scope: read

List open positions

Open positions with floating P/L, updated on every tick. Filter by account or symbol.

ParameterInTypeDescription
loginquerystringAccount login
symbolquerystringInstrument filter
Request
1curl -X GET "https://api.kalks.com/v1/positions?login=80412337" \
2 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
3 -H "X-KALKS-TIMESTAMP: 1790261892184" \
4 -H "X-KALKS-SIGNATURE: $SIG"
200 OK · application/json
1{
2 "data": [
3 {
4 "ticket": 51298844,
5 "symbol": "XAUUSD",
6 "side": "buy",
7 "volume": 0.5,
8 "open_price": 2654.48,
9 "profit": 142.6,
10 "source": "api"
11 }
12 ]
13}
DELETE/positions/{ticket}
scope: trade

Close a position

Closes a position fully, or partially when volume is passed.

ParameterInTypeDescription
ticketrequiredpathintegerPosition ticket
volumequerynumberPartial close volume
Request
1curl -X DELETE "https://api.kalks.com/v1/positions/51298844" \
2 -H "X-KALKS-KEY: kk_live_EXAMPLE1" \
3 -H "X-KALKS-TIMESTAMP: 1790261892184" \
4 -H "X-KALKS-SIGNATURE: $SIG"
200 OK · application/json
1{
2 "ticket": 51298844,
3 "status": "closed",
4 "close_price": 2657.33,
5 "profit": 142.5
6}
Streaming

Market data WebSocket

One connection streams quotes plus your own orders and positions. Up to 200 symbols per connection, 5 connections per key. Heartbeat every 5s; reconnect with exponential backoff.
WSwss://stream.kalks.com/v1
quotesorderspositionsaccount
Subscribe
subscribe
1wscat -c "wss://stream.kalks.com/v1?key=kk_live_EXAMPLE1&ts=1790261892184&sig=$SIG"
2
3> {"op": "subscribe", "channels": ["quotes"], "symbols": ["XAUUSD", "EURUSD"]}
4> {"op": "subscribe", "channels": ["positions", "orders"], "login": "80412337"}
Streamed messages
← server · newline-delimited JSON
1{"channel":"subscribed","symbols":["XAUUSD","EURUSD"],"id":1}
2{"channel":"quote","symbol":"XAUUSD","bid":2654.30,"ask":2654.48,"ts":1790261892301}
3{"channel":"quote","symbol":"EURUSD","bid":1.08456,"ask":1.08464,"ts":1790261892318}
4{"channel":"quote","symbol":"XAUUSD","bid":2654.36,"ask":2654.54,"ts":1790261892402}
5{"channel":"position","login":"80412337","ticket":51298844,"profit":142.60,"source":"api"}
6{"channel":"order","id":"ord_8f22a1","status":"filled","price":1.08461,"source":"webhook"}
7{"channel":"heartbeat","ts":1790261897000}
Signals

Signal webhooks

POST a JSON signal to your webhook URL (from TradingView or any system). Kalks validates the secret, then fans the order out to every target account using its sizing rule — fixed lot, multiplier or risk %. Orders are tagged source=webhook.
POSThttps://hooks.kalks.com/v1/signal/{webhook_id}
FieldTypeDescription
secret requiredstringWebhook secret (or send X-Kalks-Signature header instead)
action requiredenumbuy | sell | close | close_all
symbol requiredstringMust be in the webhook's allowed symbols
volumenumberSignal volume; scaled per account by its sizing rule
sl / tpnumberAbsolute prices; required for risk % sizing
commentstringDedup key within 10s, max 32 chars
Send a signal
1curl -X POST "https://hooks.kalks.com/v1/signal/wh_9f3a1c7e2b" \
2 -H "Content-Type: application/json" \
3 -d '{"secret":"whsec_EXAMPLE0…","action":"buy","symbol":"XAUUSD","volume":1.0,"sl":2638.0,"tp":2690.0,"comment":"gold-bo"}'
200 OK
1{
2 "status": "accepted",
3 "signal_id": "dlv_4a91c2",
4 "fanout": [
5 {
6 "login": "80412512",
7 "volume": 0.5,
8 "ticket": 51298861
9 },
10 {
11 "login": "80412337",
12 "volume": 0.16,
13 "ticket": 51298862
14 }
15 ],
16 "latency_ms": 42
17}
Manage webhooks
Institutional

FIX 4.4

Low-latency order entry and market data for professional systems. Sessions are provisioned per trading account; the API key id and secret are used as Username (553) and Password (554).
Host
fix.kalks.com:9880
SenderCompID (49)
KLK_80412337
TargetCompID (56)
KALKS
BeginString (8)
FIX.4.4
HeartBtInt (108)
30s
Transport
TLS 1.3 required
ResetSeqNumFlag (141)
Y
Session hours
Sun 23:05 – Fri 23:55 GMT+3
Supported message types
ALogon0Heartbeat1Test Request5LogoutDNew Order SingleFOrder Cancel RequestGOrder Cancel/Replace8Execution ReportVMarket Data RequestWMD Snapshot / Full RefreshANRequest For PositionsAPPosition Report
session.log · | = SOH (0x01)
1# Logon (35=A) — password = API secret
28=FIX.4.4|9=126|35=A|49=KLK_80412337|56=KALKS|34=1|52=20260924-14:58:12.184|98=0|108=30|141=Y|553=kk_live_EXAMPLE1|554=••••••|10=087|
3# New Order Single (35=D) — buy 0.50 lot XAUUSD at market
48=FIX.4.4|9=152|35=D|49=KLK_80412337|56=KALKS|34=2|11=gold-bo-0924-01|1=80412337|55=XAUUSD|54=1|38=50|40=1|59=3|60=20260924-14:58:12.201|10=164|
5# Execution Report (35=8) — filled
68=FIX.4.4|9=198|35=8|49=KALKS|56=KLK_80412337|34=2|37=51298844|11=gold-bo-0924-01|17=E0924-88121|150=F|39=2|55=XAUUSD|54=1|38=50|32=50|31=2654.48|14=50|6=2654.48|10=231|
Operations

Rate limits

Limits are per key unless stated. Every response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. Exceeding a limit returns 429 with Retry-After.
ScopeLimitBurstWindow
REST · read20 req/s per key401s sliding
REST · trade10 orders/s per account201s sliding
WebSocket5 connections per key——
WS subscriptions200 symbols per connection——
Webhooks5 signals / 10s per webhook1010s fixed
FIX 4.450 msg/s per session1001s sliding
Need more? Pro and ECN accounts with $50k+ equity can request up to 100 req/s and a co-located FIX session in LD4.
Operations

Errors

Errors use standard HTTP codes and a stable machine-readable name.
HTTPErrorMeaning
400bad_requestMalformed JSON or missing required field.
401unauthorizedMissing, expired or revoked API key, or bad signature.
403forbiddenKey lacks the scope (e.g. read-only key calling POST /orders) or IP not whitelisted.
404not_foundAccount, order or position does not exist or is not visible to this key.
409duplicate_client_idAn order with this client_id was already accepted.
422invalid_orderVolume, price, SL/TP or market-hours validation failed.
423kill_switch_activeTrading disabled by the key or account kill switch.
429rate_limitedToo many requests. Respect the Retry-After header.
503market_closedTrading session closed for the symbol.
422 Unprocessable Entity
1{
2 "error": {
3 "code": 422,
4 "name": "invalid_order",
5 "message": "Volume 0.001 is below the minimum lot 0.01 for XAUUSD",
6 "field": "volume",
7 "request_id": "req_7f1c20a9e4"
8 }
9}