API reference

Read your accounts and trades, and submit signals, from your own tools. Everything below is available on the Forex Elite add-on.

Forex by default, crypto on request. Every endpoint returns forex only unless you ask otherwise — add ?type=crypto or ?type=all. The default is deliberate so existing integrations keep the exact responses they already had.

Outgoing webhooks fire for both. Each close event carries trading_type so you can tell them apart. Crypto events are queued and delivered within a few minutes rather than immediately — the crypto close path runs inside trade execution and must never wait on your endpoint.

Get a key

Go to Settings → Forex → Elite power-user hooks, name a key, and press Create key.

The secret is shown once, at creation. We store only a hash and cannot show or recover it later — if you lose it, revoke the key and create another.

Create one key per bot or script. Each is revoked independently, so retiring one integration never breaks the others.

Authentication

Send your key in the X-Api-Token header:

curl https://www.signalcopier.io/api/v1/forex/api/accounts \
  -H "X-Api-Token: scp_your_key_here"

A logged-in browser session (Bearer JWT) also works and is never scope-narrowed — it is you, in your own dashboard. API keys are the credential to use for anything automated, because they carry permissions and can be revoked on their own.

Endpoints

Base URL: https://www.signalcopier.io

EndpointPermissionWhat it does
GET /api/v1/forex/api/accounts trades:read Your forex accounts and their connection state
GET /api/v1/forex/api/trades trades:read Trades. Filter with ?status=closed, &pair=EURUSD, &days=7
POST /api/v1/forex/api/signals trades:write Submit a signal for execution

Submitting signals

Send free text or fields — whichever your tool already produces. Text is read by the same AI that reads your Discord and Telegram signals, so you do not have to reshape anything.

POST /api/v1/forex/api/signals
X-Api-Token: scp_your_key_here
Content-Type: application/json

{"text": "BUY EURUSD @ 1.0850 SL 1.0800 TP 1.0950"}

— or structured —

{"pair": "EURUSD", "action": "buy",
 "entry": 1.0850, "sl": 1.0800, "tp": 1.0950}

A successful submission returns:

{"accepted": true, "submitted": true}

“submitted”, not “filled”. It means the signal reached your execution pipeline. Poll GET /api/v1/forex/api/trades for the outcome.

Permissions

Every key carries its own permissions, and they are enforced on each request — a read-only key cannot place a trade, and a write-only key cannot read your history. Give each integration the narrowest set it needs.

PermissionGrants
Loading…

A key with no permissions specified is created read-only. Administrative scopes are not available to customer keys.

Rate limits

Two independent limits apply, and both are enforced:

LimitEliteWindow
Loading…

Exceeding either returns 429. Check your current usage at GET /api/v1/rate-limit/usage.

The TradingView webhook is deliberately exempt from the 429: TradingView disables an alert that keeps receiving errors, which would cost you every future signal rather than just the throttled one. It accepts and records instead.

Errors

CodeMeaningWhat to do
400Bad request, or a permission you cannot grantCheck the response body
401Missing, unknown, revoked or expired keyCreate a new key
403Key lacks the required permissionUse a key with that scope
429Rate limit reachedBack off; see limits
503No forex account connected yetConnect an account, then retry

A refused scope tells you exactly which one was needed:

{"error": "insufficient_scope",
 "accepted": false,
 "required": "trades:write"}

Outgoing webhooks

The reverse direction: instead of you calling us, we call you. Every time one of your forex trades closes we POST a small JSON body to a URL you control — so you can log to a spreadsheet, post to Slack, or update your own dashboard without polling the API.

Turn it on in Settings → Forex → Elite power-user hooks by pasting your URL. Leave it empty to disable.

What we send

POST https://your-endpoint.example.com
Content-Type: application/json

{"schema_version": 2,
 "trade_id": "…", "account": "FTMO 100K",
 "pair": "EURUSD", "direction": "long",
 "entry_price": 1.0850, "exit_price": 1.0950,
 "exit_reason": "take_profit",
 "pnl_usdt": 42.50, "net_pnl_usdt": 41.20,
 "opened_at": "2026-08-17T09:14:03",
 "closed_at": "2026-08-17T11:02:47",
 "channel_name": "…", "channel_id": "…",
 "is_paper": false, "trading_type": "forex"}
FieldMeaning
schema_versionCurrently 2. Only bumped on a rename or removal — new keys can appear without it, so ignore ones you do not know
trade_id, accountWhich trade, on which of your accounts
pair, directionInstrument and side (long / short)
entry_price, exit_priceFill prices
exit_reasonWhy it closed — take profit, stop loss, manual, and so on
pnl_usdt, net_pnl_usdtGross and after costs, negative for a loss
opened_at, closed_atUTC timestamps
channel_name, channel_idThe signal source, when the trade came from one
is_papertrue for audition / paper trades. Off by default — enable it in settings if you want them
trading_typeforex or crypto

HTTPS only, and treat the URL as a secret if your endpoint acts on what it receives. We do not retry indefinitely — an endpoint that is down misses that event, so do not use this as your only record. GET /api/v1/forex/api/trades remains the source of truth.

This fires on closes, not on opens or on signals we reject. If you need those, poll the trades endpoint.

TradingView webhook (incoming)

TradingView cannot send authentication headers, so it gets its own URL with the token embedded. Copy it from Settings → Forex and paste it into TradingView → Notifications → Webhook URL.

Send whatever your indicator produces — any text or JSON shape. Treat that URL like a password: anyone holding it can place trades on your accounts. Rotate it from the same panel to invalidate the old one.