Documentation

API Quick Start

Get up and running with the Trading Platform API in under 10 minutes. This guide covers authentication, your first request, and response handling.

🔑

Prerequisites

You need a Trading Platform account with API access enabled. Go to Settings → API Keys to generate your API keys.

Base URL

Every path sits under /api/v1. The platform is pre-launch and the API is not publicly hosted yet. The SDKs default to https://api.binarysword.com/api/v1, the production address the API's OpenAPI spec names, but that host does not answer yet. The examples on this page use that address.


Authentication

The Trading Platform API uses API keys for authentication. Every request must include your API key in the headers.

Getting Your API Keys

  1. Log into your Trading Platform account
  2. Navigate to Settings → API Keys
  3. Click Create API Key
  4. Tick Read and Write per resource. A new key starts with Accounts and Market Data read only:
    • Trading → Read - list orders, positions and trade history
    • Trading → Write - place, modify and cancel orders; move stops and close positions
    • Orders, Positions, History, Webhooks - the same access for one resource only
    • Finance, AI Agents, Position Insights, Shared Charts - the finance tracker, AI arena, position intelligence and chart share routes; Trading grants none of them
  5. Copy and securely store your API key. It starts with tp_live_
🔐

Security Warning

Your API key is only shown once. Store it securely. Never commit API keys to version control or share them publicly.

Authentication Header

Send your API key in one header on every request:

X-API-Key: tp_live_your_api_key

An app acting for another user sends an OAuth access token instead, as Authorization: Bearer <token>. When a request carries both, the API reads the token. There is no request signature to compute.


Your First Request

List the broker accounts you linked in the app. A new key can make this call, so a 200 confirms your authentication works.

List Your Accounts

curl -X GET "https://api.binarysword.com/api/v1/accounts" \
  -H "X-API-Key: tp_live_your_api_key"

Successful Response

{
  "success": true,
  "data": [
    {
      "id": "6d1c8b7e-2a3f-4e5d-9c8b-7a6f5e4d3c01",
      "name": "Demo MT5",
      "broker": "Example Markets",
      "brokerType": "mt5",
      "accountNumber": "10000001",
      "server": "ExampleMarkets-Demo",
      "purpose": "trading",
      "isDemo": true,
      "currency": "USD",
      "balance": 10000,
      "equity": 10250.5,
      "margin": 500,
      "freeMargin": 9750.5,
      "marginLevel": 2050.1,
      "leverage": 100,
      "status": "connected",
      "liveDataUpdatedAt": "2026-09-26T01:30:00.000Z",
      "lastSyncAt": "2026-09-26T01:25:00.000Z",
      "createdAt": "2026-09-01T09:00:00.000Z",
      "updatedAt": "2026-09-26T01:25:00.000Z"
    }
  ],
  "meta": {
    "timestamp": "2026-09-26T01:30:00.412Z",
    "request_id": "req_3f9a1c7e5b2d8f0a6c4e1b9d",
    "version": "1.0.0"
  },
  "error": null
}

data is empty until you link a broker account. Each account's id is the accountId an order takes; API Endpoints describes every field.


Response Format

Every response carries success, data and error. A success also carries meta; an error sets data to null.

Success Response

{
  "success": true,
  "data": { ... },
  "meta": {
    "timestamp": "2026-09-26T01:30:00.412Z",
    "request_id": "req_3f9a1c7e5b2d8f0a6c4e1b9d",
    "version": "1.0.0"
  },
  "error": null
}

request_id is also sent as the X-Request-ID response header. Send your own X-Request-ID and the API uses it instead of generating one.

Error Response

{
  "success": false,
  "data": null,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication required",
    "request_id": "string"
  }
}

Common Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401API key or token missing, unknown, expired or revoked, or used from outside the key's IP allowlist
INSUFFICIENT_SCOPE403Key or token lacks the scope this call needs; details.required_any_of lists the scopes that pass
VALIDATION_ERROR400The request body or query failed validation
NOT_FOUND404No route at this method and path
ACCOUNT_NOT_FOUND404An order named an account you did not link, a colleague's included
ACCOUNT_PURPOSE_RESTRICTED403The order's account is not classified for trading
LIVE_ACCOUNT_RESTRICTED403The order's account is live; this API trades demo only

Rate Limiting

The API rate-limits every request made with a key or token. Each API key has its own limits; an OAuth token shares them per application and user. Your plan sets the tier for all of them:

TierRequests/minBurstRequests/day
Free10020010,000
Pro1,0002,000100,000
Enterprise10,00020,0001,000,000

