Connect your scripts and bots to MetaScalp to interact with exchange connections. Use HTTP REST to query data and execute trades, or WebSocket to receive real-time order, position, and balance updates.
HTTP API: Host: 127.0.0.1 Ports: 17845–17855 CORS enabled for all origins.
Socket API: Host: 127.0.0.1 Same port as HTTP Endpoint: ws://127.0.0.1:{port}/
Getting started: 1. Launch MetaScalp. 2. Discover the HTTP port with GET /ping. 3. List connections with GET /api/connections. 4. Use connection IDs for REST or WebSocket operations. Full documentation
Scan ports 17845–17855 to find the running MetaScalp instance. Returns the app name and version.
Changes the current ticker. The active window is always notified. When a named binding is provided, that binding's linked panels are also updated.
Accepts two request formats: a ticker pattern string (e.g. BINANCE:BTCUSDT.p) or explicit fields (exchange + market + ticker).
A binding is a named group of linked panels inside MetaScalp (e.g. a chart, order book, and trade feed showing the same ticker). Bindings are numbered "001"–"500" and configured by the user in the MetaScalp UI.
EXCHANGE:SYMBOL.suffix — suffix: .p (futures), .m (margin), .o (options), omitted (spot)_, /, -, $, :.BINANCE:BTCUSDT.p, BYBIT:ETHUSDT, OKX:BTC-USDT.m, HYPERLIQUID:cash:HOODUSDT0.p
Opens a combo layout for the specified ticker in the MetaScalp UI.
Returns all currently active exchange connections. Use the id from the response to query orders, positions, balances, or to subscribe via WebSocket.
| Field | Type | Description |
|---|---|---|
id | integer | Connection ID — use for all exchange operations |
name | string | User-defined connection name |
exchange | string | Exchange name |
exchangeId | integer | Exchange identifier |
market | string | Market display name |
marketType | integer | Market type enum value |
state | integer | 0=Disconnected, 1=Connecting, 2=Connected, 3=Reconnecting, 4=Resetting |
viewMode | boolean | Read-only (no trading) |
demoMode | boolean | Paper trading |
Returns details for a single connection by ID.
Returns all available trading pairs on a connection with price/size precision, trading status, and constraints.
Returns open orders for a specific ticker on a connection. The Ticker query parameter is required.
| Field | Type | Description |
|---|---|---|
id | integer | Exchange order ID |
ticker | string | Trading pair |
clientId | string? | Client-generated order ID |
side | integer | 0 None, 1 Buy, 2 Sell |
price | decimal | Order price |
size | decimal | Order size |
filledSize | decimal | Filled amount |
filledPrice | decimal | Execution price (0 if not yet filled) |
remainingSize | decimal | Remaining amount |
status | integer | 0 New, 1 Open, 2 Closed |
type | integer | 0 Limit, 1 Stop, 2 StopLoss, 3 TakeProfit, 4 Market |
triggerPrice | decimal? | Trigger price for stop/conditional orders |
createDate | string (ISO) | Order creation timestamp |
Returns all open positions on a connection (futures/margin markets).
Returns account balances for all assets on a connection.
Places a new order on the exchange through a connection. Returns an auto-generated clientId for order tracking and executionTimeMs indicating how long the exchange request took (in milliseconds).
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | yes | Trading pair symbol |
side | integer | yes | 1 Buy, 2 Sell |
price | decimal | yes* | Order price (*required for non-market orders) |
size | decimal | yes | Order size (must be > 0) |
type | integer | no | 0 Limit (default), 1 Stop, 2 StopLoss, 3 TakeProfit, 4 Market |
reduceOnly | boolean | no | Close-only, default false |
Cancels an existing order on the exchange.
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | yes | Trading pair symbol |
orderId | integer | yes | Exchange order ID |
type | integer | no | Order type (default 0 Limit) |
Cancels all open orders for a given ticker on the exchange.
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | yes | Trading pair symbol |
Returns cancelledCount: 0 if there are no open orders for that ticker.
Connect via WebSocket to receive real-time updates for your exchange connections. Subscribe by connection ID for order, position, balance, and finres events. Subscribe by connection ID + ticker for real-time trade and order book market data.
The WebSocket server shares the same port as the HTTP API (17845–17855). Connect to ws://127.0.0.1:{port}/.
All messages (inbound and outbound) are JSON with this envelope:
{ "type": "message_type", "data": { ... } }
Connection-level — subscribe by connection ID for order, position, balance, and finres updates:
| Type | Data | Description |
|---|---|---|
subscribe | { "connectionId": 123 } | Subscribe to updates for a connection. Connection must be active. Idempotent. |
unsubscribe | { "connectionId": 123 } | Stop receiving updates for a connection. Idempotent. |
Market data — subscribe by connection ID + ticker for trade or order book updates:
| Type | Data | Description |
|---|---|---|
trade_subscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Subscribe to real-time trade updates for a specific ticker. Idempotent. |
trade_unsubscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Stop receiving trade updates for that ticker. Idempotent. |
orderbook_subscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Subscribe to order book updates (snapshot + incremental). Idempotent. |
orderbook_unsubscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Stop receiving order book updates for that ticker. Idempotent. |
Acknowledgements:
| Type | When | Data fields |
|---|---|---|
subscribed | After successful connection subscribe | connectionId |
unsubscribed | After successful connection unsubscribe | connectionId |
trade_subscribed | After successful trade subscribe | connectionId, ticker |
trade_unsubscribed | After successful trade unsubscribe | connectionId, ticker |
orderbook_subscribed | After successful order book subscribe | connectionId, ticker |
orderbook_unsubscribed | After successful order book unsubscribe | connectionId, ticker |
error | Invalid message, bad connection ID, or missing ticker | error (string) |
Connection-level updates:
| Type | When | Data fields |
|---|---|---|
order_update | Order created/changed/filled/cancelled | connectionId, orderId, ticker, side, type, price, filledPrice, size, filledSize, fee, feeCurrency, status, time |
position_update | Position opened/changed/closed | connectionId, positionId, ticker, side, size, avgPrice, avgPriceFix, avgPriceDyn, status |
balance_update | Account balance changed | connectionId, balances[] with coin, total, free, locked |
finres_update | Financial results updated | connectionId, finreses[] with currency, result, fee, funds, available, blocked |
Market data updates:
| Type | When | Data fields |
|---|---|---|
trade_update | New trades for subscribed ticker | connectionId, ticker, trades[] with price, size, side, time |
orderbook_snapshot | Full order book on subscribe | connectionId, ticker, asks[], bids[], bestAsk, bestBid — each with price, size, type |
orderbook_update | Incremental order book changes | connectionId, ticker, updates[] with price, size, type |
| Event | Behavior |
|---|---|
| Client connects | Session created. No updates until subscribe. |
| Subscribe (valid ID) | Server responds with subscribed. Order, position, balance, finres updates start flowing. |
| Subscribe (invalid ID) | Server responds with error. No subscription created. |
| Subscribe (already subscribed) | Idempotent — responds with confirmation, no duplicate events. |
| Trade/orderbook subscribe (valid) | Server responds with trade_subscribed / orderbook_subscribed. Market data starts flowing for that ticker. |
| Trade/orderbook subscribe (invalid) | Server responds with error (bad connection ID or missing ticker). |
| Unsubscribe | Server responds with confirmation. Updates stop for that subscription. |
| Client disconnects | All subscriptions (connection-level and market data) are cleaned up automatically. |
| Multiple connections | A single client can subscribe to multiple connection IDs and multiple tickers simultaneously. |
// Subscribe
{ "type": "subscribe", "data": { "connectionId": 1 } }
// Server confirms
{ "type": "subscribed", "data": { "connectionId": 1 } }
// Order update pushed by server
{
"type": "order_update",
"data": {
"connectionId": 1,
"orderId": 98765,
"ticker": "BTCUSDT",
"side": "Buy",
"type": "Limit",
"price": 65000.0,
"filledPrice": 64980.5,
"size": 0.01,
"filledSize": 0.0,
"fee": 0.0013,
"feeCurrency": "USDT",
"status": "New",
"time": "2025-03-24T14:30:00+00:00"
}
}
// Position update pushed by server
{
"type": "position_update",
"data": {
"connectionId": 1,
"positionId": 4321,
"ticker": "ETHUSDT",
"side": "Buy",
"size": 1.5,
"avgPrice": 3200.00,
"avgPriceFix": 3200.00,
"avgPriceDyn": 3195.50,
"status": "Open"
}
}
// Balance update pushed by server
{
"type": "balance_update",
"data": {
"connectionId": 1,
"balances": [
{ "coin": "USDT", "total": 10000.0, "free": 8500.0, "locked": 1500.0 },
{ "coin": "BTC", "total": 0.5, "free": 0.5, "locked": 0.0 }
]
}
}
// FinRes update pushed by server
{
"type": "finres_update",
"data": {
"connectionId": 1,
"finreses": [
{ "currency": "USDT", "result": 250.50, "fee": 12.30, "funds": 10000.0, "available": 8500.0, "blocked": 1500.0 },
{ "currency": "BTC", "result": 0.005, "fee": 0.0001, "funds": 0.5, "available": 0.5, "blocked": 0.0 }
]
}
}
// Subscribe to trades for a specific ticker
{ "type": "trade_subscribe", "data": { "connectionId": 1, "ticker": "BTCUSDT" } }
// Server confirms trade subscription
{ "type": "trade_subscribed", "data": { "connectionId": 1, "ticker": "BTCUSDT" } }
// Trade update pushed by server
{
"type": "trade_update",
"data": {
"connectionId": 1,
"ticker": "BTCUSDT",
"trades": [
{ "price": 65123.50, "size": 0.15, "side": "Buy", "time": "2026-03-16T12:00:01.234+00:00" },
{ "price": 65123.00, "size": 0.03, "side": "Sell", "time": "2026-03-16T12:00:01.235+00:00" }
]
}
}
// Subscribe to order book for a specific ticker
{ "type": "orderbook_subscribe", "data": { "connectionId": 1, "ticker": "BTCUSDT" } }
// Server confirms order book subscription
{ "type": "orderbook_subscribed", "data": { "connectionId": 1, "ticker": "BTCUSDT" } }
// Order book snapshot (full state, sent once on subscribe)
{
"type": "orderbook_snapshot",
"data": {
"connectionId": 1,
"ticker": "BTCUSDT",
"asks": [
{ "price": 65124.00, "size": 1.20, "type": "Ask" },
{ "price": 65125.00, "size": 0.85, "type": "Ask" }
],
"bids": [
{ "price": 65123.00, "size": 2.50, "type": "Bid" },
{ "price": 65122.00, "size": 1.10, "type": "Bid" }
],
"bestAsk": { "price": 65124.00, "size": 1.20, "type": "BestAsk" },
"bestBid": { "price": 65123.00, "size": 2.50, "type": "BestBid" }
}
}
// Order book incremental update
{
"type": "orderbook_update",
"data": {
"connectionId": 1,
"ticker": "BTCUSDT",
"updates": [
{ "price": 65124.00, "size": 0.90, "type": "Ask" },
{ "price": 65126.00, "size": 0.50, "type": "Ask" },
{ "price": 65123.00, "size": 2.80, "type": "Bid" }
]
}
}
// Unsubscribe from market data
{ "type": "trade_unsubscribe", "data": { "connectionId": 1, "ticker": "BTCUSDT" } }
{ "type": "orderbook_unsubscribe", "data": { "connectionId": 1, "ticker": "BTCUSDT" } }
// Unsubscribe from connection
{ "type": "unsubscribe", "data": { "connectionId": 1 } }
// Error (invalid connection)
{ "type": "error", "data": { "error": "Connection 999 not found or not active" } }
| Value | Exchange |
|---|---|
| 2 | Binance |
| 3 | Gate |
| 5 | KuCoin |
| 6 | Bybit |
| 7 | Bitget |
| 8 | Mexc |
| 10 | Okx |
| 11 | BingX |
| 12 | HTX |
| 13 | BitMart |
| 14 | LBank |
| 15 | HyperLiquid |
| 16 | UpBit |
| 17 | AsterDex |
| 18 | Moex |
| 19 | Lighter |
| Value | Type | Description |
|---|---|---|
| 0 | Spot | Spot trading |
| 1 | Futures | Generic futures |
| 2 | UsdtFutures | USDT-margined futures |
| 3 | CoinFutures | Coin-margined futures |
| 4 | InverseFutures | Inverse futures |
| 5 | UsdtPerpetual | USDT perpetual swaps |
| 6 | UsdcPerpetual | USDC perpetual swaps |
| 7 | Margin | Margin (cross/isolated) |
| 8 | Options | Options contracts |
| 9 | Stock | Stock / equity markets |
.p suffix auto-resolves to the right futures type. For explicit fields, 2 (UsdtFutures) is the most common choice for perpetual futures.Errors return HTTP 400 or 404 with a JSON body.
| Endpoint | Condition | HTTP | Error message |
|---|---|---|---|
/api/change-ticker | Missing fields | 400 | Invalid request body. Provide 'tickerPattern' or 'exchange'+'market'+'ticker'. |
/api/change-ticker | Invalid pattern | 400 | Invalid ticker pattern: '{pattern}' |
/api/change-ticker | Binding not found | 400 | Binding '{name}' not found. Available: {list} |
/api/change-ticker | No connection | 400 | No connection found for exchange ... and market ... |
/api/change-ticker | Ticker not on connection | 400 | Ticker '{ticker}' not found on connection {id} |
/api/combo | Missing ticker | 400 | Invalid request body. 'ticker' is required. |
/api/connections/{id} | Connection not found | 404 | Connection {id} not found |
/api/connections/{id}/... | Invalid connection ID | 400 | Invalid connection ID |
/api/connections/{id}/... | Connection not found | 404 | Connection {id} not found |
/api/connections/{id}/... | Connection not active | 400 | Connection {id} is not active |
/api/connections/{id}/orders | Missing ticker query param | 400 | Query parameter 'Ticker' is required |
/api/connections/{id}/orders | Invalid order fields | 400 | Invalid request body. 'ticker', 'side', 'price', and 'size' are required. |
/api/connections/{id}/orders | Size <= 0 | 400 | Size must be greater than zero |
/api/connections/{id}/orders | Price <= 0 (non-market) | 400 | Price must be greater than zero for non-market orders |
/api/connections/{id}/orders/cancel | Missing fields | 400 | Invalid request body. 'ticker' and 'orderId' are required. |
/api/connections/{id}/orders/cancel-all | Missing ticker | 400 | Invalid request body. 'ticker' is required. |
| any | Unknown path | 400 | Not found |
| any | Wrong HTTP method | 400 | Method not allowed |
Socket errors are sent as { "type": "error", "data": { "error": "..." } }
| Condition | Error message |
|---|---|
| Subscribe to non-existent connection | Connection {id} not found or not active |
| Trade/orderbook subscribe with missing ticker | Ticker is required for trade subscription / Ticker is required for order book subscription |
| Trade/orderbook subscribe with invalid connection | Connection {id} not found or not active |
| Unknown message type | Unknown message type: {type} |
| Invalid JSON | Invalid message format |
MetaScalp exposes a local API that lets your scripts and bots interact with connected exchanges. Use HTTP REST endpoints for request/response operations and WebSocket for real-time streaming of orders, positions, balances, trades, and order book data.
127.0.0.1 (localhost only)17845–17855 (first available)application/jsonAccess-Control-Allow-Origin: *.Use HTTP to discover connections, query data, and execute trades:
| Endpoint | Purpose |
|---|---|
GET /ping | Find the running MetaScalp instance and check its version |
POST /api/change-ticker | Switch the active ticker in the MetaScalp UI |
POST /api/combo | Open a combo layout for a ticker |
GET /api/connections | List all active exchange connections |
GET /api/connections/{id}/... | Query tickers, orders, positions, balances for a connection |
POST /api/connections/{id}/orders | Place an order on a connection |
POST /api/connections/{id}/orders/cancel | Cancel a single order |
POST /api/connections/{id}/orders/cancel-all | Cancel all orders for a ticker |
Connect via WebSocket to receive real-time updates for your exchange connections.
ws://127.0.0.1:{port}/ (same port as HTTP — scan 17845–17855)subscribe with a connection ID to receive order, position, balance, and finres updatestrade_subscribe or orderbook_subscribe with connection ID + ticker to receive trade or order book updates1. Launch MetaScalp — both HTTP and WebSocket servers start automatically.
2. Discover the port — scan 17845–17855 with GET /ping.
3. List connections — call GET /api/connections to see available exchange connections.
4. Execute operations — use a connection ID for REST queries or WebSocket subscriptions.
GET /ping → find MetaScalp
GET /api/connections → list active connections
GET /api/connections/{id}/tickers → get available tickers
GET /api/connections/{id}/balance → check balances
GET /api/connections/{id}/orders?Ticker=BTCUSDT → view open orders
POST /api/connections/{id}/orders → place an order
POST /api/connections/{id}/orders/cancel → cancel an order
POST /api/connections/{id}/orders/cancel-all → cancel all orders for a ticker
1. Connect
ws = new WebSocket("ws://127.0.0.1:17845/")
2. Subscribe to a connection (orders, positions, balances, finres)
ws.send('{"type":"subscribe","data":{"connectionId":1}}')
← {"type":"subscribed","data":{"connectionId":1}}
3. Subscribe to market data for a specific ticker
ws.send('{"type":"trade_subscribe","data":{"connectionId":1,"ticker":"BTCUSDT"}}')
← {"type":"trade_subscribed","data":{"connectionId":1,"ticker":"BTCUSDT"}}
ws.send('{"type":"orderbook_subscribe","data":{"connectionId":1,"ticker":"BTCUSDT"}}')
← {"type":"orderbook_subscribed","data":{"connectionId":1,"ticker":"BTCUSDT"}}
4. Receive real-time updates
← {"type":"order_update","data":{"connectionId":1,"orderId":123,...}}
← {"type":"position_update","data":{"connectionId":1,...}}
← {"type":"balance_update","data":{"connectionId":1,"balances":[...]}}
← {"type":"finres_update","data":{"connectionId":1,"finreses":[...]}}
← {"type":"trade_update","data":{"connectionId":1,"ticker":"BTCUSDT","trades":[...]}}
← {"type":"orderbook_snapshot","data":{"connectionId":1,"ticker":"BTCUSDT","asks":[...],"bids":[...],...}}
← {"type":"orderbook_update","data":{"connectionId":1,"ticker":"BTCUSDT","updates":[...]}}
5. Unsubscribe when done
ws.send('{"type":"trade_unsubscribe","data":{"connectionId":1,"ticker":"BTCUSDT"}}')
ws.send('{"type":"orderbook_unsubscribe","data":{"connectionId":1,"ticker":"BTCUSDT"}}')
ws.send('{"type":"unsubscribe","data":{"connectionId":1}}')
← {"type":"unsubscribed","data":{"connectionId":1}}
| Type | Data | Description |
|---|---|---|
subscribe | { "connectionId": 123 } | Start receiving order, position, balance, finres updates for a connection. |
unsubscribe | { "connectionId": 123 } | Stop receiving connection-level updates. |
trade_subscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Start receiving trade updates for a specific ticker. |
trade_unsubscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Stop receiving trade updates for that ticker. |
orderbook_subscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Start receiving order book snapshot + incremental updates for a specific ticker. |
orderbook_unsubscribe | { "connectionId": 123, "ticker": "BTCUSDT" } | Stop receiving order book updates for that ticker. |
| Type | Data fields |
|---|---|
subscribed | connectionId |
unsubscribed | connectionId |
trade_subscribed | connectionId, ticker |
trade_unsubscribed | connectionId, ticker |
orderbook_subscribed | connectionId, ticker |
orderbook_unsubscribed | connectionId, ticker |
order_update | connectionId, orderId, ticker, side, type, price, filledPrice, size, filledSize, fee, feeCurrency, status, time |
position_update | connectionId, positionId, ticker, side, size, avgPrice, avgPriceFix, avgPriceDyn, status |
balance_update | connectionId, balances[]: coin, total, free, locked |
finres_update | connectionId, finreses[]: currency, result, fee, funds, available, blocked |
trade_update | connectionId, ticker, trades[]: price, size, side, time |
orderbook_snapshot | connectionId, ticker, asks[], bids[], bestAsk, bestBid — each: price, size, type |
orderbook_update | connectionId, ticker, updates[]: price, size, type |
error | error (string message) |
For complete endpoint documentation with request/response details, field descriptions, and integration examples, see the interactive panels above or download the Markdown file.