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.
| Header | Value | Notes |
|---|---|---|
| X-KALKS-KEY | kk_live_EXAMPLE1 | Public key id from API keys page |
| X-KALKS-TIMESTAMP | 1790261892184 | Unix ms; rejected if more than 5s from server time |
| X-KALKS-SIGNATURE | hex(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) |
| 2 | TS=$(date +%s%N) |
| 3 | SIG=$(printf "%s" "$TS""GET""/v1/accounts" \ |
| 4 | | openssl dgst -sha256 -hmac "$KALKS_SECRET" | cut -d' ' -f2) |
| 5 | |
| 6 | curl "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.
| Parameter | In | Type | Description |
|---|---|---|---|
| type | query | string | Filter by live or demo |
Request
| 1 | curl -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
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.
| Parameter | In | Type | Description |
|---|---|---|---|
| loginrequired | path | string | Trading account login, e.g. 80412337 |
Request
| 1 | curl -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
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.
| Parameter | In | Type | Description |
|---|---|---|---|
| loginrequired | body | string | Target trading account |
| symbolrequired | body | string | Instrument, e.g. XAUUSD |
| siderequired | body | enum | buy | sell |
| typerequired | body | enum | market | limit | stop |
| volumerequired | body | number | Lots, min 0.01, step 0.01 |
| price | body | number | Required for limit / stop |
| sl | body | number | Stop loss price |
| tp | body | number | Take profit price |
| client_id | body | string | Idempotency key, max 64 chars |
Request
| 1 | curl -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
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.
| Parameter | In | Type | Description |
|---|---|---|---|
| idrequired | path | string | Order id returned by POST /orders |
Request
| 1 | curl -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
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.
| Parameter | In | Type | Description |
|---|---|---|---|
| login | query | string | Account login |
| symbol | query | string | Instrument filter |
Request
| 1 | curl -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
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.
| Parameter | In | Type | Description |
|---|---|---|---|
| ticketrequired | path | integer | Position ticket |
| volume | query | number | Partial close volume |
Request
| 1 | curl -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
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
| 1 | wscat -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
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}
| Field | Type | Description |
|---|---|---|
| secret required | string | Webhook secret (or send X-Kalks-Signature header instead) |
| action required | enum | buy | sell | close | close_all |
| symbol required | string | Must be in the webhook's allowed symbols |
| volume | number | Signal volume; scaled per account by its sizing rule |
| sl / tp | number | Absolute prices; required for risk % sizing |
| comment | string | Dedup key within 10s, max 32 chars |
Send a signal
| 1 | curl -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
JSON| 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 | } |
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)
FIX 4.4| 1 | # Logon (35=A) — password = API secret |
| 2 | 8=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 |
| 4 | 8=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 |
| 6 | 8=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.
| Scope | Limit | Burst | Window |
|---|---|---|---|
| REST · read | 20 req/s per key | 40 | 1s sliding |
| REST · trade | 10 orders/s per account | 20 | 1s sliding |
| WebSocket | 5 connections per key | — | — |
| WS subscriptions | 200 symbols per connection | — | — |
| Webhooks | 5 signals / 10s per webhook | 10 | 10s fixed |
| FIX 4.4 | 50 msg/s per session | 100 | 1s 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.
| HTTP | Error | Meaning |
|---|---|---|
| 400 | bad_request | Malformed JSON or missing required field. |
| 401 | unauthorized | Missing, expired or revoked API key, or bad signature. |
| 403 | forbidden | Key lacks the scope (e.g. read-only key calling POST /orders) or IP not whitelisted. |
| 404 | not_found | Account, order or position does not exist or is not visible to this key. |
| 409 | duplicate_client_id | An order with this client_id was already accepted. |
| 422 | invalid_order | Volume, price, SL/TP or market-hours validation failed. |
| 423 | kill_switch_active | Trading disabled by the key or account kill switch. |
| 429 | rate_limited | Too many requests. Respect the Retry-After header. |
| 503 | market_closed | Trading session closed for the symbol. |
422 Unprocessable Entity
JSON| 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 | } |