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

  1. Connect an account in Cloud (TJP Cloud).
  2. 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.
  3. 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

MethodPathWhat it does
GET/v1/accountsAccounts the key can use, with terminal state
GET/v1/accounts/{id}Account, connection and live balance/equity/margin
GET/v1/accounts/{id}/positionsOpen 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}/rulesBreakeven, trailing stop, partial take-profits (run in the terminal, MT5)
GET/v1/accounts/{id}/rulesProtection rules running in the terminal
DELETE/v1/accounts/{id}/positions/{ticket}/rulesRemove a position's rules
GET/v1/accounts/{id}/ordersPending orders
POST/v1/accounts/{id}/ordersMarket, 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/ordersOne order on up to 50 accounts
GET/v1/accounts/{id}/symbolsAll 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.ts and run TJP_API_KEY=… npx tsx tjp-mcp.ts. It is read-only unless you set TJP_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.