The burst sits on top of the per-minute limit: an idle key can send both at once, and the bucket refills at the per-minute rate. Four endpoints also have a limit of their own: GET /quotes/:symbol 1,000 a minute, POST /orders 100 a minute, GET /candles/:symbol 200 a minute and GET /trades/export 10 an hour. Requests without a key, such as GET /symbols, are not limited.

Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds) for the tighter limit. A refused request gets 429 RATE_LIMIT_EXCEEDED with a Retry-After header; error.details.scope says whether the tier, the endpoint or a suspension refused it. A key refused 10 times within 5 minutes is suspended for 15 minutes, and the account owner gets an email. Wait for Retry-After before you retry: retrying sooner counts toward a suspension.


SDKs

The TypeScript and Python SDKs call the same endpoints. They send your key on every request and return each response's data as typed objects.

⚠️

Not published yet

Neither SDK is on npm or PyPI yet. Do not install a package with either name below from those registries. Until we publish them, call the REST API directly as shown above.

LanguagePackageImport
TypeScript / JavaScript@trading-platform/sdkimport { TradingClient } from "@trading-platform/sdk"
Python 3.9+trading-platform-sdkfrom trading_platform import TradingClient

Pass your API key as apiKey (api_key in Python), or an OAuth access token as accessToken (access_token). The base URL defaults to https://api.binarysword.com/api/v1, which does not answer yet: the API is not publicly hosted.

The examples below list your accounts, then place a market order on a demo trading account. Placing an order needs Trading → Write or Orders → Write on the key; a new key answers 403 INSUFFICIENT_SCOPE.

TypeScript

import { TradingClient } from "@trading-platform/sdk";

const client = new TradingClient({
  apiKey: process.env.TRADING_PLATFORM_API_KEY,
});

// The broker accounts you linked
const accounts = await client.accounts.list();
for (const account of accounts) {
  console.log(account.name, account.balance, account.currency);
}

// A market order on a demo trading account
const demo = accounts.find((a) => a.purpose === "trading" && a.isDemo);
if (demo) {
  const order = await client.orders.create({
    accountId: demo.id,
    symbol: "EURUSD",
    side: "buy",
    volume: 0.1,
    stopLoss: 1.095,
    takeProfit: 1.11,
  });
  console.log(order.id, order.status); // "pending" until the broker answers
}

Python

import os

from trading_platform import TradingClient

with TradingClient(api_key=os.environ["TRADING_PLATFORM_API_KEY"]) as client:
    # The broker accounts you linked
    accounts = client.accounts.list()
    for account in accounts:
        print(account.name, account.balance, account.currency)

    # A market order on a demo trading account
    demo = next((a for a in accounts if a.purpose == "trading" and a.is_demo), None)
    if demo:
        order = client.orders.create(
            account_id=demo.id,
            symbol="EURUSD",
            side="buy",
            volume=0.1,
            stop_loss=1.095,
            take_profit=1.11,
        )
        print(order.id, order.status)  # pending until the broker answers

positions.list() reads the open positions on your linked MetaTrader accounts from your broker, and trades.list() their closed trades. Code Examples lists what each part of the API does today.


Testing on a Demo Account

There is no separate sandbox: the API sends orders to your linked broker accounts. It accepts an order only on an account you linked that is:

  • Classified for trading - purpose is trading. Otherwise it answers 403 ACCOUNT_PURPOSE_RESTRICTED.
  • A demo account - isDemo is true. A live account answers 403 LIVE_ACCOUNT_RESTRICTED: live orders need a two-factor-verified session in the app, which an API key or token cannot carry.
  • A MetaTrader account - MT4 or MT5.

Only market orders are accepted today: limit, stop and stop_limit answer 501 ORDER_TYPE_NOT_SUPPORTED. See API Endpoints for the order limits.


Quick Reference

Common endpoints, relative to /api/v1:

ActionMethodEndpoint
List accountsGET/accounts
List ordersGET/orders
Create orderPOST/orders
Get an orderGET/orders/:id
List open positionsGET/positions
Close a positionPOST/positions/:id/close
List closed tradesGET/trades
List instrumentsGET/symbols

Quotes, candles and ticks answer 501 NOT_IMPLEMENTED today.


Next Steps

Now that you've made your first API request, explore these topics:

⚠️

Risk Disclosure

Automated trading via API carries the same risks as manual trading. Test thoroughly on a demo account before you rely on it. Never trade with money you cannot afford to lose.