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
- Log into your Trading Platform account
- Navigate to Settings → API Keys
- Click Create API Key
- 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
- 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_keyAn 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
| Code | HTTP Status | Description |
|---|---|---|
| UNAUTHORIZED | 401 | API key or token missing, unknown, expired or revoked, or used from outside the key's IP allowlist |
| INSUFFICIENT_SCOPE | 403 | Key or token lacks the scope this call needs; details.required_any_of lists the scopes that pass |
| VALIDATION_ERROR | 400 | The request body or query failed validation |
| NOT_FOUND | 404 | No route at this method and path |
| ACCOUNT_NOT_FOUND | 404 | An order named an account you did not link, a colleague's included |
| ACCOUNT_PURPOSE_RESTRICTED | 403 | The order's account is not classified for trading |
| LIVE_ACCOUNT_RESTRICTED | 403 | The 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:
| Tier | Requests/min | Burst | Requests/day |
|---|---|---|---|
| Free | 100 | 200 | 10,000 |
| Pro | 1,000 | 2,000 | 100,000 |
| Enterprise | 10,000 | 20,000 | 1,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.
| Language | Package | Import |
|---|---|---|
| TypeScript / JavaScript | @trading-platform/sdk | import { TradingClient } from "@trading-platform/sdk" |
| Python 3.9+ | trading-platform-sdk | from 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 answerspositions.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 -
purposeistrading. Otherwise it answers403ACCOUNT_PURPOSE_RESTRICTED. - A demo account -
isDemoistrue. A live account answers403LIVE_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:
| Action | Method | Endpoint |
|---|---|---|
| List accounts | GET | /accounts |
| List orders | GET | /orders |
| Create order | POST | /orders |
| Get an order | GET | /orders/:id |
| List open positions | GET | /positions |
| Close a position | POST | /positions/:id/close |
| List closed trades | GET | /trades |
| List instruments | GET | /symbols |
Quotes, candles and ticks answer 501 NOT_IMPLEMENTED today.
Next Steps
Now that you've made your first API request, explore these topics:
- API Endpoints - Complete endpoint reference
- Code Examples - Ready-to-use code samples
- Webhooks - Real-time event notifications
- Technical FAQ - Common questions answered
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.