API reference
Every Algo Trading Bots endpoint — user and admin — with the permission each admin route gates on, the WebSocket subscription contract, and the response conventions that catch integrators out.
Two API surfaces. Everything under /api/trading-bot is scoped to the calling
user and carries no permission — it is gated by KYC features instead. Everything
under /api/admin/trading-bot carries an explicit permission.
Conventions that will catch you out
The platform pins the HTTP status at 200 and puts the real outcome in the body. Read the body, always. A kill switch that stopped nothing returns a body saying so; a client that branches on the status code will render it as a green toast over a fleet that is still trading.
Amounts are DECIMAL columns and arrive as strings in raw form. Every
serialised endpoint converts them, but if you query the tables directly, coerce
before arithmetic — "1" + 1 is "11".
strategyConfig is a JSON column. MySQL returns it pre-parsed and MariaDB returns
a raw string; the backend normalises both, but a direct database consumer must
handle either.
User endpoints
Bots
POST /api/trading-bot/bot requires name, symbol and type. mode defaults
to PAPER. Everything else is optional and falls back to the operator's configured
defaults.
The update path copies an explicit whitelist, key by key. Passing usedAmount,
mode, status, totalProfit or userId in the body does nothing — an earlier
build wrote them straight to the row, which let a caller zero their committed
capital after live losses and free the whole allocation for withdrawal.
Positions, trades and orders
Allocation
Both mutations row-lock the bot and write an audit entry. Neither moves money — an allocation is a cap.
Markets and strategies
markets returns BASE/QUOTE symbols — the form every downstream consumer
expects. A market whose price cannot be resolved is still returned, with a null
price.
Paper trading
Accounts are per user and per currency.
Marketplace
Sorting on the browse endpoint accepts purchaseCount, totalPurchases,
avgRating, price and createdAt. Anything else falls back to totalPurchases
rather than producing an unknown-column error.
KYC gates on user routes
| Feature | Guards |
|---|---|
view_trading_bot |
GET /api/trading-bot, /bot, /markets, /marketplace |
trade_bot_live |
Creating, starting or resuming a live bot; deploying one from a strategy |
buy_bot_strategy |
Purchasing |
become_bot_seller |
Submitting for review |
Admin endpoints
WebSocket
Connect to /api/trading-bot and use the platform's generic subscription frames.
{ "action": "SUBSCRIBE", "payload": { "channel": "bot", "botId": "…", "userId": "…" } }{ "action": "SUBSCRIBE", "payload": { "channel": "bots", "userId": "…" } }UNSUBSCRIBE takes the identical payload.
Broadcasts are matched by serialising the payload, so the key order above is part of the contract. Hand-writing a subscription object with the keys in a different order produces a socket that connects, subscribes without error, and then receives nothing at all.
userId is required and load-bearing for security. The platform registers the
subscription key before the route handler runs and rejects any payload whose
userId is not the session's own, and every broadcast is addressed with the bot
owner's id — so a subscription forged with someone else's botId can never
match a broadcast.
Streams
| Stream | Channel | Carries |
|---|---|---|
bot_tick |
bot |
Heartbeat: price, whether it traded, the signal or error. Fires every engine interval |
bot_trade |
bot |
A trade opened or closed |
bot_order |
bot |
An order placed, filled or cancelled |
| status change | bot and bots |
A lifecycle transition |
On the worker-thread backend entry, a broadcast raised by the engine on the main
thread does not reach a socket held by a worker. The Bot Terminal also polls
chart-state every 15 seconds, which is what keeps it correct on those
deployments. Build any integration the same way: treat the socket as an
accelerator, not as the source of truth.
Tables
If you read the database directly:
| Table | Holds |
|---|---|
trading_bot |
The bots. Soft-deleted (paranoid), so filter deletedAt |
trading_bot_trade |
Positions, with cost, fee, profit and closedAt |
trading_bot_order |
Orders — PENDING, OPEN, PARTIAL, FILLED, CANCELLED, EXPIRED, FAILED |
trading_bot_stats |
One row per bot per day, with an isPaper flag |
trading_bot_paper_account |
Per user and currency |
trading_bot_strategy |
Listings, with gross, seller and platform revenue columns |
trading_bot_purchase |
Sales, with the fee rate charged and a config snapshot |
trading_bot_strategy_review |
Reviews and their moderation status |
trading_bot_audit_log |
The trail. Pruned after 90 days |