TJP Cloud · Developer API · beta
TJP Cloud API reference
Read and trade your TJP Cloud MetaTrader 5 accounts from your own code: REST for data and trading, a WebSocket stream for live prices and fills, and signed webhooks. Base URL https://api.tradejournalpro.net. Machine-readable spec: openapi.json.
Quick start
- Connect an account in Cloud (TJP Cloud).
- Create a key in TJP Cloud API. Keys start with
tjpc_live_and are shown once. Start read-only; allow trading only for programs that need it. - Call the API with the key as a bearer token:
curl -H "Authorization: Bearer $TJP_API_KEY" https://api.tradejournalpro.net/v1/accounts
curl -X POST https://api.tradejournalpro.net/v1/accounts/$ACCOUNT/orders \
-H "Authorization: Bearer $TJP_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: my-bot-order-0001" \
-d '{"side":"buy","symbol":"EURUSD","volume":0.1,"stopLoss":1.08,"takeProfit":1.09,"clientOrderId":"bot-1"}'Never trade twice: Idempotency-Key
Every write (POST, PUT, PATCH and DELETE) needs an Idempotency-Key header (8–200 letters, digits, _ . : -), unique for each action you intend. If you resend the same request with the same key, you get the first answer again (header Idempotent-Replayed: true) and nothing is sent to the broker twice. Keys are remembered for 24 hours.
A 503 with "uncertain": true (or a network error on a write) means the broker may have executed the request. Check positions, or retry with the same key — never a new one.
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /v1/accounts | Accounts the key can use, with terminal state |
| GET | /v1/accounts/{id} | Account, connection and live balance/equity/margin |
| GET | /v1/accounts/{id}/positions | Open positions |
| DELETE | /v1/accounts/{id}/positions?symbol=&side= | Close every matching position |
| PATCH | /v1/accounts/{id}/positions/{ticket} | Change stop loss / take profit (null removes) |
| DELETE | /v1/accounts/{id}/positions/{ticket} | Close; body {"volume"} closes part |
| PUT | /v1/accounts/{id}/positions/{ticket}/rules | Breakeven, trailing stop, partial take-profits (run in the terminal, MT5) |
| GET | /v1/accounts/{id}/rules | Protection rules running in the terminal |
| DELETE | /v1/accounts/{id}/positions/{ticket}/rules | Remove a position's rules |
| GET | /v1/accounts/{id}/orders | Pending orders |
| POST | /v1/accounts/{id}/orders | Market, limit or stop order |
| PATCH | /v1/accounts/{id}/orders/{ticket} | Move price, SL/TP or expiry |
| DELETE | /v1/accounts/{id}/orders/{ticket} | Cancel a pending order |
| POST | /v1/bulk/orders | One order on up to 50 accounts |
| GET | /v1/accounts/{id}/symbols | All broker symbols |
| GET | /v1/accounts/{id}/symbols/{symbol} | Tick size/value, contract size, volume limits |
| GET | /v1/accounts/{id}/quotes/{symbol} | Bid and ask |
| GET | /v1/accounts/{id}/candles?symbol=&timeframe=&count= | Bars M1…MN1 (or from/to) |
| GET | /v1/accounts/{id}/deals?from=&to= | Deals, at most 93 days per call |
| GET | /v1/accounts/{id}/history-orders?from=&to= | Finished orders |
Order body: side (buy/sell), type (market/limit/stop), symbol, volume, price (pending), stopLoss, takeProfit, expiresAt (ISO-8601, pending), clientOrderId (≤31 chars, stored as the order comment). Tickets are strings. Times are UTC ISO-8601.
Protection rules (in the terminal)
Give a position a breakeven, a trailing stop and up to five partial take-profits. The MetaTrader 5 terminal applies them itself on every price change, so they keep working even if our servers or your program are offline. Points are the symbol's point size (for EURUSD with 5 digits, 10 points = 1 pip). Rules end when the position closes.
curl -X PUT https://api.tradejournalpro.net/v1/accounts/$ACCOUNT/positions/123456/rules \
-H "Authorization: Bearer $TJP_API_KEY" -H "Content-Type: application/json" -H "Idempotency-Key: rules-123456-v1" \
-d '{"breakeven":{"triggerPoints":150,"offsetPoints":10},"trailing":{"startPoints":200,"distancePoints":120,"stepPoints":20},"takeProfits":[{"price":1.0950,"volume":0.05},{"price":1.1000}]}'Errors
Errors look like {"error":{"code":"BROKER_REJECTED","message":"Invalid stops","retcode":10016}}.
400— Invalid request. Nothing was sent to the broker.401— Missing, invalid or revoked key.403— Read-only key used for trading, or LIVE_TRADING_DISABLED: during the beta only demo accounts can open new orders.404— Unknown account, ticket or symbol. Accounts your key may not use also look missing.409— The terminal is offline (nothing was sent; retrying with the same key is safe), or the same Idempotency-Key is still running.422— The broker refused it: see error.retcode (MetaTrader trade server code). Or the Idempotency-Key was reused for a different request.429— Rate limit. Wait for Retry-After seconds.501— Not available on this account's platform (protection rules are MT5 only).503— uncertain: true — the broker may have executed it. Check positions; retry only with the same Idempotency-Key. Without uncertain: data not loaded yet, retry shortly.
Limits per key: bursts of 100 reads (30/s sustained) and 20 writes (5/s sustained). A bulk call costs one write per five accounts.
Live stream (WebSocket)
Connect to wss://api.tradejournalpro.net/v1/stream with the bearer header (or ?token= in browsers — use a read-only key there), then subscribe per account. Channels: ticks (with symbols), trades (deals, position changes, pending orders), account (balance/equity) and status (terminal online/offline, broker login).
const ws = new WebSocket("wss://api.tradejournalpro.net/v1/stream?token=" + key);
ws.onopen = () => ws.send(JSON.stringify({ type: "subscribe", accountId, channels: ["ticks", "trades", "status"], symbols: ["EURUSD", "XAUUSD"] }));
ws.onmessage = event => console.log(JSON.parse(event.data)); // {type:"tick",symbol,bid,ask,time} · {type:"trade",deal} · {type:"position",position,closed}Webhooks
Add an https endpoint in TJP Cloud API and choose events: trade, position, order, account, broker, status. Each delivery is a POST of {"id","type","accountId","createdAt","data"} with X-TJP-Signature: t=<unix>,v1=<hex>, where v1 is HMAC-SHA256 of t + "." + raw body with your signing secret. Reject deliveries older than five minutes. Failed deliveries are retried three times; an endpoint that keeps failing is switched off. X-TJP-Event-Id is the same on retries, so you can ignore duplicates.
import { verifyWebhook } from "./tjpcloud"; // Node / TypeScript
const ok = await verifyWebhook(secret, rawBody, req.headers["x-tjp-signature"]);
from tjpcloud import verify_webhook # Python
ok = verify_webhook(secret, raw_body, request.headers["X-TJP-Signature"])SDKs and MCP
- TypeScript / JavaScript (Node 18+, browsers, no dependencies): tjpcloud.ts —
new TjpCloud({ apiKey }).placeOrder(accountId, { side: "buy", symbol: "EURUSD", volume: 0.1 }) - Python 3.9+ (standard library only): tjpcloud.py —
TjpCloud(api_key=…).place_order(account_id, side="buy", symbol="EURUSD", volume=0.1) - MCP server for AI assistants (Claude and others): download tjp-mcp.ts next to
tjpcloud.tsand runTJP_API_KEY=… npx tsx tjp-mcp.ts. It is read-only unless you setTJP_MCP_ALLOW_TRADING=1; use a read-only key unless the assistant should trade.
{ "mcpServers": { "tjp-cloud": { "command": "npx", "args": ["tsx", "/path/to/tjp-mcp.ts"], "env": { "TJP_API_KEY": "tjpc_live_…" } } } }Service health: status page. The API is in beta; during the beta only demo accounts can open trades. Trading involves risk.