Skip to Content
cTrader MarketsAPI Reference

API Reference

All /v1/* routes require an X-API-Key header matching API_KEY. Health routes are unauthenticated.

Endpoints

MethodPathPurpose
GET/v1/stream/ticks?symbols=EURUSD,XAUUSDSSE stream of live bid/ask. symbols optional; omit for all.
GET/v1/market-data/tick?symbol=EURUSDLatest cached quote.
GET/v1/market-data/candles?symbol=EURUSD&timeframe=H1&count=200Closed trendbars.
GET/v1/symbolsResolved catalog: symbolId, digits, enabled.
GET/health/liveProcess is up.
GET/health/ready200 when connected and ticks are fresh, else 503 with details.

SSE ticks

curl -N -H 'X-API-Key: …' 'localhost:8010/v1/stream/ticks?symbols=EURUSD' event: tick data: {"symbol":"EURUSD","bid":1.08532,"ask":1.08545,"spread":0.00013,"ts":"…Z","provider":"ctrader"}

The stream replays the last known tick for each requested symbol on connect, so a client joining mid-session does not wait for the next quote on a quiet instrument. It also emits status events on connection state changes, carrying a dropped counter — see Architecture.

Candle shape

GET /v1/market-data/candles returns candles stamped at the END of their UTC interval, matching lookup-trader’s app/providers/base.py::Candle field for field:

{"ts": "2026-08-08T14:00:00Z", "open": 1.0853, "high": 1.0861, "low": 1.0849, "close": 1.0857, "volume": 4210.0, "provider": "ctrader", "source_instrument": "EURUSD", "spread": null, "spread_source": null}

cTrader sends utcTimestampInMinutes as the interval start; the conversion happens server-side in decode.py. Only closed bars are returned — the currently-forming bar is dropped.

/health/ready returns 503 until the broker session is connected and a quote has arrived within TICK_STALENESS_SECONDS. Over a market close it can stay ready with "reason": "no quotes received yet" — no ticks is normal there; only staleness after quotes have been flowing is a fault.

Last updated on