Getting Started
Authenticate and make your first REST API call.
Everything in the Tool Reference is also reachable as a plain HTTP REST API — the same account, market, trading, risk, and macro capabilities, without speaking MCP. Use it for server-side integrations, scripts, or any HTTP client that isn't an MCP-compatible AI client.
Quick Start
1. Get an API key
Create one from Dashboard → API Keys (dashboard), or exchange a terminal key for a JWT directly:
# Exchange a terminal key for a JWT (if you already have one)
curl -X POST https://api.mtcontext.com/api/token \
-H "Content-Type: application/json" \
-d '{"license_key": "mtmcp_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'API keys vs. terminal keys
REST API keys (mtmcp_api_ prefix) are license-scoped, not terminal-bound — one key can reach any terminal on your license via the X-Terminal-Id header. They're a separate credential from the terminal key used by the EA and MCP clients. Up to 5 active API keys per license; revoking one invalidates it immediately.
2. Make your first request
# Get account info
curl https://api.mtcontext.com/api/v1/account/info \
-H "Authorization: Bearer mtmcp_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "X-Terminal-Id: your-terminal-id"
# Get current tick for EURUSD
curl https://api.mtcontext.com/api/v1/market/tick/EURUSD \
-H "Authorization: Bearer mtmcp_api_..." \
-H "X-Terminal-Id: your-terminal-id"
# List connected terminals
curl https://api.mtcontext.com/api/v1/terminals \
-H "Authorization: Bearer mtmcp_api_..."Authentication
Every request needs an Authorization: Bearer <token> header. You can use either:
- API key (recommended): a
mtmcp_api_-prefixed key. The API server automatically exchanges it for a JWT on your behalf. - JWT: a pre-exchanged JWT from the
/api/tokenendpoint.
Authorization: Bearer mtmcp_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTerminal ID Resolution
Most endpoints target a specific MetaTrader terminal. Pass it via the X-Terminal-Id header:
X-Terminal-Id: your-terminal-idTo find your terminal IDs:
curl https://api.mtcontext.com/api/v1/terminals \
-H "Authorization: Bearer mtmcp_api_..."If you omit X-Terminal-Id, most endpoints auto-resolve to your only connected terminal, or return 400 TERMINAL_ID_REQUIRED if you have more than one connected. /api/v1/journal is an exception: it has no live-terminal dependency, so a request with no terminal connected (or a brief gateway hiccup) never errors — it just returns/writes unfiltered across your whole license instead. Pass terminal_id=all or terminal_id=unassigned as a query parameter to GET /api/v1/journal to explicitly query across every terminal or only entries with no terminal attribution.
Rate Limits
REST API requests are limited per license per minute, by subscription tier:
| Tier | REST API Limit |
|---|---|
| Free | 10 req/min |
| Pro | 60 req/min |
| Team | 300 req/min |
| Enterprise | 1000 req/min |
This is a separate bucket from MCP dispatch traffic, so heavy REST use doesn't eat into your MCP tool-call budget or vice versa.
Rate limit headers are included in every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1735689600 (unix seconds)
Retry-After: 42 (only on 429 responses)Response Format
Success
{
"data": {
"symbol": "EURUSD",
"bid": 1.08542,
"ask": 1.08544,
"time": "2024-01-15T10:30:00Z"
}
}Error
{
"error": {
"code": "MISSING_TERMINAL",
"message": "X-Terminal-Id header required"
}
}Common error codes
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid API key/JWT |
FORBIDDEN | 403 | Insufficient tier/capabilities |
RATE_LIMITED | 429 | Too many requests |
MISSING_TERMINAL | 400 | No terminal ID provided |
DISPATCH_ERROR | 502 | Terminal unreachable or command failed |
GATEWAY_ERROR | 502 | Gateway communication failure |
Trading (Safety First)
Every trade-affecting endpoint defaults dry_run to true. It validates the request and tells you exactly what would happen, without touching the account. Pass "dry_run": false explicitly to execute for real.
# Dry run (simulation) — default
curl -X POST https://api.mtcontext.com/api/v1/orders \
-H "Authorization: Bearer mtmcp_api_..." \
-H "X-Terminal-Id: your-terminal-id" \
-H "Content-Type: application/json" \
-d '{
"symbol": "EURUSD",
"order_type": "BUY",
"volume": 0.01
}'
# Live trade — explicit dry_run: false
curl -X POST https://api.mtcontext.com/api/v1/orders \
-H "Authorization: Bearer mtmcp_api_..." \
-H "X-Terminal-Id: your-terminal-id" \
-H "Content-Type: application/json" \
-d '{
"symbol": "EURUSD",
"order_type": "BUY",
"volume": 0.01,
"stop_loss": 1.0800,
"take_profit": 1.0900,
"dry_run": false
}'Interactive Docs
Visit /api/v1/docs for the interactive Scalar API reference, where you can try out endpoints directly in the browser. The OpenAPI 3.1 spec is available at /api/v1/openapi.json.
For a quick-scan table of every endpoint and the capability tier it requires, see Endpoint Reference.
Self-Hosting
Running the API server yourself alongside a self-hosted gateway? It's a separate process (packages/server/api/) with its own environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
PORT | No | 4000 | API server port |
GATEWAY_URL | No | http://localhost:8081 | Gateway base URL for dispatch + proxy |
JWT_PUBLIC_KEY_PATH | Yes | — | Path to the RS256 public key (PEM) used to verify JWTs. The server refuses to start without it. |
REDIS_URL | No | — | Redis connection URL. Without it, rate limiting is disabled in development; the server refuses to start in production without it. |
API_RATE_LIMIT_WINDOW_MS | No | 60000 | Rate limit window in ms |
API_RATE_LIMIT_FREE / _PRO / _TEAM / _ENTERPRISE | No | 10 / 60 / 300 / 1000 | Per-tier request limits within the window |
JWT_ISSUER / JWT_AUDIENCE | No | mt-mcp-license / mt-mcp-api | Must match the values the license service signs JWTs with |
NODE_ENV | No | development | production hides internal error details from API responses |