One HTTP API, and no hidden verbs
JSON over HTTPS, keyed authentication, cursor pagination and idempotent writes. Every endpoint the dashboard uses is an endpoint you can call — there is no private API the product reserves for itself.
Authentication
A bearer token in the header. Keys are scoped, revocable, and never returned after creation.
curl https://api.trade-logx.com/v1/positions \
-H "Authorization: Bearer $NEXUS_API_KEY" \
-H "Nexus-Version: 2026-07-01"Versioning
Nexus-Version header pins the response shape to a date. Omit it and you get the version your key was created against — never the newest, so a deploy on our side cannot change your parsing.Rate limits
X-RateLimit-Remaining; a 429 always carries Retry-After.Strategies
Returns every strategy on the account with its active version, mode (paper or live) and the regimes it is permitted to operate in. Performance is attributed per version, not per strategy, so the response carries the version id you will need for any metrics call.
example{ "data": [ { "id": "stg_8f21", "name": "structure-v4", "version": 11, "mode": "live", "regimes": ["trend", "expanding"], "risk_per_trade": 0.005 } ] }Changes the execution mode. Promotion is rejected if the strategy has no paper history, if the risk envelope would be breached on the first order, or if the connected venue is degraded. Demotion is always accepted and never closes open positions.
example{ "mode": "live" } → 200 { "id": "stg_8f21", "mode": "live", "effective_at": "2026-07-30T09:14:02Z" } → 409 { "error": { "code": "no_paper_history", ... } }
Decisions
The rejections are the point. Filter by verdict to retrieve only what was declined and why — over a month this is a more useful record than the trades, because it is the only place you can see what the system nearly did.
exampleGET /v1/decisions?verdict=veto&since=2026-07-01 { "data": [ { "id": "dec_41c9", "symbol": "ARB/USDT", "conviction": 61, "verdict": "veto", "vetoed_by": "news_blackout", "rationale": "11 minutes to scheduled release; blackout window enforced.", "feature_vector_id": "fv_9a2e" } ] }Deterministic. The stored feature vector is fed back through the current model ensemble, which is how you find out whether a change to weights would have altered a decision made months ago. Never places an order.
example{ "original": { "conviction": 61, "verdict": "veto" }, "replayed": { "conviction": 68, "verdict": "veto" }, "diverged": false }
Positions
Includes the protective orders resident at the venue, so you can verify from outside the product that a stop actually exists rather than trusting that one was requested.
example{ "data": [ { "symbol": "BTC/USDT", "side": "long", "size": "0.420", "entry": 68050.0, "mark": 68776.5, "r_multiple": 1.15, "protective": { "stop": 67420.0, "target": 69380.0, "resident": true } } ] }A manual override. It is executed immediately and written to the audit log with the actor and source address, because an override that leaves no trace is indistinguishable from a bug.
example{ "reason": "manual flatten before travel" } → 202 { "order_id": "ord_77b1", "status": "submitted" }
Backtests
Runs against the same engine and risk service as live. Sweeps return the whole surface rather than the best cell — a peak surrounded by cliffs is an overfit and the response is shaped so it looks like one.
example{ "strategy": "structure-v4", "symbol": "BTC/USDT", "timeframe": "15m", "start": "2025-01-01", "end": "2026-01-01", "sweep": { "threshold": [68, 70, 72, 74, 76] } } → 202 { "id": "bt_2f77", "status": "queued" }Gross performance and cost drag are reported separately. A strategy whose edge disappears once fees, funding and modelled slippage are applied should be visibly that, not quietly netted.
example{ "status": "complete", "gross": { "expectancy": 0.44, "hit_rate": 0.46 }, "costs": { "fees": -0.09, "funding": -0.02, "slippage": -0.02 }, "net": { "expectancy": 0.31, "max_drawdown": -0.082 } }
Webhooks
The same event envelope the internal bus uses, so a webhook payload and a replayed event are the same object.
{
"id": "evt_5c81",
"type": "decision.vetoed",
"occurred_at": "2026-07-30T09:18:00.412Z",
"sequence": 4192837,
"idempotency_key": "dec_41c9:veto",
"data": { "...": "the decision object" }
}Delivery is at-least-once, so handlers must be idempotent — the idempotency_key is stable across retries. Signatures are HMAC-SHA256 over the raw body; verify before parsing. Failed endpoints back off exponentially for 24 hours, and every attempt is visible in the dashboard rather than only in your logs.
Errors
A stable code, a human sentence, and — where a rule caused it — the name of the rule.
| Status | Code | Means |
|---|---|---|
| 400 | invalid_request | Malformed body or a parameter outside its allowed range. |
| 401 | unauthenticated | Missing, malformed or revoked API key. |
| 403 | insufficient_scope | The key is valid but not permitted for this operation. |
| 409 | risk_veto | The risk service refused the intent. `vetoed_by` names the rule. |
| 422 | venue_rejected | The exchange rejected the order; the venue's reason is passed through verbatim. |
| 429 | rate_limited | Retry after the seconds given in `Retry-After`. |
| 503 | fail_closed | A dependency is unreachable and trading has stopped by design. |
503 is not an outage
fail_closed means the risk service is unreachable and trading has stopped deliberately rather than continuing unchecked. Treat it as the system working. Current state is always on the status page.