{"openapi":"3.1.0","info":{"title":"fxapis","version":"0.1.0","description":"fxapis is the MetaTrader 5 API. Connect an MT5 account once, then trade it, read its positions\nand its history over plain HTTP. Choose whether each account stays connected or comes online\nonly when you need it.\n\n### Conventions\n\n- Every successful response is `{ \"data\": … }`; every failure is `{ \"error\": { \"code\", \"message\" } }`.\n  Match on `code`, which is stable. `message` is written for a human and may change.\n- Every response carries `requestId`. Quote it in a support request and the entire call can be found.\n- Times are RFC 3339 in UTC. Money and prices are never floats in a request body.\n\n### Bringing an account online is not instant\n\nA broker login takes as long as the broker takes — usually seconds, occasionally much longer.\n`POST /accounts/{id}/warm` brings an account online and returns **202** with a `pollUrl` rather than\nholding the request open, so your client's timeout never becomes a question about someone else's\nnetwork. Poll `GET /accounts/{id}/status` until `state` is `ready`.\n\n### Credentials\n\nThe MT5 password you send is encrypted before it is stored, with a data key that is bound to that\none account, and is never returned by any endpoint, written to the account record or included in\na log line. We cannot show it back to you — if it is lost, it is reset at the broker."},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"`Authorization: Bearer fx_live_<id>_<secret>`.\n\nA key is shown once, at creation. We cannot show it again or recover it for you.\nKeys carry a label (`live` or `test`) in the key itself, so each configuration is easy to tell\napart. Both reach real brokers: test with a broker demo account.\n\nScopes are per key. A key without `accounts:write` can read accounts and nothing else."},"adminKey":{"type":"http","scheme":"bearer","description":"`Authorization: Bearer fx_admin_<id>_<secret>`.\n\nAn admin key manages this workspace's ordinary API keys (`/v1/api-keys`) and can do nothing else.\nOnly the workspace owner makes one, in the console, optionally limited to IP addresses and given\nan expiry. Every request made with one is audited."}},"schemas":{}},"paths":{"/healthz":{"get":{"summary":"Liveness","tags":["Health"],"description":"Says the fxapis API process is up, for liveness probes and uptime monitors. Checks nothing else and never returns anything but 200; use /readyz to know whether it can serve traffic.","security":[],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"}}}}}}}}},"/readyz":{"get":{"summary":"Readiness","tags":["Health"],"description":"Says the API can serve traffic right now, including storing and using account credentials. Returns 503 when it cannot.","security":[],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"checks":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"checks":{"type":"object","additionalProperties":{"type":"string"}}}}}}}}}},"/v1/accounts":{"get":{"summary":"List connected accounts","tags":["Accounts"],"description":"Every account in this workspace, newest first.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"],"description":"Yours, for telling accounts apart."},"login":{"type":"string","description":"The MT5 account number."},"server":{"type":"string","description":"The broker server name, exactly as MetaTrader shows it."},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"stateDetail":{"type":["null","string"],"description":"Why it is in that state, when there is more to say."},"stateChangedAt":{"type":"string","format":"date-time"},"problem":{"type":["null","object"],"description":"Set when the account needs you, null otherwise: what is wrong in words, what the broker said, and what fixes it. For a refused login it names the broker's other servers, most likely first — a login only works on the server it was opened on.","properties":{"code":{"type":"string","enum":["LOGIN_REFUSED","TRADING_DISABLED","NEEDS_2FA","NEEDS_CERTIFICATE","CONNECTION_FAILED","PLATFORM_ISSUE","SERVER_NOT_FOUND"]},"title":{"type":"string","examples":["The broker refused the login"]},"explanation":{"type":"string"},"detail":{"type":["null","string"],"description":"What the broker or terminal reported, verbatim."},"otherServers":{"type":"array","items":{"type":"string"},"examples":[["JustMarkets-Demo","JustMarkets-Demo2"]]},"actions":{"type":"array","description":"`switch_server`: `POST /v1/accounts/{id}/server` with that server. `replace_credentials`: send the account's corrected credentials (see Accounts in the reference). `connect`: `POST /v1/accounts/{id}/warm`. `contact_support`: write to support.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["switch_server","replace_credentials","connect","contact_support"]},"server":{"type":"string"}},"required":["kind"]}}},"required":["code","title","explanation","detail","otherServers","actions"]},"currency":{"type":["null","string"]},"leverage":{"type":["null","integer"]},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null],"description":"How the broker holds positions: `hedging` keeps one per order, `netting` one per symbol. Null until the terminal has reported it."},"tradeAllowed":{"type":["null","boolean"]},"brokerName":{"type":["null","string"]},"environment":{"type":["null","string"],"enum":["demo","contest","live",null],"description":"Demo, contest or live — from the terminal once it has logged in, or from the server's name until then. Plans give demo accounts free up to an allowance; a trial connects demo accounts only."},"tradingDisabled":{"type":"boolean","description":"Set by us or by the broker. No order is accepted while true."},"createdAt":{"type":"string","format":"date-time"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"figuresObservedAt":{"type":["null","string"],"format":"date-time","description":"When the figures were read from the terminal: every 15 seconds while the account is online (60 from a terminal not yet updated). Null if never."}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Connect an MT5 account","tags":["Accounts"],"description":"Stores the account and encrypts its password. It does **not** log in: the account lands in `created`, and connects when you bring it online or when the first order arrives on a `warm_on_demand` account.\n\n**Reconnecting.** If this login and server were connected before and then disconnected, the same account comes back — its id and history kept — with the new password, and the answer is `200` instead of `201`. If they are still connected, the answer is `409 ACCOUNT_EXISTS` with the account's id; to change its password, use `POST /v1/accounts/{id}/password`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["login","server","password"],"properties":{"platform":{"type":"string","enum":["mt5"],"default":"mt5"},"login":{"type":"string","pattern":"^\\d+$","minLength":1,"maxLength":32,"description":"The MT5 account number.","example":"26177561"},"server":{"type":"string","minLength":1,"maxLength":128,"description":"Broker server name, e.g. `Pepperstone-Demo` or `Exness-MT5Trial7`.","example":"ICMarketsSC-Demo"},"password":{"type":"string","minLength":1,"maxLength":256,"description":"The MT5 password. Encrypted on arrival and never returned or logged. Send the *trading* password, not the investor password: an investor password can read the account but cannot place an order.","example":"your-mt5-trading-password"},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"],"default":"cold","description":"`always_on`: the account stays connected. `warm_on_demand`: it connects on demand (the first order, or a prepare) and goes offline by itself when idle. `cold`: it connects only when you ask. Orders are fastest in that order; cost runs the other way."},"label":{"type":"string","maxLength":120,"example":"Demo — strategy A"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"],"description":"Yours, for telling accounts apart."},"login":{"type":"string","description":"The MT5 account number."},"server":{"type":"string","description":"The broker server name, exactly as MetaTrader shows it."},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"stateDetail":{"type":["null","string"],"description":"Why it is in that state, when there is more to say."},"stateChangedAt":{"type":"string","format":"date-time"},"problem":{"type":["null","object"],"description":"Set when the account needs you, null otherwise: what is wrong in words, what the broker said, and what fixes it. For a refused login it names the broker's other servers, most likely first — a login only works on the server it was opened on.","properties":{"code":{"type":"string","enum":["LOGIN_REFUSED","TRADING_DISABLED","NEEDS_2FA","NEEDS_CERTIFICATE","CONNECTION_FAILED","PLATFORM_ISSUE","SERVER_NOT_FOUND"]},"title":{"type":"string","examples":["The broker refused the login"]},"explanation":{"type":"string"},"detail":{"type":["null","string"],"description":"What the broker or terminal reported, verbatim."},"otherServers":{"type":"array","items":{"type":"string"},"examples":[["JustMarkets-Demo","JustMarkets-Demo2"]]},"actions":{"type":"array","description":"`switch_server`: `POST /v1/accounts/{id}/server` with that server. `replace_credentials`: send the account's corrected credentials (see Accounts in the reference). `connect`: `POST /v1/accounts/{id}/warm`. `contact_support`: write to support.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["switch_server","replace_credentials","connect","contact_support"]},"server":{"type":"string"}},"required":["kind"]}}},"required":["code","title","explanation","detail","otherServers","actions"]},"currency":{"type":["null","string"]},"leverage":{"type":["null","integer"]},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null],"description":"How the broker holds positions: `hedging` keeps one per order, `netting` one per symbol. Null until the terminal has reported it."},"tradeAllowed":{"type":["null","boolean"]},"brokerName":{"type":["null","string"]},"environment":{"type":["null","string"],"enum":["demo","contest","live",null],"description":"Demo, contest or live — from the terminal once it has logged in, or from the server's name until then. Plans give demo accounts free up to an allowance; a trial connects demo accounts only."},"tradingDisabled":{"type":"boolean","description":"Set by us or by the broker. No order is accepted while true."},"createdAt":{"type":"string","format":"date-time"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"figuresObservedAt":{"type":["null","string"],"format":"date-time","description":"When the figures were read from the terminal: every 15 seconds while the account is online (60 from a terminal not yet updated). Null if never."}}}}}}}},"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"],"description":"Yours, for telling accounts apart."},"login":{"type":"string","description":"The MT5 account number."},"server":{"type":"string","description":"The broker server name, exactly as MetaTrader shows it."},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"stateDetail":{"type":["null","string"],"description":"Why it is in that state, when there is more to say."},"stateChangedAt":{"type":"string","format":"date-time"},"problem":{"type":["null","object"],"description":"Set when the account needs you, null otherwise: what is wrong in words, what the broker said, and what fixes it. For a refused login it names the broker's other servers, most likely first — a login only works on the server it was opened on.","properties":{"code":{"type":"string","enum":["LOGIN_REFUSED","TRADING_DISABLED","NEEDS_2FA","NEEDS_CERTIFICATE","CONNECTION_FAILED","PLATFORM_ISSUE","SERVER_NOT_FOUND"]},"title":{"type":"string","examples":["The broker refused the login"]},"explanation":{"type":"string"},"detail":{"type":["null","string"],"description":"What the broker or terminal reported, verbatim."},"otherServers":{"type":"array","items":{"type":"string"},"examples":[["JustMarkets-Demo","JustMarkets-Demo2"]]},"actions":{"type":"array","description":"`switch_server`: `POST /v1/accounts/{id}/server` with that server. `replace_credentials`: send the account's corrected credentials (see Accounts in the reference). `connect`: `POST /v1/accounts/{id}/warm`. `contact_support`: write to support.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["switch_server","replace_credentials","connect","contact_support"]},"server":{"type":"string"}},"required":["kind"]}}},"required":["code","title","explanation","detail","otherServers","actions"]},"currency":{"type":["null","string"]},"leverage":{"type":["null","integer"]},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null],"description":"How the broker holds positions: `hedging` keeps one per order, `netting` one per symbol. Null until the terminal has reported it."},"tradeAllowed":{"type":["null","boolean"]},"brokerName":{"type":["null","string"]},"environment":{"type":["null","string"],"enum":["demo","contest","live",null],"description":"Demo, contest or live — from the terminal once it has logged in, or from the server's name until then. Plans give demo accounts free up to an allowance; a trial connects demo accounts only."},"tradingDisabled":{"type":"boolean","description":"Set by us or by the broker. No order is accepted while true."},"createdAt":{"type":"string","format":"date-time"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"figuresObservedAt":{"type":["null","string"],"format":"date-time","description":"When the figures were read from the terminal: every 15 seconds while the account is online (60 from a terminal not yet updated). Null if never."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}":{"get":{"summary":"Fetch one account","tags":["Accounts"],"description":"One connected account: its login, server, label, mode, current state and when it last changed. The password is never included. Another workspace's account is 404. Balance, equity and margin are the last read from the terminal (`figuresObservedAt`); `GET /v1/accounts/{id}/figures?fresh=true` asks it now.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"],"description":"Yours, for telling accounts apart."},"login":{"type":"string","description":"The MT5 account number."},"server":{"type":"string","description":"The broker server name, exactly as MetaTrader shows it."},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"stateDetail":{"type":["null","string"],"description":"Why it is in that state, when there is more to say."},"stateChangedAt":{"type":"string","format":"date-time"},"problem":{"type":["null","object"],"description":"Set when the account needs you, null otherwise: what is wrong in words, what the broker said, and what fixes it. For a refused login it names the broker's other servers, most likely first — a login only works on the server it was opened on.","properties":{"code":{"type":"string","enum":["LOGIN_REFUSED","TRADING_DISABLED","NEEDS_2FA","NEEDS_CERTIFICATE","CONNECTION_FAILED","PLATFORM_ISSUE","SERVER_NOT_FOUND"]},"title":{"type":"string","examples":["The broker refused the login"]},"explanation":{"type":"string"},"detail":{"type":["null","string"],"description":"What the broker or terminal reported, verbatim."},"otherServers":{"type":"array","items":{"type":"string"},"examples":[["JustMarkets-Demo","JustMarkets-Demo2"]]},"actions":{"type":"array","description":"`switch_server`: `POST /v1/accounts/{id}/server` with that server. `replace_credentials`: send the account's corrected credentials (see Accounts in the reference). `connect`: `POST /v1/accounts/{id}/warm`. `contact_support`: write to support.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["switch_server","replace_credentials","connect","contact_support"]},"server":{"type":"string"}},"required":["kind"]}}},"required":["code","title","explanation","detail","otherServers","actions"]},"currency":{"type":["null","string"]},"leverage":{"type":["null","integer"]},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null],"description":"How the broker holds positions: `hedging` keeps one per order, `netting` one per symbol. Null until the terminal has reported it."},"tradeAllowed":{"type":["null","boolean"]},"brokerName":{"type":["null","string"]},"environment":{"type":["null","string"],"enum":["demo","contest","live",null],"description":"Demo, contest or live — from the terminal once it has logged in, or from the server's name until then. Plans give demo accounts free up to an allowance; a trial connects demo accounts only."},"tradingDisabled":{"type":"boolean","description":"Set by us or by the broker. No order is accepted while true."},"createdAt":{"type":"string","format":"date-time"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"figuresObservedAt":{"type":["null","string"],"format":"date-time","description":"When the figures were read from the terminal: every 15 seconds while the account is online (60 from a terminal not yet updated). Null if never."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"delete":{"summary":"Delete an account and its history","tags":["Accounts"],"description":"Removes the account for good: its terminal is stopped, its password erased, and the record deleted with its orders, deals and positions. **This cannot be undone.** To stop trading on an account but keep its history readable, disconnect it instead.\n\nRefused with `409` while an order is in flight (`ACCOUNT_EXECUTING`), while a multi-account order that includes it has not finished (`ACCOUNT_IN_WAVE`), and when our last look found open positions (`ACCOUNT_HAS_POSITIONS`): those stay open at the broker with their stops, but could no longer be shown or closed here. Close them first, or send `force=true` to delete anyway.\n\nAlert hooks stop sending to the account; a hook left with no accounts is switched off. This month's usage is unaffected. The same login and server can be connected again afterwards, as a new account.","parameters":[{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"force","required":false,"description":"`true` deletes even with open positions, which stay open at the broker."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]},"removed":{"type":"object","description":"What went with it.","properties":{"orders":{"type":"integer"},"deals":{"type":"integer"},"positions":{"type":"integer"},"alertHooksUpdated":{"type":"integer"}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/status":{"get":{"summary":"Poll lifecycle state","tags":["Accounts"],"description":"The endpoint to poll after bringing an account online. Cheap enough to call every second or two; `state` reaches `ready` when the account is logged in and ready to trade.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"detail":{"type":["null","string"]},"since":{"type":"string","format":"date-time"},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"tradingDisabled":{"type":"boolean"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/figures":{"get":{"summary":"Balance, equity and margin","tags":["Accounts"],"description":"The account's money as its MetaTrader terminal reports it: balance, equity, margin, free margin, margin level, credit and open profit, as decimal strings in the account's currency.\n\nWithout `fresh`, the last read: taken every 15 seconds while the account is online, with `observedAt` saying when. With `fresh=true`, the terminal is asked now — the account must be `ready` (409 `ACCOUNT_NOT_READY` otherwise, including while it is `executing` an order or `degraded`); a terminal not yet updated answers 501 `CAPABILITY_UNAVAILABLE` instead, rare in practice. Callers within the same second share one read, and only a read that reaches the terminal is charged to the account's live budget (300 a minute + 50 across every caller; 429 `RATE_LIMITED` with `retry-after` past it).","parameters":[{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"fresh","required":false,"description":"`true` asks the account's terminal now (the account must be online), charged to the account's live budget when the terminal is asked. Without it, the last read."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"currency":{"type":["null","string"],"example":"USD"},"leverage":{"type":["null","integer"],"example":500},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null]},"observedAt":{"type":["null","string"],"format":"date-time","description":"When the terminal was read."},"ageMs":{"type":["null","integer"],"description":"How old the figures were when this answer was sent."},"source":{"type":"string","enum":["live","snapshot"],"description":"`live`: the terminal was asked for this request (or one within the last second). `snapshot`: the last read, at most about 15 seconds old while the account is online (60 from a terminal not yet updated)."}},"required":["accountId","observedAt","ageMs","source"]}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"501":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/password":{"post":{"summary":"Replace an account's password","tags":["Accounts"],"description":"Gives a connected account a new trading password — after the member changed it at the broker, or when the account is in `invalid_credentials` because the one it had was wrong. Send `server` as well to correct the server name.\n\nThe account is taken offline first (refused with `409` while an order is in flight), the new password is encrypted and stored, and only then is the old one erased — a failure leaves the old credential in place. The account lands in `created` and comes online on the next order or when you bring it online; bring it online straight away to check the new password while the member is still there. The password is never returned or logged.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","minLength":1,"maxLength":256,"description":"The account's **trading** password, not the investor password.","example":"the-members-new-trading-password"},"server":{"type":"string","minLength":1,"maxLength":128,"description":"Optional: a corrected server name, exactly as MetaTrader shows it.","example":"Pepperstone-MT5-Live01"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"],"description":"Yours, for telling accounts apart."},"login":{"type":"string","description":"The MT5 account number."},"server":{"type":"string","description":"The broker server name, exactly as MetaTrader shows it."},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"stateDetail":{"type":["null","string"],"description":"Why it is in that state, when there is more to say."},"stateChangedAt":{"type":"string","format":"date-time"},"problem":{"type":["null","object"],"description":"Set when the account needs you, null otherwise: what is wrong in words, what the broker said, and what fixes it. For a refused login it names the broker's other servers, most likely first — a login only works on the server it was opened on.","properties":{"code":{"type":"string","enum":["LOGIN_REFUSED","TRADING_DISABLED","NEEDS_2FA","NEEDS_CERTIFICATE","CONNECTION_FAILED","PLATFORM_ISSUE","SERVER_NOT_FOUND"]},"title":{"type":"string","examples":["The broker refused the login"]},"explanation":{"type":"string"},"detail":{"type":["null","string"],"description":"What the broker or terminal reported, verbatim."},"otherServers":{"type":"array","items":{"type":"string"},"examples":[["JustMarkets-Demo","JustMarkets-Demo2"]]},"actions":{"type":"array","description":"`switch_server`: `POST /v1/accounts/{id}/server` with that server. `replace_credentials`: send the account's corrected credentials (see Accounts in the reference). `connect`: `POST /v1/accounts/{id}/warm`. `contact_support`: write to support.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["switch_server","replace_credentials","connect","contact_support"]},"server":{"type":"string"}},"required":["kind"]}}},"required":["code","title","explanation","detail","otherServers","actions"]},"currency":{"type":["null","string"]},"leverage":{"type":["null","integer"]},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null],"description":"How the broker holds positions: `hedging` keeps one per order, `netting` one per symbol. Null until the terminal has reported it."},"tradeAllowed":{"type":["null","boolean"]},"brokerName":{"type":["null","string"]},"environment":{"type":["null","string"],"enum":["demo","contest","live",null],"description":"Demo, contest or live — from the terminal once it has logged in, or from the server's name until then. Plans give demo accounts free up to an allowance; a trial connects demo accounts only."},"tradingDisabled":{"type":"boolean","description":"Set by us or by the broker. No order is accepted while true."},"createdAt":{"type":"string","format":"date-time"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"figuresObservedAt":{"type":["null","string"],"format":"date-time","description":"When the figures were read from the terminal: every 15 seconds while the account is online (60 from a terminal not yet updated). Null if never."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/server":{"post":{"summary":"Move an account to another server","tags":["Accounts"],"description":"For a login refused because it was added under the wrong server name: keeps the stored password and tries it on `server` instead, so the password is not sent again. The broker's likely servers are in the account's `problem.otherServers`. With `connect: true` (the default) the account is brought online straight away, so the answer comes back in seconds — watch `state`, or the account's events.\n\n`409 ACCOUNT_EXISTS` when that login is already connected on that server here; `409 NO_PASSWORD` when no password is stored (send one to `/password` instead).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["server"],"properties":{"server":{"type":"string","minLength":1,"maxLength":128,"description":"Exactly as MetaTrader shows it.","example":"JustMarkets-Demo"},"connect":{"type":"boolean","default":true}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"],"description":"Yours, for telling accounts apart."},"login":{"type":"string","description":"The MT5 account number."},"server":{"type":"string","description":"The broker server name, exactly as MetaTrader shows it."},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"],"description":"Online: `ready` (can trade) and `executing` (an order is in flight). Connecting: `provisioning`, `starting`, `connecting`, `synchronizing`, `reconnecting` — poll until `ready`. Offline: `created`, `standby`, `cooling` (going offline) and `offline` (after a disconnect, send the account's credentials again to reconnect). `degraded`: online but misbehaving — restart the connection. Need a human: `invalid_credentials`, `needs_2fa`, `needs_certificate`, `trading_disabled`. `error`: see `stateDetail`."},"stateDetail":{"type":["null","string"],"description":"Why it is in that state, when there is more to say."},"stateChangedAt":{"type":"string","format":"date-time"},"problem":{"type":["null","object"],"description":"Set when the account needs you, null otherwise: what is wrong in words, what the broker said, and what fixes it. For a refused login it names the broker's other servers, most likely first — a login only works on the server it was opened on.","properties":{"code":{"type":"string","enum":["LOGIN_REFUSED","TRADING_DISABLED","NEEDS_2FA","NEEDS_CERTIFICATE","CONNECTION_FAILED","PLATFORM_ISSUE","SERVER_NOT_FOUND"]},"title":{"type":"string","examples":["The broker refused the login"]},"explanation":{"type":"string"},"detail":{"type":["null","string"],"description":"What the broker or terminal reported, verbatim."},"otherServers":{"type":"array","items":{"type":"string"},"examples":[["JustMarkets-Demo","JustMarkets-Demo2"]]},"actions":{"type":"array","description":"`switch_server`: `POST /v1/accounts/{id}/server` with that server. `replace_credentials`: send the account's corrected credentials (see Accounts in the reference). `connect`: `POST /v1/accounts/{id}/warm`. `contact_support`: write to support.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["switch_server","replace_credentials","connect","contact_support"]},"server":{"type":"string"}},"required":["kind"]}}},"required":["code","title","explanation","detail","otherServers","actions"]},"currency":{"type":["null","string"]},"leverage":{"type":["null","integer"]},"marginMode":{"type":["null","string"],"enum":["netting","hedging",null],"description":"How the broker holds positions: `hedging` keeps one per order, `netting` one per symbol. Null until the terminal has reported it."},"tradeAllowed":{"type":["null","boolean"]},"brokerName":{"type":["null","string"]},"environment":{"type":["null","string"],"enum":["demo","contest","live",null],"description":"Demo, contest or live — from the terminal once it has logged in, or from the server's name until then. Plans give demo accounts free up to an allowance; a trial connects demo accounts only."},"tradingDisabled":{"type":"boolean","description":"Set by us or by the broker. No order is accepted while true."},"createdAt":{"type":"string","format":"date-time"},"balance":{"type":["null","string"],"description":"Balance, in the account's currency.","example":"10012.25000000"},"equity":{"type":["null","string"],"description":"Balance plus open profit and credit.","example":"10012.25000000"},"margin":{"type":["null","string"],"description":"Margin in use.","example":"10012.25000000"},"freeMargin":{"type":["null","string"],"description":"Equity minus margin in use.","example":"10012.25000000"},"marginLevel":{"type":["null","string"],"description":"Equity over margin, in percent. Null while no margin is used: the ratio is undefined, not zero.","example":"10012.25000000"},"credit":{"type":["null","string"],"description":"Credit the broker extended. Null from a terminal older than account.v2.","example":"10012.25000000"},"profit":{"type":["null","string"],"description":"Open profit across positions. Null from a terminal older than account.v2.","example":"10012.25000000"},"figuresObservedAt":{"type":["null","string"],"format":"date-time","description":"When the figures were read from the terminal: every 15 seconds while the account is online (60 from a terminal not yet updated). Null if never."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/events":{"get":{"summary":"What happened to an account","tags":["Accounts"],"description":"The account's history in words, newest first: added, logging in, refused by the broker, online, moved to another server, taken offline. The same record the console shows as the account's activity.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"tone":{"type":"string","enum":["success","info","warning","danger"]},"title":{"type":"string","example":"The broker refused the login"},"detail":{"type":["null","string"]},"by":{"type":"string","enum":["key","member","staff","system"]},"action":{"type":"string"}},"required":["id","at","tone","title","detail","by","action"]}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/quotes":{"get":{"summary":"Live prices from the account's broker","tags":["Market data"],"description":"Bid, ask and spread for up to 20 symbols or instruments, read from the account's own MetaTrader terminal — the prices this account trades at. The account must be online (409 `ACCOUNT_NOT_READY` otherwise).\n\nEvery quote carries `time`, `brokerTime` and `ageMs`; judge freshness from them. `stale` is true only while the market is open and the last tick is over 60 seconds old; a closed market answers its last price with `marketOpen: false`. A symbol the broker does not have answers `status: unknown_symbol` in its place. Poll this; there is no stream. Calls that reach the terminal are charged to the account's live budget (300 a minute + 50, across every caller; cached answers are free), and past it this answers 429 `RATE_LIMITED` with `retry-after`. An account whose terminal is not yet updated — rare — answers 501 `CAPABILITY_UNAVAILABLE` instead.","parameters":[{"schema":{"type":"string"},"example":"EURUSD,XAUUSD","in":"query","name":"symbols","required":false,"description":"Broker symbols, comma-separated, exactly as this broker names them: `EURUSD.a,XAUUSD.a`."},{"schema":{"type":"string"},"example":"XAUUSD,US30","in":"query","name":"instruments","required":false,"description":"Instruments (`GET /v1/instruments`), comma-separated; each is quoted as this account's own symbol for it."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string","example":"EURUSD"},"instrument":{"type":["null","string"],"description":"The instrument you asked by, when you asked by one."},"status":{"type":"string","enum":["ok","no_price","unknown_symbol"],"description":"`no_price`: the broker has sent no price for it yet. `unknown_symbol`: this broker has no such symbol."},"bid":{"type":["null","string"],"example":"1.08450000"},"ask":{"type":["null","string"],"example":"1.08462000"},"spread":{"type":["null","integer"],"description":"Ask minus bid, in points.","example":12},"digits":{"type":["null","integer"],"description":"Decimal places the broker quotes this symbol to.","example":5},"brokerTime":{"type":["null","string"],"description":"The last tick's time on the broker's own clock, as its terminal shows it. Not UTC.","example":"2026-10-15 15:00:00.123"},"time":{"type":["null","string"],"format":"date-time","description":"The last tick's time, in UTC. Always given when there is a tick, closed market included."},"observedAt":{"type":"string","format":"date-time","description":"When the terminal was read."},"ageMs":{"type":["null","integer"],"description":"How old the tick was when it was read."},"stale":{"type":"boolean","description":"True only when the market is open (by the broker's sessions) and the last tick is more than 60 seconds old. A closed market's last price is not stale. Judge freshness for your own purposes from `time` and `ageMs`."},"marketOpen":{"type":["null","boolean"],"description":"From the broker's own trading sessions. Null until the terminal has reported them (a minute or so after it first comes online)."},"tradeMode":{"type":["null","string"],"enum":["full","longOnly","shortOnly","closeOnly","disabled",null],"description":"What the broker allows on this symbol right now, read with the price: `closeOnly` and `disabled` allow no new positions. Null for an unknown symbol."}},"required":["symbol","status","stale"]}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"501":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/candles":{"get":{"summary":"Price history (candles) from the account's broker","tags":["Market data"],"description":"Open, high, low and close bars for one symbol or instrument, read from the account's own MetaTrader terminal: `timeframe` M1, M5, M15, M30, H1, H4, D1, W1 or MN1, and up to 1,000 bars (`count`, default 100) counting back from the current one, oldest first; the last bar is still forming. Times are when each bar opened, in UTC (converted with the broker's current clock offset, so bars from before its last daylight-saving change can be an hour out). `tickVolume` counts price changes, not traded volume. The account must be online (409 `ACCOUNT_NOT_READY` otherwise). Each call reaches the terminal and is charged to the account's live budget (300 a minute + 50, shared with quotes and fresh figures); past it this answers 429 `RATE_LIMITED` with `retry-after`.\n\nAn account whose terminal is not yet updated — rare — answers 501 `CAPABILITY_UNAVAILABLE` instead.","parameters":[{"schema":{"type":"string"},"example":"XAUUSD","in":"query","name":"symbol","required":false,"description":"The broker symbol, exactly as this broker names it. Send this or `instrument`."},{"schema":{"type":"string"},"example":"XAUUSD","in":"query","name":"instrument","required":false,"description":"An instrument (`GET /v1/instruments`), read as this account's own symbol for it. Send this or `symbol`."},{"schema":{"type":"string","enum":["M1","M5","M15","M30","H1","H4","D1","W1","MN1"]},"in":"query","name":"timeframe","required":true,"description":"The bar size: minutes (M), hours (H), a day, a week or a month."},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":100},"in":"query","name":"count","required":false,"description":"How many bars, counting back from the current one. At most 1,000."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"symbol":{"type":"string","example":"XAUUSD"},"instrument":{"type":["null","string"],"description":"The instrument you asked by, when you asked by one."},"timeframe":{"type":"string","example":"H1"},"digits":{"type":"integer","description":"Decimal places the broker quotes this symbol to; prices are written to them.","example":2},"candles":{"type":"array","description":"Oldest first. The last bar is the current one, still forming.","items":{"type":"object","properties":{"time":{"type":"string","format":"date-time","description":"When the bar opened, in UTC.","example":"2026-10-23T13:00:00Z"},"open":{"type":"string","example":"2650.10"},"high":{"type":"string","example":"2655.25"},"low":{"type":"string","example":"2648.00"},"close":{"type":"string","example":"2652.50"},"tickVolume":{"type":"integer","description":"Price changes in the bar (MetaTrader's tick volume), not traded volume.","example":1234},"spread":{"type":"integer","description":"The bar's spread in points, as the broker recorded it.","example":35}},"required":["time","open","high","low","close","tickVolume","spread"]}}},"required":["symbol","timeframe","digits","candles"]}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"501":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/warm":{"post":{"summary":"Bring an account online","tags":["Lifecycle"],"description":"Starts connecting the account and returns **202** immediately — the broker login is still in progress. Poll `pollUrl` until `state` is `ready`.\n\nCalling this for an account that is already online is harmless and returns `alreadyRunning: true`, so a client that is unsure can simply call it.\n\nReturns 409 when the account needs a human first (a wrong password, 2FA, a certificate, trading disabled at the broker). Retrying will not fix those, and repeated failed logins are how a broker locks an account.\n\nReturns 402 `QUOTA_EXCEEDED` when the workspace has no plan (a trial that ended): choose one in Billing.\n\nReturns 429 `RESTART_TOO_SOON` (with `retry-after`) when the account's terminal has already been started 3 times in the last 10 minutes, counting restarts and starts made for orders.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"runtimeId":{"type":"string","format":"uuid"},"alreadyRunning":{"type":"boolean","description":"True when the account was already online or connecting; asking again is harmless."},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"]},"pollUrl":{"type":"string","description":"Poll here until `state` is `ready`."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/prepare":{"post":{"summary":"Bring several accounts online at once","tags":["Lifecycle"],"description":"Brings every account listed online and returns **202** with a result for each — the broker logins are still in progress. Built for a signal: call it when the signal goes out, and by the time people act on it their accounts are online, so the order goes straight through instead of waiting for a login.\n\nAn account already online is reported as `already_running`; one that needs a human first (`needs_operator`) is not retried. `warm_on_demand` accounts go offline again by themselves after the idle window with no orders.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountIds"],"additionalProperties":false,"properties":{"accountIds":{"type":"array","minItems":1,"maxItems":200,"uniqueItems":true,"items":{"type":"string","format":"uuid"}}}}}}},"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","required":["accountId","result"],"properties":{"accountId":{"type":"string","format":"uuid"},"result":{"type":"string","enum":["starting","already_running","not_found","leased_elsewhere","needs_operator","no_secret","failed"],"description":"`starting`: connecting now. `already_running`: already online or connecting. `leased_elsewhere`: busy with another request; retry in a moment. `needs_operator`: needs a human first — a wrong login, 2FA or a certificate. `no_secret`: no credentials are stored; send them again. `failed`: could not be brought online; `message` says why."},"message":{"type":["null","string"]}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/cool":{"post":{"summary":"Take an account offline","tags":["Lifecycle"],"description":"Takes the account offline and keeps it, with its stored password, in `standby` — ready to be brought online again. Open positions are untouched: a stop loss or take profit is held by the broker and keeps working while the account is offline.\n\nReturns 409 while an order is in flight. Going offline then would turn a known outcome into an unknown one, and a retry on top of that is a duplicate trade.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"stopped":{"type":"boolean","description":"False when the account was already offline."},"state":{"type":"string"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/restart":{"post":{"summary":"Restart the connection","tags":["Lifecycle"],"description":"For an account that is online but misbehaving — `degraded`, stale quotes, a stuck sync. Returns **202**; poll `pollUrl` until `state` is `ready`. Refused with 409 while an order is in flight, for the same reason as taking it offline. Returns 402 `QUOTA_EXCEEDED` when the workspace has no plan.\n\nReturns 429 `RESTART_TOO_SOON` (with `retry-after`) when the account's terminal has already been started 3 times in the last 10 minutes; the account is left as it is.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"runtimeId":{"type":"string","format":"uuid"},"alreadyRunning":{"type":"boolean","description":"True when the account was already online or connecting; asking again is harmless."},"state":{"type":"string","enum":["created","provisioning","standby","starting","connecting","synchronizing","ready","executing","cooling","offline","degraded","reconnecting","invalid_credentials","trading_disabled","needs_2fa","needs_certificate","error"]},"pollUrl":{"type":"string","description":"Poll here until `state` is `ready`."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/disconnect":{"post":{"summary":"Disconnect and erase the credential","tags":["Lifecycle"],"description":"Takes the account offline and **deletes the stored password**. The account record stays, with its history, in `offline`. Reconnecting means sending the password again.\n\nThis is the endpoint to call when a customer leaves. A disconnected account that still holds a usable password is a credential nobody is watching.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"state":{"type":"string"},"credentialsRemoved":{"type":"boolean"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/mode":{"post":{"summary":"Change how eagerly the account stays connected","tags":["Lifecycle"],"description":"`always_on`: stays connected. `warm_on_demand`: connects on demand (the first order, or a prepare) and goes offline by itself when idle. `cold`: connects only when you ask.\n\nTakes effect the next time the account is brought online, so the call stays fast and predictable. Switch to `always_on` and then bring the account online to apply it now.\n\nA copy-trading strategy's account must stay `always_on`: moving it to another mode is refused with 409 `ACCOUNT_IS_MASTER` until the strategy is archived.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"mode":{"type":"string","enum":["always_on","warm_on_demand","cold"]},"restingState":{"type":"string","description":"Where the account sits when idle under this mode."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/instruments":{"get":{"summary":"List the instruments a signal can name","tags":["Instruments"],"description":"The markets fxapis names once, whatever each broker calls them: currency pairs, metals, indices, energies and crypto. A signal that names one of these as `instrument` is traded on every account under that account's own broker symbol. Needs no account and no broker.","parameters":[{"schema":{"type":"string","enum":["forex","metals","indices","energies","crypto"]},"in":"query","name":"category","required":false,"description":"Only this category."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"instrument":{"type":"string","example":"XAUUSD"},"name":{"type":"string","example":"Gold vs US Dollar"},"category":{"type":"string","enum":["forex","metals","indices","energies","crypto"]}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/symbols":{"get":{"summary":"List the symbols an account's broker offers","tags":["Instruments"],"description":"Every symbol the account's broker offers it, with its contract specification, as read from the broker when the account was last online — so it answers while the account is offline. Refreshed each time the account comes online and the list is a day old. `syncedAt` says when.\n\nReturns 409 `SYMBOLS_NOT_SYNCED` for an account that has never been online.","parameters":[{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Only symbols whose name or description contains this."},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"tradable","required":false,"description":"Only symbols this account can, or cannot, open positions in."},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":200},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The `nextCursor` from the previous page."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The broker's own name, exactly as an order must send it.","example":"XAUUSD.a"},"description":{"type":"string","example":"Gold vs US Dollar"},"path":{"type":"string","description":"The broker's folder for it.","example":"Metals\\XAUUSD.a"},"digits":{"type":["null","integer"],"example":2},"contractSize":{"type":["null","number"],"description":"Units of the underlying per 1.0 lot.","example":100},"volumeMin":{"type":["null","number"],"example":0.01},"volumeMax":{"type":["null","number"],"example":50},"volumeStep":{"type":["null","number"],"example":0.01},"tradable":{"type":"boolean","description":"Whether this account can open positions in it."},"sessions":{"type":["null","object"],"description":"The broker's own sessions, in its server time (see `meta.utcOffsetSeconds`). Null until read.","properties":{"trade":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]},"open":{"type":"string","examples":["00:01"],"description":"HH:MM."},"close":{"type":"string","examples":["23:58"],"description":"HH:MM; `24:00` is the end of the day."}}},"description":"When orders can be placed."},"quote":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]},"open":{"type":"string","examples":["00:01"],"description":"HH:MM."},"close":{"type":"string","examples":["23:58"],"description":"HH:MM; `24:00` is the end of the day."}}},"description":"When prices are quoted."}}},"currencyBase":{"type":"string"},"currencyProfit":{"type":"string"},"currencyMargin":{"type":"string"}}}},"meta":{"type":"object","properties":{"syncedAt":{"type":"string","format":"date-time","description":"When the list was read from the broker."},"server":{"type":"string"},"symbolCount":{"type":"integer"},"utcOffsetSeconds":{"type":["null","integer"],"description":"The broker's server clock minus UTC, in seconds, measured when the sessions were read.","example":10800},"sessionsSyncedAt":{"type":["null","string"],"format":"date-time","description":"When the sessions were read; null until they have been."}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"],"description":"Pass as `cursor` to continue."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/instruments":{"get":{"summary":"See how each instrument maps onto an account's broker","tags":["Instruments"],"description":"For every instrument, the symbol an order naming it will trade on this account — or why it cannot: the broker has several plausible symbols (`ambiguous`, with `candidates`), or does not offer it (`missing`). Useful when a member connects, to tell them which signals their account can follow.\n\nA symbol is mapped automatically only when its name matches and, where the market has one standard contract, its contract size agrees: gold quoted per gram is never taken for gold per ounce.\n\nReturns 409 `SYMBOLS_NOT_SYNCED` for an account that has never been online.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"instrument":{"type":"string","example":"XAUUSD"},"name":{"type":"string"},"category":{"type":"string","enum":["forex","metals","indices","energies","crypto"]},"status":{"type":"string","enum":["mapped","ambiguous","missing"],"description":"`mapped`: orders naming the instrument trade `symbol`. `ambiguous`: the broker has more than one plausible symbol (in `candidates`), so an order must name the one it means. `missing`: the broker does not offer it to this account."},"symbol":{"type":["null","string"],"example":"XAUUSD.a"},"reason":{"type":["null","string"],"example":"its name once the broker's suffix is removed, contract size agrees"},"candidates":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"confidence":{"type":"number","description":"0 to 1."},"reason":{"type":"string"}}}}}}},"meta":{"type":"object","properties":{"syncedAt":{"type":"string","format":"date-time","description":"When the list was read from the broker."},"server":{"type":"string"},"symbolCount":{"type":"integer"},"utcOffsetSeconds":{"type":["null","integer"],"description":"The broker's server clock minus UTC, in seconds, measured when the sessions were read.","example":10800},"sessionsSyncedAt":{"type":["null","string"],"format":"date-time","description":"When the sessions were read; null until they have been."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/sessions":{"get":{"summary":"Market hours for a symbol or instrument, from the account's broker","tags":["Instruments"],"description":"When the account's broker lets orders be placed in a symbol — or in this account's symbol for an instrument — as the broker configured it (MetaTrader's `SymbolInfoSessionTrade`), with whether it is open now and when that next changes.\n\n`trade` and `quote` are given in the broker's server time and in UTC; `utcOffsetSeconds` is the broker's clock as measured when the sessions were read. Read when the account comes online and refreshed daily, so it answers while the account is offline.\n\nHolidays a broker does not load into its schedule are not here: on such a day an order is still refused with `ORDER_REJECTED` (`Market closed`).","parameters":[{"schema":{"type":"string"},"in":"query","name":"symbol","required":false,"description":"A broker symbol, exactly as the broker spells it."},{"schema":{"type":"string"},"in":"query","name":"instrument","required":false,"description":"Or an instrument, e.g. `XAUUSD`: this account's symbol for it is used."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"symbol":{"type":"string","example":"XAUUSD"},"instrument":{"type":["null","string"],"example":"XAUUSD"},"server":{"type":"string"},"utcOffsetSeconds":{"type":"integer","example":10800},"sessionsSyncedAt":{"type":"string","format":"date-time"},"openNow":{"type":"boolean"},"nextOpen":{"type":["null","string"],"format":"date-time","description":"When it next opens (UTC), if closed."},"nextClose":{"type":["null","string"],"format":"date-time","description":"When it next closes (UTC), if open."},"trade":{"type":"object","properties":{"server":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]},"open":{"type":"string","description":"HH:MM.","example":"00:01"},"close":{"type":"string","description":"HH:MM; `24:00` is the end of the day.","example":"23:58"}}},"description":"In the broker's server time."},"utc":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]},"open":{"type":"string","description":"HH:MM.","example":"00:01"},"close":{"type":"string","description":"HH:MM; `24:00` is the end of the day.","example":"23:58"}}},"description":"In UTC."}}},"quote":{"type":"object","properties":{"server":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]},"open":{"type":"string","description":"HH:MM.","example":"00:01"},"close":{"type":"string","description":"HH:MM; `24:00` is the end of the day.","example":"23:58"}}}},"utc":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","enum":["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]},"open":{"type":"string","description":"HH:MM.","example":"00:01"},"close":{"type":"string","description":"HH:MM; `24:00` is the end of the day.","example":"23:58"}}}}}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/symbols/sync":{"post":{"summary":"Read an account's symbols from its broker now","tags":["Instruments"],"description":"Reads the broker's symbol list again and remaps the instruments, for when the broker has added symbols. Needs the account online (`ready`); returns 409 `ACCOUNT_NOT_READY` otherwise. It happens on its own once a day while the account is online, so most integrations never call this.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"syncedAt":{"type":"string","format":"date-time","description":"When the list was read from the broker."},"server":{"type":"string"},"symbolCount":{"type":"integer"},"utcOffsetSeconds":{"type":["null","integer"],"description":"The broker's server clock minus UTC, in seconds, measured when the sessions were read.","example":10800},"sessionsSyncedAt":{"type":["null","string"],"format":"date-time","description":"When the sessions were read; null until they have been."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/brokers/servers":{"get":{"summary":"Search broker servers","tags":["Accounts"],"description":"MT5 servers matching what someone typed — a broker's name (`vantage`), the start of a server name (`JustMarkets-De`), with or without dashes and spaces. Built for a typeahead in your connect form: call it as the person types (debounced, from 2 characters) and let them pick.\n\nServers accounts on fxapis have logged in to come first (`proven: true`), then names starting with what was typed, then the kind asked for (`demo`/`live`), then the broker's main server. With fewer than five matches for 3+ characters, the broker search is asked once and its servers added, so a broker nobody here has used yet is found too — that call can take a second or two.\n\n**A server that is not listed can still be connected**: always let people use exactly what they typed. Without `q`, the servers used most here.","parameters":[{"schema":{"type":"string","maxLength":64},"example":"justmarkets","in":"query","name":"q","required":false},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Exactly as MetaTrader shows it — send this as `server`.","example":"JustMarkets-Demo"},"company":{"type":["null","string"],"description":"The broker's legal name, when known.","example":"JustMarkets Ltd"},"kind":{"type":"string","enum":["demo","live","contest","unknown"],"description":"From the server's name; `unknown` when the name does not say."},"proven":{"type":"boolean","description":"Accounts on fxapis have logged in to this server."}},"required":["name","company","kind","proven"]}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/orders/market":{"post":{"summary":"Place a market order","tags":["Trading"],"description":"Sends a market order and waits for the broker's answer.\n\n**Send an `Idempotency-Key` header.** Without one, a request that times out leaves you unable to retry safely: you cannot tell whether the order was placed, and guessing wrong opens a second position. With one, retrying is free — the same key returns the same answer and never places a second order.\n\nThree failures are worth telling apart, and the response distinguishes them:\n\n- **`NO_PRICE` (422)** — the broker had no current price for the symbol (market closed, or not offered by this broker), so nothing was sent. Retry once it quotes; the same `Idempotency-Key` may be reused.\n- **`SEND_FAILED` (503)** — nothing reached the broker. Resend only when `retryable` is `true`; it is `false` when the order was taken from this request before it could go (cancelled, say), so look at the order first.\n- **`ORDER_REJECTED` (422)** — the broker refused it, with a reason and its own return code. `retryable` says whether the reason was transient (a requote, a moved price) or permanent (insufficient margin, a closed market).\n- **`ORDER_UNRESOLVED` (503)** — we do not know. The order may be live at the broker. It is in `unknown` while we confirm the result with the broker. **Do not resend it**; poll the order instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["side","volume"],"description":"Send `symbol` or `instrument`, not both.","properties":{"symbol":{"type":"string","minLength":1,"maxLength":32,"description":"As the broker names it, e.g. `EURUSD`.","example":"EURUSD"},"instrument":{"type":"string","minLength":1,"maxLength":32,"description":"Instead of `symbol`: an instrument from `GET /v1/instruments`, traded under this account's own broker symbol for it (`XAUUSD` may be `XAUUSD.a` or `GOLD` at the broker). The order records both. Refused with `INSTRUMENT_NOT_OFFERED` or `INSTRUMENT_AMBIGUOUS` when the account's broker has no single match.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"volume":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots, **as a string** — `\"0.10\"`, not `0.1`. A JSON number is a double, and a volume that arrives as 0.30000000000000004 is rejected by the broker.","example":"0.01"},"stopLoss":{"type":"string","description":"Absolute price, not a distance. Must be below entry for a buy.","example":"1.12900"},"takeProfit":{"type":"string","description":"Absolute price, not a distance. Must be above entry for a buy.","example":"1.14200"},"deviationPoints":{"type":"integer","minimum":0,"maximum":10000,"description":"Maximum slippage in points. Too small and a fast market returns a requote instead of a fill.","example":20},"comment":{"type":"string","maxLength":120,"description":"Stored on the MT5 order after our 11-character reference, cut to fit MT5's limit: the first 17 characters, plain ASCII.","example":"signal 42"},"clientOrderId":{"type":"string","maxLength":120,"description":"Your reference. Not required to be unique.","example":"sig-42-user-7"}}}}},"description":"Send `symbol` or `instrument`, not both."},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","maxLength":200},"example":"3f0c9a52-8a8e-4f7e-9b0e-6c1d2f5a7b10","in":"header","name":"idempotency-key","required":false,"description":"Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused."}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/positions/{positionId}/close":{"post":{"summary":"Close a position","tags":["Trading"],"description":"Closes a position in whole, or partly if you send a `volume`.\n\n**Send an `Idempotency-Key`.** It matters more here than on an opening order: a retried close does not close twice, it opens an opposing position, and the account ends up with exposure nobody chose.\n\nThe three failure modes are the same as for an opening order, and `ORDER_UNRESOLVED` means the same thing — **do not resend**, poll the order. An unresolved close is the case where you might believe you are flat and not be.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"volume":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots to close, as a string. Omit to close the whole position.","example":"0.01"},"deviationPoints":{"type":"integer","minimum":0,"maximum":10000,"example":20},"comment":{"type":"string","maxLength":120,"example":"take profit early"},"clientOrderId":{"type":"string","maxLength":120,"example":"sig-42-user-7-close"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"positionId","required":true,"description":"The broker's position ticket."},{"schema":{"type":"string","maxLength":200},"example":"3f0c9a52-8a8e-4f7e-9b0e-6c1d2f5a7b10","in":"header","name":"idempotency-key","required":false,"description":"Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused."}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/positions/{positionId}/modify":{"post":{"summary":"Move a position's stop loss or take profit","tags":["Trading"],"description":"**Send `null` to remove a level.** Omitting the field leaves it unchanged — an omitted field silently clearing a stop is how protection disappears without anybody choosing it.\n\nRecorded in the order history with intent `modify`, because widening a stop changes what the account risks and belongs beside the trade it protects.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"stopLoss":{"type":["string","null"],"description":"Absolute price. **Send null to remove it** — omitting the field leaves it unchanged.","example":"1.13100"},"takeProfit":{"type":["string","null"],"description":"Absolute price. Send null to remove it.","example":"1.14500"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"positionId","required":true,"description":"The broker's position ticket."}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/orders/pending":{"post":{"summary":"Place a limit, stop or stop-limit order","tags":["Trading"],"description":"A success here means **placed and waiting**, not filled — the broker answers `10008 PLACED` and the order is `working` until it triggers.\n\nA limit waits for a better price (buy below the market, sell above); a stop waits for a worse one and is how a breakout is traded (buy above, sell below). When fxapis has a recent price for the symbol on this account, the wrong side is refused before anything is sent, with a message naming the order you probably meant; otherwise the broker answers with its own `INVALID_PRICE`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["side","kind","volume","price"],"description":"Send `symbol` or `instrument`, not both.","properties":{"symbol":{"type":"string","minLength":1,"maxLength":32,"description":"As the broker names it.","example":"EURUSD"},"instrument":{"type":"string","minLength":1,"maxLength":32,"description":"Instead of `symbol`: an instrument from `GET /v1/instruments`, traded under this account's own broker symbol for it (`XAUUSD` may be `XAUUSD.a` or `GOLD` at the broker). The order records both. Refused with `INSTRUMENT_NOT_OFFERED` or `INSTRUMENT_AMBIGUOUS` when the account's broker has no single match.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"kind":{"type":"string","enum":["limit","stop","stop_limit"],"description":"A **limit** waits for a better price: buy below the market, sell above it. A **stop** waits for a worse one and is how a breakout is traded: buy above, sell below. Getting these backwards is the commonest mistake here, so the wrong side is refused with a message saying which you meant."},"volume":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$","example":"0.01"},"price":{"type":"string","description":"The price the order waits at.","example":"1.12800"},"stopLimitPrice":{"type":"string","description":"Required for stop_limit: the limit placed once the stop triggers.","example":"1.12780"},"stopLoss":{"type":"string","example":"1.12400"},"takeProfit":{"type":"string","example":"1.13600"},"expiresAt":{"type":"string","format":"date-time","description":"When the broker should drop it. Omit for good-till-cancelled."},"comment":{"type":"string","maxLength":120,"example":"breakout"},"clientOrderId":{"type":"string","maxLength":120,"example":"sig-43-user-7"}}}}},"description":"Send `symbol` or `instrument`, not both."},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","maxLength":200},"example":"3f0c9a52-8a8e-4f7e-9b0e-6c1d2f5a7b10","in":"header","name":"idempotency-key","required":false,"description":"Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused."}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/orders/{id}/modify":{"post":{"summary":"Move a pending order's price or levels","tags":["Trading"],"description":"Keeps the order's ticket. Cancelling and re-placing loses its place in the broker's queue and leaves a window where the order does not exist at all — on a fast market that window is where the move happens.\n\nAn omitted field is left alone. Send `stopLoss: null` to clear a stop; omitting it keeps whatever is there.\n\nOnly an order in `working` can be moved. A `filled` order is a position — move its stop with `/positions/{id}/modify` instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price":{"type":"string","description":"The new price the order waits at.","example":"1.12750"},"stopLoss":{"type":["string","null"],"description":"`null` clears it; omitting it keeps what is there.","example":"1.12350"},"takeProfit":{"type":["string","null"],"description":"`null` clears it; omitting it keeps what is there.","example":"1.13550"},"stopLimitPrice":{"type":"string","description":"For a stop-limit order.","example":"1.12730"},"expiresAt":{"type":"string","format":"date-time"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/orders/{id}/cancel":{"post":{"summary":"Cancel a pending order","tags":["Trading"],"description":"Removes a pending order that has not triggered. If it already has, the broker refuses with `10035` — at that point there is a position, not an order, and what you want is a close.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/calculate":{"post":{"summary":"Margin required, or profit at a price","tags":["Trading"],"description":"Opens nothing and is safe to call freely. This is how you find out an order will be refused for margin *before* sending it, rather than collecting a `10019` from the broker.\n\nThe account must be online: an offline account is refused with 409 `NO_RUNTIME`. A null `value` means the broker would not answer, which is not the same as zero.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kind","symbol","side","volume","price"],"properties":{"kind":{"type":"string","enum":["margin","profit"]},"symbol":{"type":"string","maxLength":32,"example":"EURUSD"},"side":{"type":"string","enum":["buy","sell"]},"volume":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$","example":"0.10"},"price":{"type":"string","description":"The price the position opens at.","example":"1.13426"},"closePrice":{"type":"string","description":"Required for a profit calculation.","example":"1.13926"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"kind":{"type":"string","enum":["margin","profit"]},"value":{"type":["null","string"],"description":"In the account's currency. Null means the broker would not answer — which is not the same as zero."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/orders":{"get":{"summary":"List orders","tags":["History"],"description":"Every order this workspace has placed, newest first, across all accounts unless `accountId` narrows it. Filter by `state` to find what needs attention — `state=unknown` is the set whose result we are still confirming with the broker.\n\nPaginated by cursor rather than offset: an offset shifts as new orders arrive, so page two would silently skip rows.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"accountId","required":false,"description":"Narrow to one account."},{"schema":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"in":"query","name":"state","required":false,"description":"`unknown` is the set whose result we are still confirming with the broker."},{"schema":{"type":"string","maxLength":32},"in":"query","name":"symbol","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"since","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"until","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The `nextCursor` from the previous page."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"],"description":"Pass as `cursor` to continue."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/orders/{id}":{"get":{"summary":"Fetch one order","tags":["History"],"description":"The authoritative record of one order: what was asked for, what the broker returned, and its own return code unmodified. Poll this after an `ORDER_UNRESOLVED` response — an opening order moves out of `unknown` as soon as we have confirmed the result with the broker; a close, stop change or cancel stays `unknown`, with a `stateDetail` saying what to check at the broker.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"clientOrderId":{"type":["null","string"],"description":"Your own reference, echoed back."},"symbol":{"type":"string","description":"The broker symbol traded."},"instrument":{"type":["null","string"],"description":"The instrument the order named, when it named one; `symbol` is what it was traded as.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"type":{"type":"string","enum":["market","limit","stop","stop_limit"]},"intent":{"type":"string","enum":["open","close","modify","cancel"],"description":"What this order was for. A close is an order, with the same record and the same failed/unknown distinction as an open — `modify` covers moving a stop, which changes what the account risks."},"brokerPositionId":{"type":["null","string"],"description":"The broker's position ticket. On a close or a stop change, the position it acted on. On an opening order, the position it opened — pass it to `POST /v1/accounts/{id}/positions/{positionId}/close`. Set when the order fills if the terminal reports it; for an order filled by an older terminal, or a pending order that fills later, once the broker's deal history for it has been read. Null until known."},"volume":{"type":["null","string"],"description":"Requested volume, in lots."},"stopLoss":{"type":["null","string"],"description":"Absolute price, not a distance."},"takeProfit":{"type":["null","string"],"description":"Absolute price, not a distance."},"state":{"type":"string","enum":["accepted","validating","sending","working","completed","filled","partially_filled","rejected","failed","unknown","cancelled","expired"]},"stateDetail":{"type":["null","string"]},"needsReconciliation":{"type":"boolean","description":"True while we are confirming the result with the broker. Never resend such an order; poll it."},"retcode":{"type":["null","integer"],"description":"The broker's own MT5 return code, unmodified. 10009 is a completed request."},"retcodeText":{"type":["null","string"]},"brokerOrderId":{"type":["null","string"],"description":"The broker's ticket. What their statement shows."},"brokerDealId":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"What actually filled, which can be less than requested."},"filledPrice":{"type":["null","string"],"description":"What it actually filled at, which is rarely the requested price."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time","description":"When an answer arrived."},"reconciledAt":{"type":["null","string"],"format":"date-time","description":"Set when a result was confirmed with the broker after the fact."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/orders/{id}/deals":{"get":{"summary":"Deals produced by one order","tags":["History"],"description":"One order can produce several deals — a partial fill leaves more than one. These are the broker's own records of money changing hands, which is what a statement is reconciled against.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"Null when the broker did this without us — a stop firing, a swap, a manual trade."},"brokerDealId":{"type":"string","description":"The broker's deal ticket. The identity of this record."},"brokerOrderId":{"type":["null","string"]},"brokerPositionId":{"type":["null","string"]},"symbol":{"type":"string"},"dealType":{"type":"string","description":"buy, sell, balance, credit, commission, swap-adjacent charges and corrections."},"entry":{"type":["null","string"],"description":"in, out, inout or out_by — whether exposure opened or closed."},"volume":{"type":["null","string"],"description":"Lots."},"price":{"type":["null","string"],"description":"Execution price."},"commission":{"type":["null","string"],"description":"Account currency."},"swap":{"type":["null","string"],"description":"Account currency."},"profit":{"type":["null","string"],"description":"Realised, in account currency. Negative is a loss."},"fee":{"type":["null","string"],"description":"Account currency."},"dealtAt":{"type":"string","format":"date-time","description":"The broker's timestamp, not ours."},"comment":{"type":["null","string"]}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/deals":{"get":{"summary":"An account's full deal history","tags":["History"],"description":"Everything the broker recorded against this account, **including deals no order of yours caused** — a stop loss firing, a swap charge, a deposit, or somebody trading the same login from the MetaTrader desktop.\n\nThat inclusion is the point. A history containing only your own orders would show an account whose balance moves for no visible reason. Ordered by the broker's timestamp, not ours.","parameters":[{"schema":{"type":"string","maxLength":32},"in":"query","name":"symbol","required":false,"description":"Only deals on this symbol, as the broker names it."},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"since","required":false,"description":"Deals at or after this time (the broker's timestamp)."},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"until","required":false,"description":"Deals at or before this time."},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The `nextCursor` from the previous page."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"Null when the broker did this without us — a stop firing, a swap, a manual trade."},"brokerDealId":{"type":"string","description":"The broker's deal ticket. The identity of this record."},"brokerOrderId":{"type":["null","string"]},"brokerPositionId":{"type":["null","string"]},"symbol":{"type":"string"},"dealType":{"type":"string","description":"buy, sell, balance, credit, commission, swap-adjacent charges and corrections."},"entry":{"type":["null","string"],"description":"in, out, inout or out_by — whether exposure opened or closed."},"volume":{"type":["null","string"],"description":"Lots."},"price":{"type":["null","string"],"description":"Execution price."},"commission":{"type":["null","string"],"description":"Account currency."},"swap":{"type":["null","string"],"description":"Account currency."},"profit":{"type":["null","string"],"description":"Realised, in account currency. Negative is a loss."},"fee":{"type":["null","string"],"description":"Account currency."},"dealtAt":{"type":"string","format":"date-time","description":"The broker's timestamp, not ours."},"comment":{"type":["null","string"]}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"],"description":"Pass as `cursor` to continue."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/reconcile":{"post":{"summary":"Confirm pending results with the broker now","tags":["Trading"],"description":"Confirms the result of every opening order on this account still in `unknown`, and brings its deals and positions up to date with the broker. A close, stop change or cancel in `unknown` is not settled from deal history — its `stateDetail` says to check the position or order at the broker.\n\nThis happens automatically; call it when you do not want to wait. It is safe to call at any time and safe to call twice — nothing is recorded or settled twice.\n\n`ambiguous` counts orders whose result the broker's records do not settle unambiguously. Those are left in `unknown` on purpose: a wrong guess produces a history that looks settled and is wrong, which is worse than the gap. They need a human.\n\n`skipped` is `no-runtime` when the account is offline: bring it online and call again.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"examined":{"type":"integer","description":"Orders that were in `unknown`."},"resolved":{"type":"integer","description":"How many now have a confirmed result."},"stillUnknown":{"type":"integer","description":"Still unconfirmed, including the ambiguous ones."},"ambiguous":{"type":"integer","description":"Orders the broker's records do not settle unambiguously. Left alone deliberately — a wrong guess produces a history that looks settled and is wrong. These need a human."},"historyNotReady":{"type":"integer","description":"Orders left unconfirmed only because the broker's records were not available yet — usually for about half a minute after an account comes online. An empty answer is not treated as proof an order did not execute; they are confirmed on a later attempt."},"historyReady":{"type":["null","boolean"],"description":"Whether the broker's records were available for this check. Null when that could not be told."},"dealsIngested":{"type":"integer","description":"Broker deals recorded, including ones no order caused."},"positionsOpen":{"type":"integer"},"positionsClosed":{"type":"integer","description":"Positions the broker stopped reporting."},"skipped":{"type":["null","string"],"description":"`no-runtime` when the account is offline, so there was nothing to ask; `unreachable` when the broker would not answer."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/accounts/{id}/positions":{"get":{"summary":"Positions on an account","tags":["Trading"],"description":"What we last saw, with `observedAt` saying when. The broker is authoritative and this is a snapshot, not a ledger — `observedAt` is here so you can tell a current view from a stale one rather than having to assume.\n\nOpen positions only, unless `includeClosed=true`.","parameters":[{"schema":{"type":"string","enum":["true","false"],"default":"false"},"in":"query","name":"includeClosed","required":false,"description":"`true` also returns positions we have seen closed, with `closedAt` set."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid"},"brokerPositionId":{"type":"string"},"symbol":{"type":"string"},"side":{"type":"string","enum":["buy","sell"]},"volume":{"type":["null","string"],"description":"Lots."},"openPrice":{"type":["null","string"],"description":""},"currentPrice":{"type":["null","string"],"description":""},"stopLoss":{"type":["null","string"],"description":""},"takeProfit":{"type":["null","string"],"description":""},"swap":{"type":["null","string"],"description":""},"profit":{"type":["null","string"],"description":"Unrealised, at observedAt."},"openedAt":{"type":["null","string"],"format":"date-time"},"observedAt":{"type":"string","format":"date-time","description":"When this was last true. A snapshot without it would be worthless."},"closedAt":{"type":["null","string"],"format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/execution-waves":{"post":{"summary":"Place one trade on many accounts","tags":["Waves"],"description":"A multi-account order: one trade placed on many accounts at once. Every account is brought online first, then the orders are sent together — at `executeAt`, or as soon as every account is online.\n\n**A multi-account order is not all-or-nothing once sent, and cannot be.** There is no transaction across a hundred brokers: accounts fill at different prices, some are rejected for margin, some go unanswered. So it never reports a single success or failure — it reports a result for each account, and `summary` counts what landed. An account whose result is `unresolved` must not be resent; poll its order.\n\n`dispatchSpreadMs` is the gap between the first account's order being sent and the last. It is the number worth watching: as it grows, your accounts are getting different prices.\n\n**`barrierPolicy`** decides what happens when some accounts are not online in time:\n\n- `release-ready` — trade on the accounts that are online, skip the rest. A partial entry beats a late one.\n- `all-or-nothing` — trade on none unless all are online. Note this is about *sending*: a broker can still reject an account's order after it was sent.\n- `wait` — keep waiting past `executeAt` until every account is online, up to `expiresAt`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Send `symbol` or `instrument`, not both.","required":["accountIds","side","volume"],"properties":{"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"The accounts to trade on, one order each. An account listed twice is traded once."},"symbol":{"type":"string","minLength":1,"maxLength":32,"description":"As the brokers name it. Every account trades this exact symbol, so use it when all the accounts are at brokers that name it the same way.","example":"EURUSD"},"instrument":{"type":"string","minLength":1,"maxLength":32,"description":"Instead of `symbol`: an instrument from `GET /v1/instruments`. Each account trades its own broker's symbol for it (`XAUUSD.a` at one broker, `GOLD` at another), resolved once, when the order is made, and shown on each leg. Refused whole with `INSTRUMENT_UNAVAILABLE` when any account cannot trade it; `details` names each account and why.","example":"XAUUSD"},"side":{"type":"string","enum":["buy","sell"]},"volume":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per account, unless a weight overrides it.","example":"0.01"},"weights":{"type":"object","additionalProperties":{"type":"string"},"description":"Per-account volume, keyed by account id. For accounts that differ in equity."},"stopLoss":{"type":"string","example":"1.12900"},"takeProfit":{"type":"string","example":"1.14200"},"comment":{"type":"string","maxLength":120,"example":"signal 42"},"label":{"type":"string","maxLength":120,"example":"London open — EURUSD long"},"clientWaveId":{"type":"string","maxLength":120,"example":"signal-42"},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"],"default":"release-ready","description":"What to do when some accounts are not online in time. `release-ready` trades on the ones that are; `all-or-nothing` trades on none unless all are; `wait` keeps waiting past executeAt until expiresAt."},"executeAt":{"type":"string","format":"date-time","description":"When the orders should be sent. Omit to send as soon as every account is online — accounts still logging in are waited for up to 60 seconds, then the barrier policy decides."},"expiresAt":{"type":"string","format":"date-time","description":"Stop waiting for accounts that are not online after this."}}}}},"description":"Send `symbol` or `instrument`, not both."},"parameters":[{"schema":{"type":"string","maxLength":200},"example":"3f0c9a52-8a8e-4f7e-9b0e-6c1d2f5a7b10","in":"header","name":"idempotency-key","required":false,"description":"Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused."}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"clientWaveId":{"type":["null","string"]},"symbol":{"type":["null","string"],"description":"The symbol every account trades. Null when the order named an `instrument`; each leg then shows its own."},"instrument":{"type":["null","string"],"description":"The instrument the order named instead of a symbol, if it did."},"side":{"type":"string","enum":["buy","sell"]},"baseVolume":{"type":["null","string"]},"state":{"type":"string","enum":["planned","preparing","armed","releasing","settled","cancelled","abandoned"]},"stateDetail":{"type":["null","string"]},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"]},"executeAt":{"type":["null","string"],"format":"date-time"},"expiresAt":{"type":["null","string"],"format":"date-time"},"preparedAt":{"type":["null","string"],"format":"date-time"},"releasedAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"},"dispatchSpreadMs":{"type":["null","integer"],"description":"The gap between the first account's order being sent and the last, in milliseconds. As it grows, your accounts are getting different prices."},"retryOf":{"type":["null","string"],"format":"uuid","description":"Set when this multi-account order was made by `POST /v1/execution-waves/{id}/retry`: the one it retries."},"retriedBy":{"type":"array","items":{"type":"string","format":"uuid"},"description":"The multi-account orders made by retrying this one, oldest first."},"summary":{"type":"object","description":"What landed. Deliberately not a success flag — a multi-account order is not all-or-nothing once sent.","properties":{"total":{"type":"integer"},"filled":{"type":"integer"},"partiallyFilled":{"type":"integer","description":"Of `filled`, the accounts whose order filled only in part. Counted within `filled`, not beside it."},"rejected":{"type":"integer"},"skipped":{"type":"integer"},"unresolved":{"type":"integer","description":"Accounts whose result we are still confirming with the broker. Do not resend these."}}},"legs":{"type":"array","description":"One entry per account: the order placed there and how it went.","items":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"The ordinary order placed on this account. Query it like any other."},"symbol":{"type":"string","description":"The broker symbol this account trades.","example":"XAUUSD.a"},"volume":{"type":["null","string"]},"state":{"type":"string","enum":["pending","preparing","ready","dispatched","filled","rejected","skipped","unresolved"],"description":"`pending`/`preparing`: being brought online. `ready`: online and waiting. `dispatched`: sent, awaiting the broker. `filled`: the broker filled it, fully or in part. `rejected`: the broker refused it. `skipped`: never reached the broker (not online in time, trading switched off, the plan's allowance, no price, a send that provably failed), or the broker has no record of it. `unresolved`: sent, and we are confirming the result with the broker — do not resend. An unresolved account moves to `filled`, `rejected` or `skipped` once its order is confirmed."},"stateDetail":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"On a `filled` account: how much its order filled, from the order. Null otherwise.","example":"0.01"},"partiallyFilled":{"type":"boolean","description":"On a `filled` account: true when its order filled only in part (`filledVolume` below `volume`)."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"get":{"summary":"List multi-account orders","tags":["Waves"],"description":"Multi-account orders in this workspace, newest first, with each one's state, symbol, side, number of accounts and summary of results.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"clientWaveId":{"type":["null","string"]},"symbol":{"type":["null","string"],"description":"The symbol every account trades. Null when the order named an `instrument`; each leg then shows its own."},"instrument":{"type":["null","string"],"description":"The instrument the order named instead of a symbol, if it did."},"side":{"type":"string","enum":["buy","sell"]},"baseVolume":{"type":["null","string"]},"state":{"type":"string","enum":["planned","preparing","armed","releasing","settled","cancelled","abandoned"]},"stateDetail":{"type":["null","string"]},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"]},"executeAt":{"type":["null","string"],"format":"date-time"},"expiresAt":{"type":["null","string"],"format":"date-time"},"preparedAt":{"type":["null","string"],"format":"date-time"},"releasedAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"},"dispatchSpreadMs":{"type":["null","integer"],"description":"The gap between the first account's order being sent and the last, in milliseconds. As it grows, your accounts are getting different prices."},"retryOf":{"type":["null","string"],"format":"uuid","description":"Set when this multi-account order was made by `POST /v1/execution-waves/{id}/retry`: the one it retries."},"retriedBy":{"type":"array","items":{"type":"string","format":"uuid"},"description":"The multi-account orders made by retrying this one, oldest first."},"summary":{"type":"object","description":"What landed. Deliberately not a success flag — a multi-account order is not all-or-nothing once sent.","properties":{"total":{"type":"integer"},"filled":{"type":"integer"},"partiallyFilled":{"type":"integer","description":"Of `filled`, the accounts whose order filled only in part. Counted within `filled`, not beside it."},"rejected":{"type":"integer"},"skipped":{"type":"integer"},"unresolved":{"type":"integer","description":"Accounts whose result we are still confirming with the broker. Do not resend these."}}},"legs":{"type":"array","description":"One entry per account: the order placed there and how it went.","items":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"The ordinary order placed on this account. Query it like any other."},"symbol":{"type":"string","description":"The broker symbol this account trades.","example":"XAUUSD.a"},"volume":{"type":["null","string"]},"state":{"type":"string","enum":["pending","preparing","ready","dispatched","filled","rejected","skipped","unresolved"],"description":"`pending`/`preparing`: being brought online. `ready`: online and waiting. `dispatched`: sent, awaiting the broker. `filled`: the broker filled it, fully or in part. `rejected`: the broker refused it. `skipped`: never reached the broker (not online in time, trading switched off, the plan's allowance, no price, a send that provably failed), or the broker has no record of it. `unresolved`: sent, and we are confirming the result with the broker — do not resend. An unresolved account moves to `filled`, `rejected` or `skipped` once its order is confirmed."},"stateDetail":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"On a `filled` account: how much its order filled, from the order. Null otherwise.","example":"0.01"},"partiallyFilled":{"type":"boolean","description":"On a `filled` account: true when its order filled only in part (`filledVolume` below `volume`)."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/execution-waves/{id}":{"get":{"summary":"Follow a multi-account order","tags":["Waves"],"description":"Poll this after creating a multi-account order. `state` moves `planned → preparing → armed → releasing → settled`: accepted, bringing accounts online, waiting for `executeAt`, sending, and every account has a result. `cancelled` and `abandoned` mean nothing was sent.\n\nEach account in `legs` carries its own state and its own order id — an account's order is an ordinary order, confirmed with the broker and audited like any other.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"clientWaveId":{"type":["null","string"]},"symbol":{"type":["null","string"],"description":"The symbol every account trades. Null when the order named an `instrument`; each leg then shows its own."},"instrument":{"type":["null","string"],"description":"The instrument the order named instead of a symbol, if it did."},"side":{"type":"string","enum":["buy","sell"]},"baseVolume":{"type":["null","string"]},"state":{"type":"string","enum":["planned","preparing","armed","releasing","settled","cancelled","abandoned"]},"stateDetail":{"type":["null","string"]},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"]},"executeAt":{"type":["null","string"],"format":"date-time"},"expiresAt":{"type":["null","string"],"format":"date-time"},"preparedAt":{"type":["null","string"],"format":"date-time"},"releasedAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"},"dispatchSpreadMs":{"type":["null","integer"],"description":"The gap between the first account's order being sent and the last, in milliseconds. As it grows, your accounts are getting different prices."},"retryOf":{"type":["null","string"],"format":"uuid","description":"Set when this multi-account order was made by `POST /v1/execution-waves/{id}/retry`: the one it retries."},"retriedBy":{"type":"array","items":{"type":"string","format":"uuid"},"description":"The multi-account orders made by retrying this one, oldest first."},"summary":{"type":"object","description":"What landed. Deliberately not a success flag — a multi-account order is not all-or-nothing once sent.","properties":{"total":{"type":"integer"},"filled":{"type":"integer"},"partiallyFilled":{"type":"integer","description":"Of `filled`, the accounts whose order filled only in part. Counted within `filled`, not beside it."},"rejected":{"type":"integer"},"skipped":{"type":"integer"},"unresolved":{"type":"integer","description":"Accounts whose result we are still confirming with the broker. Do not resend these."}}},"legs":{"type":"array","description":"One entry per account: the order placed there and how it went.","items":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"The ordinary order placed on this account. Query it like any other."},"symbol":{"type":"string","description":"The broker symbol this account trades.","example":"XAUUSD.a"},"volume":{"type":["null","string"]},"state":{"type":"string","enum":["pending","preparing","ready","dispatched","filled","rejected","skipped","unresolved"],"description":"`pending`/`preparing`: being brought online. `ready`: online and waiting. `dispatched`: sent, awaiting the broker. `filled`: the broker filled it, fully or in part. `rejected`: the broker refused it. `skipped`: never reached the broker (not online in time, trading switched off, the plan's allowance, no price, a send that provably failed), or the broker has no record of it. `unresolved`: sent, and we are confirming the result with the broker — do not resend. An unresolved account moves to `filled`, `rejected` or `skipped` once its order is confirmed."},"stateDetail":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"On a `filled` account: how much its order filled, from the order. Null otherwise.","example":"0.01"},"partiallyFilled":{"type":"boolean","description":"On a `filled` account: true when its order filled only in part (`filledVolume` below `volume`)."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/execution-waves/{id}/cancel":{"post":{"summary":"Cancel a multi-account order before it is sent","tags":["Waves"],"description":"Only while nothing has been sent. Once orders are going out there is no cancelling them — `cancelled` would claim nothing was sent, and that is exactly the promise we can no longer make.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"clientWaveId":{"type":["null","string"]},"symbol":{"type":["null","string"],"description":"The symbol every account trades. Null when the order named an `instrument`; each leg then shows its own."},"instrument":{"type":["null","string"],"description":"The instrument the order named instead of a symbol, if it did."},"side":{"type":"string","enum":["buy","sell"]},"baseVolume":{"type":["null","string"]},"state":{"type":"string","enum":["planned","preparing","armed","releasing","settled","cancelled","abandoned"]},"stateDetail":{"type":["null","string"]},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"]},"executeAt":{"type":["null","string"],"format":"date-time"},"expiresAt":{"type":["null","string"],"format":"date-time"},"preparedAt":{"type":["null","string"],"format":"date-time"},"releasedAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"},"dispatchSpreadMs":{"type":["null","integer"],"description":"The gap between the first account's order being sent and the last, in milliseconds. As it grows, your accounts are getting different prices."},"retryOf":{"type":["null","string"],"format":"uuid","description":"Set when this multi-account order was made by `POST /v1/execution-waves/{id}/retry`: the one it retries."},"retriedBy":{"type":"array","items":{"type":"string","format":"uuid"},"description":"The multi-account orders made by retrying this one, oldest first."},"summary":{"type":"object","description":"What landed. Deliberately not a success flag — a multi-account order is not all-or-nothing once sent.","properties":{"total":{"type":"integer"},"filled":{"type":"integer"},"partiallyFilled":{"type":"integer","description":"Of `filled`, the accounts whose order filled only in part. Counted within `filled`, not beside it."},"rejected":{"type":"integer"},"skipped":{"type":"integer"},"unresolved":{"type":"integer","description":"Accounts whose result we are still confirming with the broker. Do not resend these."}}},"legs":{"type":"array","description":"One entry per account: the order placed there and how it went.","items":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"The ordinary order placed on this account. Query it like any other."},"symbol":{"type":"string","description":"The broker symbol this account trades.","example":"XAUUSD.a"},"volume":{"type":["null","string"]},"state":{"type":"string","enum":["pending","preparing","ready","dispatched","filled","rejected","skipped","unresolved"],"description":"`pending`/`preparing`: being brought online. `ready`: online and waiting. `dispatched`: sent, awaiting the broker. `filled`: the broker filled it, fully or in part. `rejected`: the broker refused it. `skipped`: never reached the broker (not online in time, trading switched off, the plan's allowance, no price, a send that provably failed), or the broker has no record of it. `unresolved`: sent, and we are confirming the result with the broker — do not resend. An unresolved account moves to `filled`, `rejected` or `skipped` once its order is confirmed."},"stateDetail":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"On a `filled` account: how much its order filled, from the order. Null otherwise.","example":"0.01"},"partiallyFilled":{"type":"boolean","description":"On a `filled` account: true when its order filled only in part (`filledVolume` below `volume`)."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/execution-waves/{id}/retry":{"post":{"summary":"Retry the accounts a multi-account order did not reach","tags":["Waves"],"description":"Places a new multi-account order for the accounts of this one that were `skipped` (never sent: not online in time, trading switched off, no price). Same market, side, per-account volumes, stops and comment. Add `rejected` to `include` to retry the accounts the broker refused too. A `cancelled` or `abandoned` order sent nothing, so every account is retried.\n\nOnly once the order has ended (`settled`, `cancelled` or `abandoned`); before that, **409** `WAVE_NOT_ENDED`. **409** `NOTHING_TO_RETRY` when no account matches. An `unresolved` account is never retried: it may have executed.\n\nThe new order is checked like any new one (plan, accounts, the key's limits) and is linked both ways: its `retryOf` is this order, and this order's `retriedBy` lists it. **An `Idempotency-Key` is required**; the same key again returns the same new order (200, `idempotent-replay: true`).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"All optional. Without a body, every `skipped` account is retried with the original's barrier policy.","properties":{"include":{"type":"array","items":{"type":"string","enum":["skipped","rejected"]},"minItems":1,"uniqueItems":true,"default":["skipped"],"description":"Which accounts of a settled multi-account order to retry, by their result. `skipped` (the default) is the accounts that never reached the broker; add `rejected` to retry the ones the broker refused too. A cancelled or abandoned one sent nothing, so every account is retried whatever this says."},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"Only these accounts, of those `include` selects."},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"],"description":"Default: the original's."},"executeAt":{"type":"string","format":"date-time","description":"When to send. Omit to send as soon as every account is online."},"expiresAt":{"type":"string","format":"date-time","description":"Stop waiting for accounts that are not online after this."}}}}},"description":"All optional. Without a body, every `skipped` account is retried with the original's barrier policy."},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","maxLength":200},"example":"3f0c9a52-8a8e-4f7e-9b0e-6c1d2f5a7b10","in":"header","name":"idempotency-key","required":false,"description":"Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused."}],"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"clientWaveId":{"type":["null","string"]},"symbol":{"type":["null","string"],"description":"The symbol every account trades. Null when the order named an `instrument`; each leg then shows its own."},"instrument":{"type":["null","string"],"description":"The instrument the order named instead of a symbol, if it did."},"side":{"type":"string","enum":["buy","sell"]},"baseVolume":{"type":["null","string"]},"state":{"type":"string","enum":["planned","preparing","armed","releasing","settled","cancelled","abandoned"]},"stateDetail":{"type":["null","string"]},"barrierPolicy":{"type":"string","enum":["release-ready","all-or-nothing","wait"]},"executeAt":{"type":["null","string"],"format":"date-time"},"expiresAt":{"type":["null","string"],"format":"date-time"},"preparedAt":{"type":["null","string"],"format":"date-time"},"releasedAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"},"dispatchSpreadMs":{"type":["null","integer"],"description":"The gap between the first account's order being sent and the last, in milliseconds. As it grows, your accounts are getting different prices."},"retryOf":{"type":["null","string"],"format":"uuid","description":"Set when this multi-account order was made by `POST /v1/execution-waves/{id}/retry`: the one it retries."},"retriedBy":{"type":"array","items":{"type":"string","format":"uuid"},"description":"The multi-account orders made by retrying this one, oldest first."},"summary":{"type":"object","description":"What landed. Deliberately not a success flag — a multi-account order is not all-or-nothing once sent.","properties":{"total":{"type":"integer"},"filled":{"type":"integer"},"partiallyFilled":{"type":"integer","description":"Of `filled`, the accounts whose order filled only in part. Counted within `filled`, not beside it."},"rejected":{"type":"integer"},"skipped":{"type":"integer"},"unresolved":{"type":"integer","description":"Accounts whose result we are still confirming with the broker. Do not resend these."}}},"legs":{"type":"array","description":"One entry per account: the order placed there and how it went.","items":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"The ordinary order placed on this account. Query it like any other."},"symbol":{"type":"string","description":"The broker symbol this account trades.","example":"XAUUSD.a"},"volume":{"type":["null","string"]},"state":{"type":"string","enum":["pending","preparing","ready","dispatched","filled","rejected","skipped","unresolved"],"description":"`pending`/`preparing`: being brought online. `ready`: online and waiting. `dispatched`: sent, awaiting the broker. `filled`: the broker filled it, fully or in part. `rejected`: the broker refused it. `skipped`: never reached the broker (not online in time, trading switched off, the plan's allowance, no price, a send that provably failed), or the broker has no record of it. `unresolved`: sent, and we are confirming the result with the broker — do not resend. An unresolved account moves to `filled`, `rejected` or `skipped` once its order is confirmed."},"stateDetail":{"type":["null","string"]},"filledVolume":{"type":["null","string"],"description":"On a `filled` account: how much its order filled, from the order. Null otherwise.","example":"0.01"},"partiallyFilled":{"type":"boolean","description":"On a `filled` account: true when its order filled only in part (`filledVolume` below `volume`)."},"sentAt":{"type":["null","string"],"format":"date-time"},"settledAt":{"type":["null","string"],"format":"date-time"}}}},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"422":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/execution-waves/{id}/close":{"post":{"summary":"Close the positions a multi-account order opened","tags":["Waves"],"description":"Closes, on every account at once, the position each `filled` account's order opened, and answers with a result for each account. Each close is an ordinary close order, placed exactly as `POST /v1/accounts/{id}/positions/{positionId}/close` places one: never refused for the plan's allowance, refused when trading is switched off. Send `accountIds` to close only some accounts.\n\n**An `Idempotency-Key` is required.** A repeated close would not close twice; it would open opposing positions. Each account's close is keyed from yours, so the same key again answers with the first result (`idempotent-replay: true`) and never sends a second close.\n\nPer account, `result` is `closed`, `not_found` (already closed), `rejected` (the broker refused), `unresolved` (sent, result being confirmed: **do not resend**; poll `closeOrderId`) or `skipped` (nothing sent; `detail` says why). Only once the order has ended; before that, **409** `WAVE_NOT_ENDED`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Optional. Without a body, every account of the multi-account order is closed.","properties":{"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"Close only these accounts' positions. Each must be an account of this multi-account order."}}}}},"description":"Optional. Without a body, every account of the multi-account order is closed."},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","maxLength":200},"example":"3f0c9a52-8a8e-4f7e-9b0e-6c1d2f5a7b10","in":"header","name":"idempotency-key","required":false,"description":"Any unique string, usually a UUID. A retry with the same key and body returns the first answer instead of placing a second order; the same key with a different body is refused."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"waveId":{"type":"string","format":"uuid"},"summary":{"type":"object","properties":{"total":{"type":"integer"},"closed":{"type":"integer"},"notFound":{"type":"integer"},"rejected":{"type":"integer"},"unresolved":{"type":"integer"},"skipped":{"type":"integer"}}},"legs":{"type":"array","description":"One entry per account: the position its order opened and what happened when it was closed.","items":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"orderId":{"type":["null","string"],"format":"uuid","description":"The order that opened the position."},"positionId":{"type":["null","string"],"description":"The position's ticket: the order's `brokerPositionId`, or its `brokerOrderId` until that is set."},"result":{"type":"string","enum":["closed","not_found","rejected","unresolved","skipped"],"description":"`closed`: the broker closed it. `not_found`: already closed, or no such open position. `rejected`: the broker refused the close. `unresolved`: sent, and we are confirming the result with the broker — do not resend; poll `closeOrderId`. `skipped`: nothing was sent, and `detail` says why (the account's order did not fill, the account is not online, trading is switched off)."},"closeOrderId":{"type":["null","string"],"format":"uuid","description":"The close order, an ordinary order. Null when nothing was sent."},"detail":{"type":["null","string"]}}}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/status":{"get":{"summary":"Whether copy trading is running","tags":["Copy trading"],"description":"`paused` true while copy trading is paused (it is coming soon): strategies and subscriptions can be read, paused and deleted, but nothing that starts copying is taken (503 `COPY_TRADING_PAUSED`), nothing is copied, and no follower is billed. `message` says so in a sentence, or is null.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","required":["paused","message"],"properties":{"paused":{"type":"boolean"},"message":{"type":["null","string"]}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/strategies":{"get":{"summary":"List strategies","tags":["Copy trading"],"description":"This workspace's copy-trading strategies, newest first, archived ones included. Paginated by cursor.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":500},"in":"query","name":"limit","required":false,"description":"Default: `100`."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The previous page's `nextCursor`."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid","description":"The master account."},"name":{"type":"string"},"status":{"type":"string","enum":["active","paused","archived"],"description":"`paused`: the master is not watched and nothing is copied until it is resumed. `archived`: gone; the account can be a strategy again."},"masterAlwaysOn":{"type":"boolean","description":"False when the master was switched away from always_on since: it may be stopped when idle, and nothing is copied while it is offline."},"followers":{"type":"integer","description":"Subscriptions that copy it now (active or close_only)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"],"description":"Pass as `cursor` to continue."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Make an account a strategy","tags":["Copy trading"],"description":"Marks an account as a strategy: its trades are copied to every account that subscribes to it. The account must be `always_on` — a master traded by hand never sends fxapis an order, so an idle terminal would be stopped — and a hedging account, and must not follow a strategy itself. One live strategy per account. A member confirms it is them (step-up). While copy trading is paused on this server (`GET /v1/copy/status`), this answers 503 `COPY_TRADING_PAUSED`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","name"],"additionalProperties":false,"properties":{"accountId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":80,"example":"Gold scalper"}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid","description":"The master account."},"name":{"type":"string"},"status":{"type":"string","enum":["active","paused","archived"],"description":"`paused`: the master is not watched and nothing is copied until it is resumed. `archived`: gone; the account can be a strategy again."},"masterAlwaysOn":{"type":"boolean","description":"False when the master was switched away from always_on since: it may be stopped when idle, and nothing is copied while it is offline."},"followers":{"type":"integer","description":"Subscriptions that copy it now (active or close_only)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/strategies/{id}":{"get":{"summary":"Fetch a strategy","tags":["Copy trading"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid","description":"The master account."},"name":{"type":"string"},"status":{"type":"string","enum":["active","paused","archived"],"description":"`paused`: the master is not watched and nothing is copied until it is resumed. `archived`: gone; the account can be a strategy again."},"masterAlwaysOn":{"type":"boolean","description":"False when the master was switched away from always_on since: it may be stopped when idle, and nothing is copied while it is offline."},"followers":{"type":"integer","description":"Subscriptions that copy it now (active or close_only)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"patch":{"summary":"Rename, pause or resume a strategy","tags":["Copy trading"],"description":"A paused strategy's master is not watched, and nothing is copied — closes included — until it is resumed; the drift check then puts followers right. Resuming asks a member to confirm it is them (step-up), needs a plan with copy trading, and is refused as a whole (403 `KEY_LIMIT_EXCEEDED`, naming the account) when the caller may not open on one of the active followers — a connected app's consent list, a key's `accountIds`, or a key with limits and someone else's subscription. Pause that subscription first. Renaming and pausing always work; resuming is refused while copy trading is paused on this server (503 `COPY_TRADING_PAUSED`, `GET /v1/copy/status`).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":80},"status":{"type":"string","enum":["active","paused"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid","description":"The master account."},"name":{"type":"string"},"status":{"type":"string","enum":["active","paused","archived"],"description":"`paused`: the master is not watched and nothing is copied until it is resumed. `archived`: gone; the account can be a strategy again."},"masterAlwaysOn":{"type":"boolean","description":"False when the master was switched away from always_on since: it may be stopped when idle, and nothing is copied while it is offline."},"followers":{"type":"integer","description":"Subscriptions that copy it now (active or close_only)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"delete":{"summary":"Archive a strategy","tags":["Copy trading"],"description":"Only once no subscription copies it (pause or delete them first). Its executions and links stay in the log, and its paused or stopped subscriptions stay, unable to resume; the account can become a strategy again.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"accountId":{"type":"string","format":"uuid","description":"The master account."},"name":{"type":"string"},"status":{"type":"string","enum":["active","paused","archived"],"description":"`paused`: the master is not watched and nothing is copied until it is resumed. `archived`: gone; the account can be a strategy again."},"masterAlwaysOn":{"type":"boolean","description":"False when the master was switched away from always_on since: it may be stopped when idle, and nothing is copied while it is offline."},"followers":{"type":"integer","description":"Subscriptions that copy it now (active or close_only)."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/subscriptions":{"get":{"summary":"List subscriptions","tags":["Copy trading"],"description":"Followers, newest first, with their status, settings, equity, today's profit where the figures allow, and their last execution. Paginated by cursor.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"strategyId","required":false},{"schema":{"type":"string","format":"uuid"},"in":"query","name":"followerAccountId","required":false},{"schema":{"type":"integer","minimum":1,"maximum":500},"in":"query","name":"limit","required":false,"description":"Default: `100`."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The previous page's `nextCursor`."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"strategyId":{"type":"string","format":"uuid"},"followerAccountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["active","paused","close_only","stopped"],"description":"`active` copies everything; `paused` nothing; `close_only` closes and partial closes only; `stopped` nothing until reset (a risk limit, a netting follower, a revoked creator) — or, with `deleting`, until it is gone."},"stopReason":{"type":["null","string"],"description":"Why it stopped: `risk_limit:<day|week|month|lifetime>:<balance|equity>`, with `:unverified` when the account's deposits and withdrawals could not be confirmed; `netting_not_supported`; `creator_revoked`; `deleted` while a deletion closes its positions.","example":"risk_limit:day:equity"},"stopDetail":{"type":["null","string"],"description":"`stopReason` in words."},"stoppedAt":{"type":["null","string"],"format":"date-time"},"deleting":{"type":"boolean","description":"Deleted with `closePositions=true` and still closing its positions: it is removed once they are closed. Delete again to retry closes that failed."},"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"default":"balance_ratio","type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"]},"multiplier":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":100},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"required":["mode","multiplier"],"additionalProperties":false},"reverse":{"default":false,"type":"boolean"},"copySlTp":{"default":"always","type":"string","enum":["off","on_open","always"]},"symbols":{"type":"object","properties":{"allow":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"default":{},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"required":["allow","block","map"],"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"default":null,"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}]},"maxOpenPositions":{"default":null,"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}]},"minLots":{"default":"skip","type":"string","enum":["skip","use_min"]}},"required":["maxLots","maxOpenPositions","minLots"],"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"default":30,"type":"integer","minimum":1,"maximum":600},"maxDeviationPoints":{"default":null,"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"copyExistingOnStart":{"default":false,"type":"boolean"}},"required":["maxDelaySeconds","maxDeviationPoints","copyExistingOnStart"],"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"default":[],"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"default":false,"type":"boolean"}},"required":["period","metric","closePositions"],"additionalProperties":false}}},"required":["limits"],"additionalProperties":false}},"required":["sizing","reverse","copySlTp","symbols","limits","late","risk"],"additionalProperties":false,"description":"How this follower copies, every field filled in."},"follower":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"login":{"type":"string"},"server":{"type":"string"},"state":{"type":"string"},"equity":{"type":["null","string"]},"todayProfit":{"type":["null","string"],"description":"Equity now against the first figures read today (UTC) for a day risk limit; null until there are both."}}},"lastExecution":{"type":["null","object"],"properties":{"status":{"type":"string"},"reason":{"type":["null","string"]},"createdAt":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"],"description":"Pass as `cursor` to continue."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Subscribe an account to a strategy","tags":["Copy trading"],"description":"The follower copies the strategy's master from now on, with its own settings; every setting has a default. Same workspace, hedging accounts only, and an account cannot be a master and a follower at once. Counts against the plan's followers when it starts `active`. A member confirms it is them (step-up). While copy trading is paused on this server (`GET /v1/copy/status`), this answers 503 `COPY_TRADING_PAUSED`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["strategyId","followerAccountId"],"additionalProperties":false,"properties":{"strategyId":{"type":"string","format":"uuid"},"followerAccountId":{"type":"string","format":"uuid"},"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"],"description":"Default: `\"balance_ratio\"`."},"multiplier":{"type":"number","exclusiveMinimum":0,"maximum":100,"description":"Default: `1`."},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"additionalProperties":false},"reverse":{"type":"boolean","description":"Default: `false`."},"copySlTp":{"type":"string","enum":["off","on_open","always"],"description":"Default: `\"always\"`."},"symbols":{"type":"object","properties":{"allow":{"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}],"description":"Default: `null`."},"maxOpenPositions":{"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}],"description":"Default: `null`."},"minLots":{"type":"string","enum":["skip","use_min"],"description":"Default: `\"skip\"`."}},"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"type":"integer","minimum":1,"maximum":600,"description":"Default: `30`."},"maxDeviationPoints":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}],"description":"Default: `null`."},"copyExistingOnStart":{"type":"boolean","description":"Default: `false`."}},"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"type":"boolean","description":"Default: `false`."}},"required":["period","metric"],"additionalProperties":false}}},"additionalProperties":false}},"additionalProperties":false,"description":"How this follower copies. Every field has a default; send only what differs. On a change, objects merge key by key and lists (and `symbols.map`) replace."},"status":{"type":"string","enum":["active","paused"],"description":"Default: `\"active\"`."}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"strategyId":{"type":"string","format":"uuid"},"followerAccountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["active","paused","close_only","stopped"],"description":"`active` copies everything; `paused` nothing; `close_only` closes and partial closes only; `stopped` nothing until reset (a risk limit, a netting follower, a revoked creator) — or, with `deleting`, until it is gone."},"stopReason":{"type":["null","string"],"description":"Why it stopped: `risk_limit:<day|week|month|lifetime>:<balance|equity>`, with `:unverified` when the account's deposits and withdrawals could not be confirmed; `netting_not_supported`; `creator_revoked`; `deleted` while a deletion closes its positions.","example":"risk_limit:day:equity"},"stopDetail":{"type":["null","string"],"description":"`stopReason` in words."},"stoppedAt":{"type":["null","string"],"format":"date-time"},"deleting":{"type":"boolean","description":"Deleted with `closePositions=true` and still closing its positions: it is removed once they are closed. Delete again to retry closes that failed."},"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"default":"balance_ratio","type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"]},"multiplier":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":100},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"required":["mode","multiplier"],"additionalProperties":false},"reverse":{"default":false,"type":"boolean"},"copySlTp":{"default":"always","type":"string","enum":["off","on_open","always"]},"symbols":{"type":"object","properties":{"allow":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"default":{},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"required":["allow","block","map"],"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"default":null,"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}]},"maxOpenPositions":{"default":null,"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}]},"minLots":{"default":"skip","type":"string","enum":["skip","use_min"]}},"required":["maxLots","maxOpenPositions","minLots"],"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"default":30,"type":"integer","minimum":1,"maximum":600},"maxDeviationPoints":{"default":null,"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"copyExistingOnStart":{"default":false,"type":"boolean"}},"required":["maxDelaySeconds","maxDeviationPoints","copyExistingOnStart"],"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"default":[],"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"default":false,"type":"boolean"}},"required":["period","metric","closePositions"],"additionalProperties":false}}},"required":["limits"],"additionalProperties":false}},"required":["sizing","reverse","copySlTp","symbols","limits","late","risk"],"additionalProperties":false,"description":"How this follower copies, every field filled in."},"follower":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"login":{"type":"string"},"server":{"type":"string"},"state":{"type":"string"},"equity":{"type":["null","string"]},"todayProfit":{"type":["null","string"],"description":"Equity now against the first figures read today (UTC) for a day risk limit; null until there are both."}}},"lastExecution":{"type":["null","object"],"properties":{"status":{"type":"string"},"reason":{"type":["null","string"]},"createdAt":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/subscriptions/{id}":{"get":{"summary":"Fetch a subscription","tags":["Copy trading"],"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"strategyId":{"type":"string","format":"uuid"},"followerAccountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["active","paused","close_only","stopped"],"description":"`active` copies everything; `paused` nothing; `close_only` closes and partial closes only; `stopped` nothing until reset (a risk limit, a netting follower, a revoked creator) — or, with `deleting`, until it is gone."},"stopReason":{"type":["null","string"],"description":"Why it stopped: `risk_limit:<day|week|month|lifetime>:<balance|equity>`, with `:unverified` when the account's deposits and withdrawals could not be confirmed; `netting_not_supported`; `creator_revoked`; `deleted` while a deletion closes its positions.","example":"risk_limit:day:equity"},"stopDetail":{"type":["null","string"],"description":"`stopReason` in words."},"stoppedAt":{"type":["null","string"],"format":"date-time"},"deleting":{"type":"boolean","description":"Deleted with `closePositions=true` and still closing its positions: it is removed once they are closed. Delete again to retry closes that failed."},"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"default":"balance_ratio","type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"]},"multiplier":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":100},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"required":["mode","multiplier"],"additionalProperties":false},"reverse":{"default":false,"type":"boolean"},"copySlTp":{"default":"always","type":"string","enum":["off","on_open","always"]},"symbols":{"type":"object","properties":{"allow":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"default":{},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"required":["allow","block","map"],"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"default":null,"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}]},"maxOpenPositions":{"default":null,"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}]},"minLots":{"default":"skip","type":"string","enum":["skip","use_min"]}},"required":["maxLots","maxOpenPositions","minLots"],"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"default":30,"type":"integer","minimum":1,"maximum":600},"maxDeviationPoints":{"default":null,"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"copyExistingOnStart":{"default":false,"type":"boolean"}},"required":["maxDelaySeconds","maxDeviationPoints","copyExistingOnStart"],"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"default":[],"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"default":false,"type":"boolean"}},"required":["period","metric","closePositions"],"additionalProperties":false}}},"required":["limits"],"additionalProperties":false}},"required":["sizing","reverse","copySlTp","symbols","limits","late","risk"],"additionalProperties":false,"description":"How this follower copies, every field filled in."},"follower":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"login":{"type":"string"},"server":{"type":"string"},"state":{"type":"string"},"equity":{"type":["null","string"]},"todayProfit":{"type":["null","string"],"description":"Equity now against the first figures read today (UTC) for a day risk limit; null until there are both."}}},"lastExecution":{"type":["null","object"],"properties":{"status":{"type":"string"},"reason":{"type":["null","string"]},"createdAt":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"patch":{"summary":"Change a subscription's settings or status","tags":["Copy trading"],"description":"`settings` is merged into what is there: objects key by key, lists and `symbols.map` replaced. `status` is `active`, `paused` or `close_only`; a stopped subscription is brought back with POST …/reset. Changing sizing, limits, reverse or risk limits, or resuming, asks a member to confirm it is them (step-up); pausing and close_only never do. Moving into `active` or `close_only` counts against the plan's followers. Moving into `active` is refused while copy trading is paused on this server (503 `COPY_TRADING_PAUSED`, `GET /v1/copy/status`); settings, pausing and close_only still work.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"],"description":"Default: `\"balance_ratio\"`."},"multiplier":{"type":"number","exclusiveMinimum":0,"maximum":100,"description":"Default: `1`."},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"additionalProperties":false},"reverse":{"type":"boolean","description":"Default: `false`."},"copySlTp":{"type":"string","enum":["off","on_open","always"],"description":"Default: `\"always\"`."},"symbols":{"type":"object","properties":{"allow":{"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}],"description":"Default: `null`."},"maxOpenPositions":{"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}],"description":"Default: `null`."},"minLots":{"type":"string","enum":["skip","use_min"],"description":"Default: `\"skip\"`."}},"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"type":"integer","minimum":1,"maximum":600,"description":"Default: `30`."},"maxDeviationPoints":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}],"description":"Default: `null`."},"copyExistingOnStart":{"type":"boolean","description":"Default: `false`."}},"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"type":"boolean","description":"Default: `false`."}},"required":["period","metric"],"additionalProperties":false}}},"additionalProperties":false}},"additionalProperties":false,"description":"How this follower copies. Every field has a default; send only what differs. On a change, objects merge key by key and lists (and `symbols.map`) replace."},"status":{"type":"string","enum":["active","paused","close_only"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"strategyId":{"type":"string","format":"uuid"},"followerAccountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["active","paused","close_only","stopped"],"description":"`active` copies everything; `paused` nothing; `close_only` closes and partial closes only; `stopped` nothing until reset (a risk limit, a netting follower, a revoked creator) — or, with `deleting`, until it is gone."},"stopReason":{"type":["null","string"],"description":"Why it stopped: `risk_limit:<day|week|month|lifetime>:<balance|equity>`, with `:unverified` when the account's deposits and withdrawals could not be confirmed; `netting_not_supported`; `creator_revoked`; `deleted` while a deletion closes its positions.","example":"risk_limit:day:equity"},"stopDetail":{"type":["null","string"],"description":"`stopReason` in words."},"stoppedAt":{"type":["null","string"],"format":"date-time"},"deleting":{"type":"boolean","description":"Deleted with `closePositions=true` and still closing its positions: it is removed once they are closed. Delete again to retry closes that failed."},"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"default":"balance_ratio","type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"]},"multiplier":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":100},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"required":["mode","multiplier"],"additionalProperties":false},"reverse":{"default":false,"type":"boolean"},"copySlTp":{"default":"always","type":"string","enum":["off","on_open","always"]},"symbols":{"type":"object","properties":{"allow":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"default":{},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"required":["allow","block","map"],"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"default":null,"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}]},"maxOpenPositions":{"default":null,"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}]},"minLots":{"default":"skip","type":"string","enum":["skip","use_min"]}},"required":["maxLots","maxOpenPositions","minLots"],"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"default":30,"type":"integer","minimum":1,"maximum":600},"maxDeviationPoints":{"default":null,"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"copyExistingOnStart":{"default":false,"type":"boolean"}},"required":["maxDelaySeconds","maxDeviationPoints","copyExistingOnStart"],"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"default":[],"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"default":false,"type":"boolean"}},"required":["period","metric","closePositions"],"additionalProperties":false}}},"required":["limits"],"additionalProperties":false}},"required":["sizing","reverse","copySlTp","symbols","limits","late","risk"],"additionalProperties":false,"description":"How this follower copies, every field filled in."},"follower":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"login":{"type":"string"},"server":{"type":"string"},"state":{"type":"string"},"equity":{"type":["null","string"]},"todayProfit":{"type":["null","string"],"description":"Equity now against the first figures read today (UTC) for a day risk limit; null until there are both."}}},"lastExecution":{"type":["null","object"],"properties":{"status":{"type":"string"},"reason":{"type":["null","string"]},"createdAt":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"delete":{"summary":"Delete a subscription","tags":["Copy trading"],"description":"`closePositions` is required.\n\n- `true`: the subscription stops at once (`stopped`, `stopReason` `deleted`, `deleting` true) and every position it holds on the follower is closed, by ticket — including one whose copied open is still in flight, once it fills. The closes are recorded before any is sent, so they go even if this request is cut off, and a follower that is offline gets them when it is back. The subscription is removed once they are all closed: 200 with `deleted` true when that happens within this request, otherwise 202 with what is still `pending`. A close the broker refuses (`failed`) keeps the subscription until it is closed: delete again to retry, or with `false` to keep the rest.\n- `false`: the subscription is removed now, and its links with it: the positions stay open on the follower as the account's own, no longer copied, closed or corrected by copy trading (`released` counts them).\n\nEither way the executions log is kept, with `subscriptionId` null.","parameters":[{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"closePositions","required":false},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","description":"True once the subscription is gone; false while its positions are still being closed (202)."},"deleting":{"type":"boolean","description":"True (with 202) while the subscription stays, stopped, closing its positions; it is removed once they are closed."},"closed":{"type":"integer","description":"Positions closed (or found already closed) by this call."},"pending":{"type":"integer","description":"Closes still waiting: for the follower to come online, or for a copied open still in flight. They go when they can."},"failed":{"type":"integer","description":"Closes the broker refused. The subscription stays, stopped, until they are closed: delete again to retry, or with closePositions=false to keep them."},"released":{"type":"integer","description":"With closePositions=false: positions left open on the follower as its own, no longer copied."}}}}}}}},"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","description":"True once the subscription is gone; false while its positions are still being closed (202)."},"deleting":{"type":"boolean","description":"True (with 202) while the subscription stays, stopped, closing its positions; it is removed once they are closed."},"closed":{"type":"integer","description":"Positions closed (or found already closed) by this call."},"pending":{"type":"integer","description":"Closes still waiting: for the follower to come online, or for a copied open still in flight. They go when they can."},"failed":{"type":"integer","description":"Closes the broker refused. The subscription stays, stopped, until they are closed: delete again to retry, or with closePositions=false to keep them."},"released":{"type":"integer","description":"With closePositions=false: positions left open on the follower as its own, no longer copied."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/subscriptions/{id}/reset":{"post":{"summary":"Reset a stopped subscription","tags":["Copy trading"],"description":"Back to `active` (or to `paused`, if it was paused when it stopped), with every risk period measured afresh from the next figures read. Back to `active` counts against the plan's followers. Needs a plan with copy trading, and asks a member to confirm it is them (step-up). A stop-out's closes still pending keep going. While copy trading is paused on this server (`GET /v1/copy/status`), this answers 503 `COPY_TRADING_PAUSED`.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"strategyId":{"type":"string","format":"uuid"},"followerAccountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["active","paused","close_only","stopped"],"description":"`active` copies everything; `paused` nothing; `close_only` closes and partial closes only; `stopped` nothing until reset (a risk limit, a netting follower, a revoked creator) — or, with `deleting`, until it is gone."},"stopReason":{"type":["null","string"],"description":"Why it stopped: `risk_limit:<day|week|month|lifetime>:<balance|equity>`, with `:unverified` when the account's deposits and withdrawals could not be confirmed; `netting_not_supported`; `creator_revoked`; `deleted` while a deletion closes its positions.","example":"risk_limit:day:equity"},"stopDetail":{"type":["null","string"],"description":"`stopReason` in words."},"stoppedAt":{"type":["null","string"],"format":"date-time"},"deleting":{"type":"boolean","description":"Deleted with `closePositions=true` and still closing its positions: it is removed once they are closed. Delete again to retry closes that failed."},"settings":{"type":"object","properties":{"sizing":{"type":"object","properties":{"mode":{"default":"balance_ratio","type":"string","enum":["balance_ratio","equity_ratio","multiplier","fixed_lots","risk_percent"]},"multiplier":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":100},"lots":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"riskPercent":{"type":"number","minimum":0.01,"maximum":10}},"required":["mode","multiplier"],"additionalProperties":false},"reverse":{"default":false,"type":"boolean"},"copySlTp":{"default":"always","type":"string","enum":["off","on_open","always"]},"symbols":{"type":"object","properties":{"allow":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"block":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}},"map":{"default":{},"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"},"additionalProperties":{"type":"string","minLength":1,"maxLength":32,"pattern":"^\\S+$"}}},"required":["allow","block","map"],"additionalProperties":false},"limits":{"type":"object","properties":{"maxLots":{"default":null,"anyOf":[{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},{"type":"null"}]},"maxOpenPositions":{"default":null,"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}]},"minLots":{"default":"skip","type":"string","enum":["skip","use_min"]}},"required":["maxLots","maxOpenPositions","minLots"],"additionalProperties":false},"late":{"type":"object","properties":{"maxDelaySeconds":{"default":30,"type":"integer","minimum":1,"maximum":600},"maxDeviationPoints":{"default":null,"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]},"copyExistingOnStart":{"default":false,"type":"boolean"}},"required":["maxDelaySeconds","maxDeviationPoints","copyExistingOnStart"],"additionalProperties":false},"risk":{"type":"object","properties":{"limits":{"default":[],"maxItems":8,"type":"array","items":{"type":"object","properties":{"period":{"type":"string","enum":["day","week","month","lifetime"]},"metric":{"type":"string","enum":["balance","equity"]},"maxLossPercent":{"type":"number","exclusiveMinimum":0,"maximum":100},"maxLossAmount":{"type":"string","pattern":"^\\d+(\\.\\d{1,8})?$"},"closePositions":{"default":false,"type":"boolean"}},"required":["period","metric","closePositions"],"additionalProperties":false}}},"required":["limits"],"additionalProperties":false}},"required":["sizing","reverse","copySlTp","symbols","limits","late","risk"],"additionalProperties":false,"description":"How this follower copies, every field filled in."},"follower":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":["null","string"]},"login":{"type":"string"},"server":{"type":"string"},"state":{"type":"string"},"equity":{"type":["null","string"]},"todayProfit":{"type":["null","string"],"description":"Equity now against the first figures read today (UTC) for a day risk limit; null until there are both."}}},"lastExecution":{"type":["null","object"],"properties":{"status":{"type":"string"},"reason":{"type":["null","string"]},"createdAt":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/subscriptions/{id}/links":{"get":{"summary":"List a subscription's links","tags":["Copy trading"],"description":"Which follower position copies which master position. Closes, partial closes and the drift check go through these, never by symbol. Open links only, or with `state=all` those closed in the last 30 days too.","parameters":[{"schema":{"type":"string","enum":["open","all"]},"in":"query","name":"state","required":false,"description":"Default: `\"open\"`."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subscriptionId":{"type":"string","format":"uuid"},"masterPositionId":{"type":"string"},"followerAccountId":{"type":"string","format":"uuid"},"followerPositionId":{"type":["null","string"],"description":"Null until the opening order's position is known."},"symbol":{"type":"string","description":"The follower's symbol."},"side":{"type":"string","enum":["buy","sell"],"description":"The follower's side (reversed when the subscription reverses)."},"followerVolume":{"type":"string"},"masterVolume":{"type":"string"},"openedAt":{"type":"string","format":"date-time"},"closedAt":{"type":["null","string"],"format":"date-time"}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/copy/executions":{"get":{"summary":"List copy executions","tags":["Copy trading"],"description":"The copy-trading log: what each master change (and each drift correction or stop-out close) did on each follower, newest first — executed, skipped, failed or still pending — with the reason, in words, and the follower's order. Paginated by cursor.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"query","name":"strategyId","required":false},{"schema":{"type":"string","format":"uuid"},"in":"query","name":"subscriptionId","required":false},{"schema":{"type":"string","format":"uuid"},"in":"query","name":"followerAccountId","required":false},{"schema":{"type":"string","enum":["executed","skipped","failed","pending"]},"in":"query","name":"status","required":false},{"schema":{"type":"string","enum":["too_late","price_moved","follower_offline","below_min_volume","no_stop_loss","stale_figures","symbol_unmapped","symbol_blocked","limit_exceeded","not_enough_margin","market_closed","feature_not_included","quota_exceeded","broker_rejected","unresolved","netting_not_supported","internal_error","follower_changed"]},"in":"query","name":"reason","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"since","required":false,"description":"Only executions created at or after this moment."},{"schema":{"type":"integer","minimum":1,"maximum":200},"in":"query","name":"limit","required":false,"description":"Default: `50`."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"The previous page's `nextCursor`."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"strategyId":{"type":"string","format":"uuid"},"subscriptionId":{"type":["null","string"],"format":"uuid","description":"Null once the subscription was deleted."},"followerAccountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["executed","skipped","failed","pending"],"description":"`pending` while in flight, or while a close waits for its follower to come back online."},"reason":{"type":["null","string"],"enum":["too_late","price_moved","follower_offline","below_min_volume","no_stop_loss","stale_figures","symbol_unmapped","symbol_blocked","limit_exceeded","not_enough_margin","market_closed","feature_not_included","quota_exceeded","broker_rejected","unresolved","netting_not_supported","internal_error","follower_changed",null],"description":"Why it was skipped or failed:\n\n- `too_late`: The change was seen too long ago to copy (late.maxDelaySeconds).\n- `price_moved`: The price moved further from the master's than late.maxDeviationPoints allows.\n- `follower_offline`: The follower was offline and could not be brought online in time.\n- `below_min_volume`: The sized volume was below the follower's minimum, and limits.minLots is skip.\n- `no_stop_loss`: risk_percent sizing needs a stop loss, and the master's trade had none.\n- `stale_figures`: The follower's balance or equity could not be read recently enough to size the trade.\n- `symbol_unmapped`: The master's symbol has no match on the follower; add it to symbols.map.\n- `symbol_blocked`: The symbol is blocked, or not on the allow list, in this subscription's settings.\n- `limit_exceeded`: A limit stopped it: the subscription's maxLots or maxOpenPositions, or the creating key's limits.\n- `not_enough_margin`: The follower did not have the margin for it.\n- `market_closed`: The market was closed.\n- `feature_not_included`: The workspace's plan does not include copy trading.\n- `quota_exceeded`: The workspace's plan quota was used up.\n- `broker_rejected`: The follower's broker refused it.\n- `unresolved`: Sent, with no answer from the broker yet: never resent, and settled once the broker's records are read.\n- `netting_not_supported`: A netting account: copy trading copies between hedging accounts only.\n- `internal_error`: Something on fxapis's side failed, not at the broker; the follower's order may not have been sent. Check the follower's positions.\n- `follower_changed`: The follower's position was changed outside copying (part closed by hand), so its link now follows what it holds."},"detail":{"type":["null","string"],"description":"In words: the broker's answer, or why."},"orderId":{"type":["null","string"],"format":"uuid","description":"The follower's order. Fetch it with GET /v1/orders/{id}."},"requestedVolume":{"type":["null","string"]},"latencyMs":{"type":["null","integer"],"description":"From the master change being seen to the follower's order being sent. Broker execution time is extra."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"signal":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["open","close","reduce","modify","drift"]},"correction":{"type":["null","string"],"enum":["open","close","reduce","modify","stop_out","rebase",null],"description":"On a drift signal: what it corrected. `stop_out` closes a position for a risk limit or a deletion; `rebase` follows a position changed on the follower (no order)."},"masterPositionId":{"type":"string"},"symbol":{"type":"string","description":"The master's symbol."},"side":{"type":"string","enum":["buy","sell"]},"volumeBefore":{"type":["null","string"]},"volumeAfter":{"type":["null","string"]},"price":{"type":["null","string"]},"stopLoss":{"type":["null","string"]},"takeProfit":{"type":["null","string"]},"detectedAt":{"type":"string","format":"date-time"}}}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"],"description":"Pass as `cursor` to continue."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets":{"get":{"summary":"Markets with daily official data","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"array","items":{"type":"object","required":["symbol","available"],"properties":{"symbol":{"type":"string"},"available":{"type":"boolean"},"asOf":{"type":["null","string"],"format":"date-time"},"source":{"type":["null","string"]}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/pairs":{"get":{"summary":"Currencies and pairs a watchlist can hold","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["currencies","positioning","maxWatchlist"],"properties":{"currencies":{"type":"array","items":{"type":"string"},"description":"Currencies available for a watchlist pair."},"positioning":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Whether CFTC positioning is published for each currency."},"maxWatchlist":{"type":"integer","description":"Most pairs a watchlist may hold."},"metals":{"type":"array","items":{"type":"string"},"description":"Metals a watchlist may hold (gold and silver against the dollar)."}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/watchlist":{"get":{"summary":"This workspace's watchlist","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"array","items":{"type":"object","required":["symbol","sparkline","source","derived"],"properties":{"symbol":{"type":"string"},"asOf":{"type":["null","string"],"format":"date-time"},"last":{"type":["null","string"]},"change1d":{"type":["null","string"]},"sparkline":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string"},"value":{"type":"string"}}}},"realisedVol20":{"type":["null","string"],"description":"20-day realised volatility."},"source":{"type":"string"},"derived":{"type":"boolean"},"positioning":{"type":["null","object"],"properties":{"net":{"type":"number"},"asOf":{"type":"string"},"currency":{"type":["null","string"],"description":"The currency whose CFTC futures the figure is for."}}},"research":{"type":["null","object"],"properties":{"reportId":{"type":"string"},"horizon":{"type":"string"},"lean":{"type":["null","string"],"enum":["bullish","bearish","neutral",null]},"confidence":{"type":["null","string"],"enum":["low","medium","high",null]}},"description":"The latest research report for this pair, if any."}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/today":{"get":{"summary":"Today for you: your positions, events and research for the next hours","tags":["MarketLabs"],"description":"Events in the next `hours` (default 48) for your held and watched currencies, your open positions and pending orders against them (needs `trading:read` as well), each pair's research lean, and what changed in the last 24 hours. Research, not trading advice.","parameters":[{"schema":{"type":"integer","minimum":24,"maximum":72},"in":"query","name":"hours","required":false},{"schema":{"type":"string"},"in":"query","name":"timeZone","required":false,"description":"IANA time zone, e.g. Europe/London. Times stay in UTC."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["generatedAt","window","exposure","upcoming","leans","sinceYesterday","sources"],"properties":{"generatedAt":{"type":"string","format":"date-time"},"window":{"type":"object","required":["from","to","hours","timeZone"],"properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"hours":{"type":"integer"},"timeZone":{"type":["null","string"]}}},"exposure":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"reason":{"type":"string","description":"Why the block is empty when available is false."},"accounts":{"type":"array","items":{"type":"object","required":["accountId","name","state","observedAt","stale","items"],"properties":{"accountId":{"type":"string"},"name":{"type":"string"},"state":{"type":"string"},"observedAt":{"type":["null","string"],"format":"date-time"},"stale":{"type":"boolean","description":"True when the account was last read more than 15 minutes ago."},"items":{"type":"array","items":{"type":"object","required":["kind","id","symbol","side","volume","currencies","unmapped","pair","nextEvent","eventCount"],"properties":{"kind":{"type":"string","enum":["position","order"]},"id":{"type":"string"},"symbol":{"type":"string","description":"The broker's symbol."},"side":{"type":"string","enum":["buy","sell"]},"volume":{"type":"string"},"currencies":{"type":"array","items":{"type":"string"}},"unmapped":{"type":"boolean","description":"True when the symbol's currencies are not ones the calendar tracks."},"pair":{"type":["null","string"],"description":"The research pair, when the instrument is a tracked currency pair."},"nextEvent":{"type":["null","object"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"currency":{"type":"string"},"impact":{"type":"string","enum":["high","medium","low"]}}},"eventCount":{"type":"integer","description":"High and medium impact events for its currencies in the window."}}}}}}},"ordersNote":{"type":"string"},"eventsAvailable":{"type":"boolean","description":"False when the calendar could not be read, so an item showing no event may still have one."}}},"upcoming":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"reason":{"type":"string","description":"Why the block is empty when available is false."},"events":{"type":"array","items":{"type":"object","required":["id","title","occurredAt","currency","kind","impact","status","confirmed","source","attribution","held"],"properties":{"id":{"type":"string","description":"Stable per series and period, e.g. bls:cpi_mom:2026-10: a rescheduled release keeps its id."},"title":{"type":"string"},"occurredAt":{"type":"string","format":"date-time","description":"When the publisher releases it, in UTC."},"currency":{"type":"string","description":"Three-letter currency code."},"kind":{"type":"string","enum":["release","rate_decision","survey","earnings"]},"impact":{"type":"string","enum":["high","medium","low"],"description":"fxapis' own ranking by topic, not a market forecast."},"unit":{"type":["null","string"],"description":"Unit of actual and previous, e.g. %."},"period":{"type":["null","string"],"description":"The period the figure covers, e.g. Oct 2026 or Q3 2026."},"previous":{"type":["null","string"],"description":"The publisher's figure for the period before, as it stood before this release."},"actual":{"type":["null","string"],"description":"The publisher's figure, once released. Surveys never carry figures."},"revisedPrevious":{"type":["null","string"],"description":"The previous period's figure as revised in this release, when it changed."},"forecast":{"type":["null","string"],"description":"Consensus forecast. Empty until a licensed forecast source is added."},"forecastSource":{"type":["null","string"]},"status":{"type":"string","enum":["scheduled","released","delayed","cancelled"]},"releasedAt":{"type":["null","string"],"format":"date-time","description":"When fxapis first had the figure."},"confirmed":{"type":"boolean","description":"False when the publisher's calendar could not be checked recently: the date may have moved."},"source":{"type":"string"},"figureSource":{"type":["null","string"]},"attribution":{"type":"string","description":"The source credit to show with the event."},"held":{"type":"boolean","description":"True when you hold a position or order in this currency."}}}}}},"leans":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"reason":{"type":"string","description":"Why the block is empty when available is false."},"pairs":{"type":"array","items":{"type":"object","required":["symbol","held","watched","latest","previous"],"properties":{"symbol":{"type":"string"},"held":{"type":"boolean"},"watched":{"type":"boolean"},"latest":{"type":["null","object"],"properties":{"id":{"type":"string"},"symbol":{"type":"string"},"ecbDate":{"type":"string","description":"Date (UTC) of the reference rate the report used."},"status":{"type":"string"},"createdAt":{"type":["null","string"],"format":"date-time"},"referenceRate":{"type":["null","string"]},"views":{"type":"array","items":{"type":"object","required":["horizon","lean","confidence","conclusion"],"properties":{"horizon":{"type":"string","enum":["1d","1w"]},"lean":{"type":["null","string"],"enum":["bullish","bearish","neutral",null]},"confidence":{"type":["null","string"],"enum":["low","medium","high",null]},"conclusion":{"type":"string"}}}}}},"previous":{"type":["null","object"],"properties":{"id":{"type":"string"},"symbol":{"type":"string"},"ecbDate":{"type":"string","description":"Date (UTC) of the reference rate the report used."},"status":{"type":"string"},"createdAt":{"type":["null","string"],"format":"date-time"},"referenceRate":{"type":["null","string"]},"views":{"type":"array","items":{"type":"object","required":["horizon","lean","confidence","conclusion"],"properties":{"horizon":{"type":"string","enum":["1d","1w"]},"lean":{"type":["null","string"],"enum":["bullish","bearish","neutral",null]},"confidence":{"type":["null","string"],"enum":["low","medium","high",null]},"conclusion":{"type":"string"}}}}}}}}}}},"sinceYesterday":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"reason":{"type":"string","description":"Why the block is empty when available is false."},"released":{"type":"array","items":{"type":"object","required":["id","title","occurredAt","currency","kind","impact","status","confirmed","source","attribution"],"properties":{"id":{"type":"string","description":"Stable per series and period, e.g. bls:cpi_mom:2026-10: a rescheduled release keeps its id."},"title":{"type":"string"},"occurredAt":{"type":"string","format":"date-time","description":"When the publisher releases it, in UTC."},"currency":{"type":"string","description":"Three-letter currency code."},"kind":{"type":"string","enum":["release","rate_decision","survey","earnings"]},"impact":{"type":"string","enum":["high","medium","low"],"description":"fxapis' own ranking by topic, not a market forecast."},"unit":{"type":["null","string"],"description":"Unit of actual and previous, e.g. %."},"period":{"type":["null","string"],"description":"The period the figure covers, e.g. Oct 2026 or Q3 2026."},"previous":{"type":["null","string"],"description":"The publisher's figure for the period before, as it stood before this release."},"actual":{"type":["null","string"],"description":"The publisher's figure, once released. Surveys never carry figures."},"revisedPrevious":{"type":["null","string"],"description":"The previous period's figure as revised in this release, when it changed."},"forecast":{"type":["null","string"],"description":"Consensus forecast. Empty until a licensed forecast source is added."},"forecastSource":{"type":["null","string"]},"status":{"type":"string","enum":["scheduled","released","delayed","cancelled"]},"releasedAt":{"type":["null","string"],"format":"date-time","description":"When fxapis first had the figure."},"confirmed":{"type":"boolean","description":"False when the publisher's calendar could not be checked recently: the date may have moved."},"source":{"type":"string"},"figureSource":{"type":["null","string"]},"attribution":{"type":"string","description":"The source credit to show with the event."}}}},"leanChanges":{"type":"array","items":{"type":"object","required":["symbol","horizon","from","to","reportId"],"properties":{"symbol":{"type":"string"},"horizon":{"type":"string"},"from":{"type":["null","string"]},"to":{"type":["null","string"]},"reportId":{"type":"string"}}}},"headlines":{"type":"array","items":{"type":"object","required":["id","title","domain","seen","source","currencies"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"domain":{"type":"string"},"seen":{"type":"string","format":"date-time"},"source":{"type":"string"},"currencies":{"type":"array","items":{"type":"string"}},"sourceName":{"type":["null","string"],"description":"The outlet's name."},"summary":{"type":["null","string"],"description":"When available, a short summary written by fxapis from the headline, not the article."},"url":{"type":["null","string"],"format":"uri"}}}}}},"sources":{"type":"array","items":{"type":"object","required":["id","name","attribution","state"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"attribution":{"type":"string"},"creditUrl":{"type":["null","string"]},"lastSuccess":{"type":["null","string"],"format":"date-time"},"lastFailureAt":{"type":["null","string"],"format":"date-time"},"state":{"type":"string","enum":["fresh","aging","stale","never"]}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets/{symbol}/replay":{"get":{"summary":"Stored daily candles for a market, replayed","tags":["MarketLabs"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"symbol","required":true,"description":"Instrument, such as EURUSD."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["symbol","source","candles","barSize","days"],"properties":{"symbol":{"type":"string"},"source":{"type":"string"},"candles":{"type":"array","items":{"type":"object","required":["time","open","high","low","close"],"properties":{"time":{"type":"integer","description":"Unix seconds."},"open":{"type":"string"},"high":{"type":"string"},"low":{"type":"string"},"close":{"type":"string"}}}},"barSize":{"type":"string"},"days":{"type":"integer","enum":[1,5,20]},"tooCoarseFor":{"type":"array","items":{"type":"string"},"description":"Replay speeds too coarse for this bar size."},"headlines":{"type":"array","items":{"type":"object","additionalProperties":true}},"positioning":{"type":["null","object"],"properties":{"symbol":{"type":"string"},"reportDate":{"type":"string"},"noncommercialNet":{"type":"string"},"commercialNet":{"type":"string"},"source":{"type":"string"},"caption":{"type":"string"}}},"treasury10y":{"type":["null","object"],"properties":{"value":{"type":"string"},"asOf":{"type":"string"},"source":{"type":"string"},"caption":{"type":"string"}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets/{symbol}/candles":{"get":{"summary":"Daily official candles for a market","tags":["MarketLabs"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"symbol","required":true,"description":"Instrument, such as EURUSD."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["symbol","source","candles"],"properties":{"symbol":{"type":"string"},"source":{"type":"string"},"candles":{"type":"array","items":{"type":"object","required":["time","open","high","low","close"],"properties":{"time":{"type":"integer","description":"Unix seconds."},"open":{"type":"string"},"high":{"type":"string"},"low":{"type":"string"},"close":{"type":"string"}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets/{symbol}/series":{"get":{"summary":"A market's reference rate, volatility, positioning and events over time","tags":["MarketLabs"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"symbol","required":true,"description":"Instrument, such as EURUSD."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["symbol","source","derived","points","volatility","positioning","events"],"properties":{"symbol":{"type":"string"},"source":{"type":"string"},"derived":{"type":"boolean"},"points":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string"},"value":{"type":"string"}}}},"volatility":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string"},"value":{"type":"string"}}}},"positioningCurrency":{"type":["null","string"],"description":"The currency whose CFTC futures the positioning series is for."},"positioning":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string"},"dealer":{"type":["null","number"]},"assetManager":{"type":["null","number"]},"leveraged":{"type":["null","number"]},"noncommercial":{"type":["null","number"]}}}},"events":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"currency":{"type":"string"},"impact":{"type":"string","enum":["high","medium","low"]}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/strength":{"get":{"summary":"Relative currency strength","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["window","basis","currencies"],"properties":{"asOf":{"type":["null","string"],"format":"date-time"},"window":{"type":"integer","description":"Days the score is computed over."},"basis":{"type":"string"},"currencies":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"score":{"type":"string"}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/correlation":{"get":{"summary":"Correlation between pairs","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["symbols","window","matrix","basis"],"properties":{"symbols":{"type":"array","items":{"type":"string"}},"window":{"type":"integer"},"matrix":{"type":"array","items":{"type":"array","items":{"type":"number"}},"description":"Correlation matrix, symbols[i] by symbols[j]."},"basis":{"type":"string"}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/news":{"get":{"summary":"Recent headlines","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","title","domain","seen","source","currencies"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"domain":{"type":"string"},"seen":{"type":"string","format":"date-time"},"source":{"type":"string"},"currencies":{"type":"array","items":{"type":"string"}},"sourceName":{"type":["null","string"],"description":"The outlet's name."},"summary":{"type":["null","string"],"description":"When available, a short summary written by fxapis from the headline, not the article."},"url":{"type":["null","string"],"format":"uri"}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/sources":{"get":{"summary":"Freshness of each data source","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","name","attribution","state"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"attribution":{"type":"string"},"creditUrl":{"type":["null","string"]},"lastSuccess":{"type":["null","string"],"format":"date-time"},"lastFailureAt":{"type":["null","string"],"format":"date-time"},"state":{"type":"string","enum":["fresh","aging","stale","never"]}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/events":{"get":{"summary":"Official economic calendar with figures","tags":["MarketLabs"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"currencies","required":false,"description":"Comma-separated, e.g. USD,EUR."},{"schema":{"type":"string","format":"date"},"in":"query","name":"from","required":false},{"schema":{"type":"string","format":"date"},"in":"query","name":"to","required":false},{"schema":{"type":"string"},"in":"query","name":"kind","required":false,"description":"Comma-separated: release, rate_decision, survey, earnings."},{"schema":{"type":"string"},"in":"query","name":"impact","required":false,"description":"Comma-separated: high, medium, low."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["events","blsConfigured","impactBasis"],"properties":{"events":{"type":"array","items":{"type":"object","required":["id","title","occurredAt","currency","kind","impact","status","confirmed","source","attribution"],"properties":{"id":{"type":"string","description":"Stable per series and period, e.g. bls:cpi_mom:2026-10: a rescheduled release keeps its id."},"title":{"type":"string"},"occurredAt":{"type":"string","format":"date-time","description":"When the publisher releases it, in UTC."},"currency":{"type":"string","description":"Three-letter currency code."},"kind":{"type":"string","enum":["release","rate_decision","survey","earnings"]},"impact":{"type":"string","enum":["high","medium","low"],"description":"fxapis' own ranking by topic, not a market forecast."},"unit":{"type":["null","string"],"description":"Unit of actual and previous, e.g. %."},"period":{"type":["null","string"],"description":"The period the figure covers, e.g. Oct 2026 or Q3 2026."},"previous":{"type":["null","string"],"description":"The publisher's figure for the period before, as it stood before this release."},"actual":{"type":["null","string"],"description":"The publisher's figure, once released. Surveys never carry figures."},"revisedPrevious":{"type":["null","string"],"description":"The previous period's figure as revised in this release, when it changed."},"forecast":{"type":["null","string"],"description":"Consensus forecast. Empty until a licensed forecast source is added."},"forecastSource":{"type":["null","string"]},"status":{"type":"string","enum":["scheduled","released","delayed","cancelled"]},"releasedAt":{"type":["null","string"],"format":"date-time","description":"When fxapis first had the figure."},"confirmed":{"type":"boolean","description":"False when the publisher's calendar could not be checked recently: the date may have moved."},"source":{"type":"string"},"figureSource":{"type":["null","string"]},"attribution":{"type":"string","description":"The source credit to show with the event."}}}},"blsConfigured":{"type":"boolean","description":"Whether US labour-market releases (CPI, payrolls) are configured."},"impactBasis":{"type":"string","description":"What the impact ranking is."}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets/{symbol}/intelligence":{"get":{"summary":"Latest shared intelligence for a market","tags":["MarketLabs"],"description":"A cached snapshot shared by every workspace.","parameters":[{"schema":{"type":"string"},"in":"path","name":"symbol","required":true,"description":"Instrument, such as EURUSD."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["symbol","asOf","freshness","classification","summary","baseline"],"properties":{"symbol":{"type":"string"},"asOf":{"type":"string","format":"date-time"},"freshness":{"type":"string","enum":["fresh","stale"]},"classification":{"type":"string"},"summary":{"type":"string"},"baseline":{"type":"string","description":"Decimal string."},"source":{"type":"string"},"attribution":{"type":"string"},"change":{"type":["null","string"]},"riskLevel":{"type":"string"},"headlineNote":{"type":["null","string"]},"headlines":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"title":{"type":"string"},"seen":{"type":"string"},"domain":{"type":"string"},"source":{"type":"string"}}}},"positioning":{"type":["null","object"],"additionalProperties":false,"properties":{"symbol":{"type":"string"},"reportDate":{"type":"string"},"noncommercialNet":{"type":"string"},"commercialNet":{"type":"string"},"source":{"type":"string"},"caption":{"type":"string"}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets/{symbol}/events":{"get":{"summary":"Events attached to the latest shared snapshot","tags":["MarketLabs"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"symbol","required":true,"description":"Instrument, such as EURUSD."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","symbol","title","occurredAt"],"properties":{"id":{"type":"string"},"symbol":{"type":"string"},"title":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/settings":{"get":{"summary":"This workspace's MarketLabs settings","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"patch":{"summary":"Change this workspace's watchlist and settings","tags":["MarketLabs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","additionalProperties":true},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/markets/{symbol}/research":{"get":{"summary":"Today's research for a market","tags":["MarketLabs"],"description":"Research, not trading advice: it places no trade. Confidence is scored against the outcome after the fact.","parameters":[{"schema":{"type":"string"},"in":"path","name":"symbol","required":true,"description":"Instrument, such as EURUSD."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["status","conclusion","evidenceIds","today","report"],"properties":{"status":{"type":"string"},"conclusion":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}},"asOf":{"type":"string","format":"date-time"},"report":{"type":["null","object"],"required":["id","symbol","ecbDate","status","views","notes","bull","bear","summary","upcomingEvents","risk","evidence"],"properties":{"id":{"type":"string"},"symbol":{"type":"string"},"ecbDate":{"type":"string","description":"Date (UTC) of the reference rate the report used."},"status":{"type":"string"},"createdAt":{"type":["null","string"],"format":"date-time"},"referenceRate":{"type":["null","string"]},"views":{"type":"array","items":{"type":"object","required":["horizon","lean","confidence","conclusion"],"properties":{"horizon":{"type":"string","enum":["1d","1w"]},"lean":{"type":["null","string"],"enum":["bullish","bearish","neutral",null]},"confidence":{"type":["null","string"],"enum":["low","medium","high",null]},"conclusion":{"type":"string"}}}},"notes":{"type":"object","properties":{"technical":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"macro":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"news":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"positioning":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}}}},"bull":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"bear":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"summary":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"upcomingEvents":{"type":"array","items":{"type":"object","properties":{"eventId":{"type":"string"},"title":{"type":["null","string"]},"date":{"type":"string"},"bull":{"type":["null","string"]},"bear":{"type":["null","string"]}}}},"risk":{"type":"object","properties":{"invalidation":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"eventRisk":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"dataGaps":{"type":"array","items":{"type":"string"}}}},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"group":{"type":"string"},"source":{"type":"string"},"label":{"type":"string"},"date":{"type":"string"},"value":{"type":["null","string"]},"title":{"type":["null","string"]},"derivedFrom":{"type":"array","items":{"type":"string"}}}}}},"description":"The latest report for this pair, or null when none has been published yet."},"today":{"type":"string","enum":["ready","pending","unavailable"],"description":"Whether today's report is ready, still being written, or unavailable."}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/research":{"get":{"summary":"Past research reports","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","symbol","ecbDate","status","views"],"properties":{"id":{"type":"string"},"symbol":{"type":"string"},"ecbDate":{"type":"string","description":"Date (UTC) of the reference rate the report used."},"status":{"type":"string"},"createdAt":{"type":["null","string"],"format":"date-time"},"referenceRate":{"type":["null","string"]},"views":{"type":"array","items":{"type":"object","required":["horizon","lean","confidence","conclusion"],"properties":{"horizon":{"type":"string","enum":["1d","1w"]},"lean":{"type":["null","string"],"enum":["bullish","bearish","neutral",null]},"confidence":{"type":["null","string"],"enum":["low","medium","high",null]},"conclusion":{"type":"string"}}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/research/track-record":{"get":{"summary":"Research hit rate, per pair and horizon","tags":["MarketLabs"],"description":"Empty until a pair and horizon has reached the minimum number of scored calls.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["minimum","records"],"properties":{"minimum":{"type":"integer","description":"Scored calls needed, per pair and horizon, before a hit rate is shown."},"records":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string"},"horizon":{"type":"string"},"settled":{"type":"integer"},"hits":{"type":["null","integer"]},"hitRate":{"type":["null","string"]},"neutralHitRate":{"type":["null","string"]},"status":{"type":"string"}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/research/calibration":{"get":{"summary":"Research hit rate, by confidence level","tags":["MarketLabs"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["minimum","settled","bins"],"properties":{"minimum":{"type":"integer","description":"Scored calls needed before a hit rate is shown."},"settled":{"type":"integer"},"bins":{"type":"array","items":{"type":"object","properties":{"confidence":{"type":"string","enum":["low","medium","high"]},"settled":{"type":"integer"},"hits":{"type":["null","integer"]},"hitRate":{"type":["null","string"]}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/marketlabs/research/{id}":{"get":{"summary":"One research report, in full","tags":["MarketLabs"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"A report id, rr_ followed by 16 hex characters."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","requestId"],"properties":{"data":{"type":"object","required":["id","symbol","ecbDate","status","views","notes","bull","bear","summary","upcomingEvents","risk","evidence"],"properties":{"id":{"type":"string"},"symbol":{"type":"string"},"ecbDate":{"type":"string","description":"Date (UTC) of the reference rate the report used."},"status":{"type":"string"},"createdAt":{"type":["null","string"],"format":"date-time"},"referenceRate":{"type":["null","string"]},"views":{"type":"array","items":{"type":"object","required":["horizon","lean","confidence","conclusion"],"properties":{"horizon":{"type":"string","enum":["1d","1w"]},"lean":{"type":["null","string"],"enum":["bullish","bearish","neutral",null]},"confidence":{"type":["null","string"],"enum":["low","medium","high",null]},"conclusion":{"type":"string"}}}},"notes":{"type":"object","properties":{"technical":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"macro":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"news":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"positioning":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}}}},"bull":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"bear":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"summary":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"upcomingEvents":{"type":"array","items":{"type":"object","properties":{"eventId":{"type":"string"},"title":{"type":["null","string"]},"date":{"type":"string"},"bull":{"type":["null","string"]},"bear":{"type":["null","string"]}}}},"risk":{"type":"object","properties":{"invalidation":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"eventRisk":{"type":"array","items":{"type":"object","required":["text","evidenceIds"],"properties":{"text":{"type":"string"},"evidenceIds":{"type":"array","items":{"type":"string"}}}}},"dataGaps":{"type":"array","items":{"type":"string"}}}},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"group":{"type":"string"},"source":{"type":"string"},"label":{"type":"string"},"date":{"type":"string"},"value":{"type":["null","string"]},"title":{"type":["null","string"]},"derivedFrom":{"type":"array","items":{"type":"string"}}}}}}},"requestId":{"type":"string"}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/plans":{"get":{"summary":"The available plans","tags":["Billing"],"description":"The plans on offer now: what each includes and what it costs. Prices are in minor units — `9900` is $99.00, never a float.\n\n`accounts` is a capacity limit: you cannot exceed it and be billed for the excess. The monthly allowances can run over where the plan allows it, up to twice the allowance, after which orders are refused — a runaway strategy should not be able to generate an unbounded invoice.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"annualPrice":{"type":["null","integer"],"description":"Minor units a year, billed yearly. Null: monthly only."},"pricing":{"type":"object","description":"How the plan charges. `bundle`: its price buys a fixed allowance. `usage`: its price includes `includedAccounts`, then each account past them costs the band's `unitPrice` a month, always-on accounts `alwaysOnPrice` a month, and opening executions past `executionsPerAccount` × the accounts paid for cost `overagePer1000` per 1,000. `freeDemoAccounts` demo accounts are not charged. Minor units throughout.","properties":{"model":{"type":"string","enum":["bundle","usage"]},"includedAccounts":{"type":"integer"},"accountTiers":{"type":"array","items":{"type":"object","properties":{"upTo":{"type":"integer"},"unitPrice":{"type":"integer"}}}},"alwaysOnPrice":{"type":["null","integer"]},"executionsPerAccount":{"type":"integer"},"overagePer1000":{"type":"integer"},"freeDemoAccounts":{"type":"integer"},"trialDays":{"type":["null","integer"]},"demoOnly":{"type":"boolean"},"includedFollowers":{"type":"integer","description":"Copy-trading followers (subscriptions) the base covers."},"followerPrice":{"type":["null","integer"],"description":"Minor units per follower beyond those included, a month, billed by the day. Null: none sold beyond those included — the plan's cap."},"creditLimit":{"type":["null","object"],"description":"Credit control on a `usage` plan: accounts beyond those included, always-on accounts and followers beyond those included may come to at most `allowance` (minor units a month; null: the plan's `monthlyPrice`) plus what the workspace paid in renewals and usage charges in the last 90 days. Past it, adding is refused with `402 CREDIT_LIMIT`. Absent: the default, an allowance of the monthly price. Null: no limit.","properties":{"allowance":{"type":["null","integer"]}}}}},"monthlyPrice":{"type":["null","integer"],"description":"Minor units. 9900 is $99.00 — never a float. Null for a plan priced by contract."},"currency":{"type":"string"},"selfServe":{"type":"boolean","description":"False for a plan arranged with us rather than chosen in the dashboard."},"overagePerOrder":{"type":"integer","description":"Minor units per order beyond the allowance."},"features":{"type":"object","description":"What the plan switches on. A feature a plan lacks is refused with `402 FEATURE_NOT_IN_PLAN` when used to open something; closing, cancelling and modifying what already exists are always allowed.","properties":{"executionWaves":{"type":"boolean","description":"`POST /execution-waves`."},"pendingOrders":{"type":"boolean","description":"`POST /accounts/{id}/orders/pending`."},"alwaysOn":{"type":"boolean","description":"The `always_on` account mode."},"webhooks":{"type":"boolean","description":"Event webhooks: order, position, account and multi-account order events, signed and retried. See /v1/webhooks."},"copyTrading":{"type":"boolean","description":"Running or following a copy-trading strategy."},"marketlabs":{"type":"boolean","description":"MarketLabs market intelligence and research. Absent from a plan that has not been given it."}}},"entitlements":{"type":"object","properties":{"accounts":{"type":"integer","description":"Accounts holding credentials at once. A capacity limit, not a monthly allowance: you cannot exceed it and be billed."},"ordersPerMonth":{"type":"integer","description":"Opening orders. Closing, cancelling and moving stops are never counted."},"wavesPerMonth":{"type":"integer"},"legsPerWave":{"type":"integer","description":"Accounts in one multi-account order."},"apiCallsPerMonth":{"type":"integer"},"allowOverage":{"type":"boolean","description":"Whether the monthly allowances may be exceeded and billed, up to twice the allowance."},"eventRetentionDays":{"type":"integer","description":"Days events are kept for GET /v1/events and replay. Absent on plans without webhooks."},"copyStrategies":{"type":"integer","description":"Copy-trading strategies a workspace may run at once. Absent: the spec's default, 50."},"copyFollowersPerStrategy":{"type":"integer","description":"Followers one strategy may have. Absent: the spec's default, 500."},"copyStrategiesPerFollower":{"type":"integer","description":"Strategies one follower account may copy. Absent: the spec's default, 5."},"copyLegsPerSecond":{"type":"integer","description":"Copy legs a second for the workspace; more queue. Absent: the spec's default, 200."},"marketlabsSimulations":{"type":"integer","description":"MarketLabs simulations included this month. Absent: none."}}}}}}}}}}}}}},"/v1/billing/usage":{"get":{"summary":"This month's usage and what it would cost","tags":["Billing"],"description":"Counted as it happens rather than derived at the end of the month, so this is the same number the invoice will use.\n\n**Over quota, opening is refused and closing is always allowed.** A billing problem must never hold you in a position you cannot exit — an order to close comes back `201` however far over the plan you are, and only opening returns `402 QUOTA_EXCEEDED`.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"plan":{"type":"string"},"planName":{"type":"string"},"currency":{"type":"string"},"subtotal":{"type":["null","integer"],"description":"The subscription, in minor units. Null on a contract-priced plan."},"overage":{"type":"integer","description":"Charged on opening orders only — never on API calls or on getting flat."},"total":{"type":["null","integer"]},"entitlements":{"type":"object","properties":{"accounts":{"type":"integer","description":"Accounts holding credentials at once. A capacity limit, not a monthly allowance: you cannot exceed it and be billed."},"ordersPerMonth":{"type":"integer","description":"Opening orders. Closing, cancelling and moving stops are never counted."},"wavesPerMonth":{"type":"integer"},"legsPerWave":{"type":"integer","description":"Accounts in one multi-account order."},"apiCallsPerMonth":{"type":"integer"},"allowOverage":{"type":"boolean","description":"Whether the monthly allowances may be exceeded and billed, up to twice the allowance."},"eventRetentionDays":{"type":"integer","description":"Days events are kept for GET /v1/events and replay. Absent on plans without webhooks."},"copyStrategies":{"type":"integer","description":"Copy-trading strategies a workspace may run at once. Absent: the spec's default, 50."},"copyFollowersPerStrategy":{"type":"integer","description":"Followers one strategy may have. Absent: the spec's default, 500."},"copyStrategiesPerFollower":{"type":"integer","description":"Strategies one follower account may copy. Absent: the spec's default, 5."},"copyLegsPerSecond":{"type":"integer","description":"Copy legs a second for the workspace; more queue. Absent: the spec's default, 200."},"marketlabsSimulations":{"type":"integer","description":"MarketLabs simulations included this month. Absent: none."}}},"features":{"type":"object","description":"What the plan switches on. A feature a plan lacks is refused with `402 FEATURE_NOT_IN_PLAN` when used to open something; closing, cancelling and modifying what already exists are always allowed.","properties":{"executionWaves":{"type":"boolean","description":"`POST /execution-waves`."},"pendingOrders":{"type":"boolean","description":"`POST /accounts/{id}/orders/pending`."},"alwaysOn":{"type":"boolean","description":"The `always_on` account mode."},"webhooks":{"type":"boolean","description":"Event webhooks: order, position, account and multi-account order events, signed and retried. See /v1/webhooks."},"copyTrading":{"type":"boolean","description":"Running or following a copy-trading strategy."},"marketlabs":{"type":"boolean","description":"MarketLabs market intelligence and research. Absent from a plan that has not been given it."}}},"pricing":{"type":"object","description":"How the plan charges. `bundle`: its price buys a fixed allowance. `usage`: its price includes `includedAccounts`, then each account past them costs the band's `unitPrice` a month, always-on accounts `alwaysOnPrice` a month, and opening executions past `executionsPerAccount` × the accounts paid for cost `overagePer1000` per 1,000. `freeDemoAccounts` demo accounts are not charged. Minor units throughout.","properties":{"model":{"type":"string","enum":["bundle","usage"]},"includedAccounts":{"type":"integer"},"accountTiers":{"type":"array","items":{"type":"object","properties":{"upTo":{"type":"integer"},"unitPrice":{"type":"integer"}}}},"alwaysOnPrice":{"type":["null","integer"]},"executionsPerAccount":{"type":"integer"},"overagePer1000":{"type":"integer"},"freeDemoAccounts":{"type":"integer"},"trialDays":{"type":["null","integer"]},"demoOnly":{"type":"boolean"},"includedFollowers":{"type":"integer","description":"Copy-trading followers (subscriptions) the base covers."},"followerPrice":{"type":["null","integer"],"description":"Minor units per follower beyond those included, a month, billed by the day. Null: none sold beyond those included — the plan's cap."},"creditLimit":{"type":["null","object"],"description":"Credit control on a `usage` plan: accounts beyond those included, always-on accounts and followers beyond those included may come to at most `allowance` (minor units a month; null: the plan's `monthlyPrice`) plus what the workspace paid in renewals and usage charges in the last 90 days. Past it, adding is refused with `402 CREDIT_LIMIT`. Absent: the default, an allowance of the monthly price. Null: no limit.","properties":{"allowance":{"type":["null","integer"]}}}}},"trialEndsAt":{"type":["null","string"],"format":"date-time","description":"While on the free trial: when it ends."},"usage":{"type":"object","properties":{"orders":{"type":"integer"},"waves":{"type":"integer"},"api_calls":{"type":"integer"},"accounts":{"type":"integer","description":"Connected right now, not a monthly total."}}},"usageCharges":{"type":["null","object"],"description":"On a per-account plan: what this month has used so far and what it would add to the plan's price if the month ended now. Charged after the month ends — to the card the plan renews on, or with the next crypto payment.","properties":{"month":{"type":"string"},"total":{"type":"integer"},"paidAccounts":{"type":"integer"},"lines":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"quantity":{"type":"number"},"unitAmount":{"type":["null","integer"],"description":"Minor units each, where the line has a unit price."},"amount":{"type":"integer","description":"Minor units."}}}},"measured":{"type":"object","properties":{"liveAccounts":{"type":"integer"},"demoAccounts":{"type":"integer"},"alwaysOnDays":{"type":"integer"},"executions":{"type":"integer"}}}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/billing/usage/daily":{"get":{"summary":"Usage broken down by day","tags":["Billing"],"description":"For a chart, or for checking an invoice line against the day it came from.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","description":"UTC date, as YYYY-MM-DD."},"metric":{"type":"string"},"count":{"type":"integer"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/billing/subscription":{"get":{"summary":"What is paying for the plan","tags":["Billing"],"description":"The workspace's subscription, if it has one: plan, card or crypto, status, the current paid period and whether it ends at period end. Null when nothing is being paid for.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["null","object"],"properties":{"id":{"type":"string","format":"uuid"},"plan":{"type":"string"},"method":{"type":"string","enum":["card","crypto","transfer"]},"interval":{"type":"string","enum":["month","year"]},"agreement":{"type":"boolean","description":"Pays for the workspace's enterprise agreement rather than a plan from the price list."},"status":{"type":"string","enum":["pending","active","past_due","ended"],"description":"`past_due`: a card renewal failed and is being retried; the plan is kept meanwhile. When paying stops the workspace moves to Free — opening is then refused, and closing never is."},"currentPeriodEnd":{"type":["null","string"],"format":"date-time"},"cancelAtPeriodEnd":{"type":"boolean"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/billing/invoices":{"get":{"summary":"Invoices, newest first","tags":["Billing"],"description":"Every invoice for this workspace, newest first, with its number, amount, status, provider and any refunds. Amounts are in minor units.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"string","description":"Sequential, e.g. FX-2026-000123. Never reused. Invoices issued before the fxapis name keep their OW- numbers."},"plan":{"type":"string"},"method":{"type":"string","enum":["card","crypto","transfer"]},"status":{"type":"string","enum":["open","paid","void","uncollectible"]},"currency":{"type":"string"},"amount":{"type":"integer","description":"Minor units. 9900 is $99.00."},"amountRefunded":{"type":"integer","description":"Minor units."},"periodStart":{"type":["null","string"],"format":"date-time"},"periodEnd":{"type":["null","string"],"format":"date-time"},"crypto":{"type":["null","object"],"description":"Crypto only. While the invoice is open: send exactly `amount` of `coin` on `network` to `address`, with `extraId` as the memo or tag when one is given — without it the payment cannot be matched.","properties":{"coin":{"type":["null","string"]},"network":{"type":["null","string"]},"address":{"type":["null","string"]},"amount":{"type":["null","string"],"description":"Exact, as quoted. A string, never a float."},"extraId":{"type":["null","string"]},"expiresAt":{"type":["null","string"],"format":"date-time"},"providerStatus":{"type":["null","string"],"description":"waiting, confirming, confirmed, sending, partially_paid, finished, failed, expired."},"amountReceived":{"type":["null","string"]}}},"note":{"type":["null","string"]},"paidAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/billing/crypto/coins":{"get":{"summary":"Coins accepted for crypto payment","tags":["Billing"],"description":"Each with the network it must be sent on. Sending on another network loses the payment.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ticker":{"type":"string"},"label":{"type":"string"},"network":{"type":"string","description":"The chain it must be sent on."},"stable":{"type":"boolean"},"note":{"type":"string"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/billing/invoices/{id}":{"get":{"summary":"One invoice","tags":["Billing"],"description":"One invoice by id, with its lines, payment status and refunds. Another workspace's invoice is 404.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"string","description":"Sequential, e.g. FX-2026-000123. Never reused. Invoices issued before the fxapis name keep their OW- numbers."},"plan":{"type":"string"},"method":{"type":"string","enum":["card","crypto","transfer"]},"status":{"type":"string","enum":["open","paid","void","uncollectible"]},"currency":{"type":"string"},"amount":{"type":"integer","description":"Minor units. 9900 is $99.00."},"amountRefunded":{"type":"integer","description":"Minor units."},"periodStart":{"type":["null","string"],"format":"date-time"},"periodEnd":{"type":["null","string"],"format":"date-time"},"crypto":{"type":["null","object"],"description":"Crypto only. While the invoice is open: send exactly `amount` of `coin` on `network` to `address`, with `extraId` as the memo or tag when one is given — without it the payment cannot be matched.","properties":{"coin":{"type":["null","string"]},"network":{"type":["null","string"]},"address":{"type":["null","string"]},"amount":{"type":["null","string"],"description":"Exact, as quoted. A string, never a float."},"extraId":{"type":["null","string"]},"expiresAt":{"type":["null","string"],"format":"date-time"},"providerStatus":{"type":["null","string"],"description":"waiting, confirming, confirmed, sending, partially_paid, finished, failed, expired."},"amountReceived":{"type":["null","string"]}}},"note":{"type":["null","string"]},"paidAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/api-keys":{"get":{"summary":"List this workspace's keys","tags":["API keys"],"description":"**Needs an admin key** (`fx_admin_…`), made by the workspace owner in the console — or a signed-in owner or admin. Ordinary API keys are refused with `ADMIN_KEY_REQUIRED`.\n\nNewest first, revoked keys included — a revocation is history worth seeing.","security":[{"adminKey":[]}],"x-fxapis-audience":"admin","x-fxapis-sdk":"admin.keys.list","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"publicId":{"type":"string","description":"The key's public half. Safe to log and to show."},"hint":{"type":"string","description":"The key with its secret elided, e.g. `fx_live_7f3a9c21_…`, for telling keys apart."},"environment":{"type":"string","enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"To the minute. Null if it has never been used."},"expiresAt":{"type":["null","string"],"format":"date-time"},"revokedAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"limits":{"type":["null","object"],"description":"What the key may open, on top of its scopes. Each field is its own limit; leave one out for no limit. Checked on every opening order the key places — through the API, a multi-account order, a TradingView hook it created, or MCP. Closing, cancelling and moving stops are never limited. A refused order answers `403 KEY_LIMIT_EXCEEDED`.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}},"createdBy":{"type":["null","object"],"description":"Who made the key in the console. Removing or suspending that person revokes it. Null for a key made with an admin key (see `createdByAdminKey`), or before keys recorded their maker.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"createdByAdminKey":{"type":["null","object"],"description":"The admin key that made this key, when one did. Revoking that admin key does not revoke this one.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Create a key","tags":["API keys"],"description":"**Needs an admin key** (`fx_admin_…`), made by the workspace owner in the console — or a signed-in owner or admin. Ordinary API keys are refused with `ADMIN_KEY_REQUIRED`.\n\nReturns the key in `key`, **once**. We cannot show a key again after creation, or recover it. A lost key is replaced, not recovered.\n\n`admin`, `keys:manage`, `members:manage` and `billing:manage` cannot be granted here, not even by an admin key. Issue narrow keys: an integration that only reads positions should hold `trading:read` and nothing else.\n\nA console session confirms it's you first (`403 STEP_UP_REQUIRED`) only when the key can move money or accounts — `trading:execute`, `trading:reduce` or `accounts:write`. A read-only key, or one that only manages webhooks, is created without one.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","scopes"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":80,"example":"Production trading server"},"scopes":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["accounts:read","accounts:write","trading:read","trading:reduce","trading:execute","history:read","billing:read","webhooks:write","marketlabs:read","marketlabs:run"]},"description":"`admin` and `keys:manage` cannot be granted to a key through the API."},"environment":{"type":"string","enum":["live","test"],"default":"live"},"expiresAt":{"type":"string","format":"date-time","description":"Optional. Must be in the future."},"limits":{"type":["null","object"],"description":"What the key may open, on top of its scopes. Each field is its own limit; leave one out for no limit. Checked on every opening order the key places — through the API, a multi-account order, a TradingView hook it created, or MCP. Closing, cancelling and moving stops are never limited. A refused order answers `403 KEY_LIMIT_EXCEEDED`.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}}}}}}},"security":[{"adminKey":[]}],"x-fxapis-audience":"admin","x-fxapis-sdk":"admin.keys.create","responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"publicId":{"type":"string","description":"The key's public half. Safe to log and to show."},"hint":{"type":"string","description":"The key with its secret elided, e.g. `fx_live_7f3a9c21_…`, for telling keys apart."},"environment":{"type":"string","enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"To the minute. Null if it has never been used."},"expiresAt":{"type":["null","string"],"format":"date-time"},"revokedAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"limits":{"type":["null","object"],"description":"What the key may open, on top of its scopes. Each field is its own limit; leave one out for no limit. Checked on every opening order the key places — through the API, a multi-account order, a TradingView hook it created, or MCP. Closing, cancelling and moving stops are never limited. A refused order answers `403 KEY_LIMIT_EXCEEDED`.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}},"createdBy":{"type":["null","object"],"description":"Who made the key in the console. Removing or suspending that person revokes it. Null for a key made with an admin key (see `createdByAdminKey`), or before keys recorded their maker.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"createdByAdminKey":{"type":["null","object"],"description":"The admin key that made this key, when one did. Revoking that admin key does not revoke this one.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"key":{"type":"string","description":"The whole key. Shown here and never again — store it now. We cannot show it again after creation."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/api-keys/{id}":{"get":{"summary":"Read one key","tags":["API keys"],"description":"**Needs an admin key** (`fx_admin_…`), made by the workspace owner in the console — or a signed-in owner or admin. Ordinary API keys are refused with `ADMIN_KEY_REQUIRED`.\n\nA key's name, scopes, environment label, hint and when it was last used — never the key itself, which is shown only once, when it is created.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"adminKey":[]}],"x-fxapis-audience":"admin","x-fxapis-sdk":"admin.keys.get","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"publicId":{"type":"string","description":"The key's public half. Safe to log and to show."},"hint":{"type":"string","description":"The key with its secret elided, e.g. `fx_live_7f3a9c21_…`, for telling keys apart."},"environment":{"type":"string","enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"To the minute. Null if it has never been used."},"expiresAt":{"type":["null","string"],"format":"date-time"},"revokedAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"limits":{"type":["null","object"],"description":"What the key may open, on top of its scopes. Each field is its own limit; leave one out for no limit. Checked on every opening order the key places — through the API, a multi-account order, a TradingView hook it created, or MCP. Closing, cancelling and moving stops are never limited. A refused order answers `403 KEY_LIMIT_EXCEEDED`.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}},"createdBy":{"type":["null","object"],"description":"Who made the key in the console. Removing or suspending that person revokes it. Null for a key made with an admin key (see `createdByAdminKey`), or before keys recorded their maker.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"createdByAdminKey":{"type":["null","object"],"description":"The admin key that made this key, when one did. Revoking that admin key does not revoke this one.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"patch":{"summary":"Rename or re-scope a key","tags":["API keys"],"description":"**Needs an admin key** (`fx_admin_…`), made by the workspace owner in the console — or a signed-in owner or admin. Ordinary API keys are refused with `ADMIN_KEY_REQUIRED`.\n\nNew scopes replace the old ones and apply from the key's next request. The key itself does not change, so nothing using it needs redeploying. A revoked key cannot be changed.\n\nA console session confirms it's you first only when the change widens the key to a scope that can move money or accounts (`trading:execute`, `trading:reduce`, `accounts:write`) it did not already hold, or changes the limits on a key that already has some. Narrowing scopes, renaming, or adding limits to a key that had none, never asks.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":80,"example":"Production trading server"},"scopes":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["accounts:read","accounts:write","trading:read","trading:reduce","trading:execute","history:read","billing:read","webhooks:write","marketlabs:read","marketlabs:run"]},"description":"Replaces the key's scopes. Takes effect on its next request."},"limits":{"type":["null","object"],"description":"Replaces the key's limits; null removes them. Takes effect on its next order.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"adminKey":[]}],"x-fxapis-audience":"admin","x-fxapis-sdk":"admin.keys.update","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"publicId":{"type":"string","description":"The key's public half. Safe to log and to show."},"hint":{"type":"string","description":"The key with its secret elided, e.g. `fx_live_7f3a9c21_…`, for telling keys apart."},"environment":{"type":"string","enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"To the minute. Null if it has never been used."},"expiresAt":{"type":["null","string"],"format":"date-time"},"revokedAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"limits":{"type":["null","object"],"description":"What the key may open, on top of its scopes. Each field is its own limit; leave one out for no limit. Checked on every opening order the key places — through the API, a multi-account order, a TradingView hook it created, or MCP. Closing, cancelling and moving stops are never limited. A refused order answers `403 KEY_LIMIT_EXCEEDED`.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}},"createdBy":{"type":["null","object"],"description":"Who made the key in the console. Removing or suspending that person revokes it. Null for a key made with an admin key (see `createdByAdminKey`), or before keys recorded their maker.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"createdByAdminKey":{"type":["null","object"],"description":"The admin key that made this key, when one did. Revoking that admin key does not revoke this one.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/api-keys/{id}/revoke":{"post":{"summary":"Revoke a key","tags":["API keys"],"description":"**Needs an admin key** (`fx_admin_…`), made by the workspace owner in the console — or a signed-in owner or admin. Ordinary API keys are refused with `ADMIN_KEY_REQUIRED`.\n\nRefused from its very next request — there is no cache to wait for. Revoking an already-revoked key succeeds and changes nothing, so a retried revoke is safe.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"security":[{"adminKey":[]}],"x-fxapis-audience":"admin","x-fxapis-sdk":"admin.keys.revoke","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"publicId":{"type":"string","description":"The key's public half. Safe to log and to show."},"hint":{"type":"string","description":"The key with its secret elided, e.g. `fx_live_7f3a9c21_…`, for telling keys apart."},"environment":{"type":"string","enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"To the minute. Null if it has never been used."},"expiresAt":{"type":["null","string"],"format":"date-time"},"revokedAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"limits":{"type":["null","object"],"description":"What the key may open, on top of its scopes. Each field is its own limit; leave one out for no limit. Checked on every opening order the key places — through the API, a multi-account order, a TradingView hook it created, or MCP. Closing, cancelling and moving stops are never limited. A refused order answers `403 KEY_LIMIT_EXCEEDED`.","additionalProperties":false,"properties":{"maxVolume":{"type":["null","string"],"examples":["1.00"],"pattern":"^\\d+(\\.\\d{1,8})?$","description":"Lots per opening order."},"symbols":{"type":["null","array"],"items":{"type":"string","minLength":1,"maxLength":32},"minItems":1,"maxItems":100,"uniqueItems":true,"examples":[["EURUSD","XAUUSD"]],"description":"Broker symbols or instruments the key may open, compared without case."},"accountIds":{"type":["null","array"],"items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"uniqueItems":true,"description":"The accounts the key may open on."},"maxOpeningOrdersPerDay":{"type":["null","integer"],"minimum":1,"maximum":1000000,"examples":[100],"description":"Opening orders per UTC day. Each account in a multi-account order counts as one."}}},"createdBy":{"type":["null","object"],"description":"Who made the key in the console. Removing or suspending that person revokes it. Null for a key made with an admin key (see `createdByAdminKey`), or before keys recorded their maker.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"createdByAdminKey":{"type":["null","object"],"description":"The admin key that made this key, when one did. Revoking that admin key does not revoke this one.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/workspace":{"get":{"summary":"The workspace this credential belongs to","tags":["Workspace"],"description":"Its plan, and whether trading is switched off. Our staff switch trading off for a whole workspace only during an incident; this is where to see it.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","required":["id","name","plan","planName","planAssigned","tradingDisabled"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"plan":{"type":"string","description":"The plan in force. `none` when the workspace pays for nothing and no free plan is offered: choose a plan to connect accounts and open trades."},"planName":{"type":"string"},"planAssigned":{"type":"boolean","description":"The plan was arranged with us rather than paid for, and is changed by talking to us."},"tradingDisabled":{"type":"boolean","description":"Trading is switched off for the whole workspace. While it is, every order is refused with `409 TRADING_DISABLED` — closes included."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/alert-hooks":{"get":{"summary":"List TradingView alert hooks","tags":["Alerts"],"description":"Newest first. Deleted hooks are not listed. The URLs are shown only as hints — the secret is not stored.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Create a TradingView alert hook","tags":["Alerts"],"description":"Returns a secret `url` to paste into a TradingView alert's **Webhook URL**. Every alert sent to it becomes an order on the hook's accounts: one account places an ordinary order, several place a multi-account order.\n\n**The URL is returned once**, here, and is a credential: anyone who has it can trade these accounts. We store only a hash of it. Lost or leaked, rotate it.\n\n`defaults` fill in what an alert leaves out and translate TradingView's symbols to your broker's. See the TradingView guide for the message format.\n\nSeveral accounts need a plan with multi-account orders; that is checked here, and again on every alert.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","accountIds"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":80,"example":"Gold breakout strategy"},"accountIds":{"type":"array","minItems":1,"maxItems":500,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"example":["2b0c7c1e-5d0b-4d8e-9a53-0e6f3b1c9a10"]},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","pattern":"^\\d+(\\.\\d{1,8})?$","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","minimum":0,"maximum":10000,"example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","maxLength":16,"example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}},"additionalProperties":false}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"},"url":{"type":"string","description":"Paste this into the alert's Webhook URL. Shown here and never again — anyone holding it can trade the hook's accounts. Lost or leaked: rotate.","example":"https://api.fxapis.com/hooks/tradingview/3q2-7ZkT0d8m1sQe9yVbW4nX6pLr5aHcUgJf0oKxQx4w"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/alert-hooks/{id}":{"get":{"summary":"Read one alert hook","tags":["Alerts"],"description":"One alert hook: its name, accounts, defaults, whether it is enabled and when it was last used. The secret URL is never returned again — rotate the hook for a new one.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"patch":{"summary":"Change an alert hook's name, accounts or defaults","tags":["Alerts"],"description":"The URL does not change, so nothing needs editing in TradingView. `defaults` fields you send replace those fields; the rest stay as they are. `symbolMap`, when sent, replaces the whole map.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":80,"example":"Gold breakout strategy"},"accountIds":{"type":"array","minItems":1,"maxItems":500,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"example":["2b0c7c1e-5d0b-4d8e-9a53-0e6f3b1c9a10"]},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","pattern":"^\\d+(\\.\\d{1,8})?$","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","minimum":0,"maximum":10000,"example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","maxLength":16,"example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}},"additionalProperties":false}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"delete":{"summary":"Delete an alert hook","tags":["Alerts"],"description":"Its URL stops working at once and cannot be brought back. Orders it placed stay in the history, with the alert that caused them in `clientOrderId`.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/alert-hooks/{id}/rotate":{"post":{"summary":"Replace an alert hook's URL","tags":["Alerts"],"description":"Issues a new secret URL and retires the old one at once: alerts still pointing at it are refused from now on. Update every TradingView alert that uses it. The new `url` is returned **once**.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"},"url":{"type":"string","description":"Paste this into the alert's Webhook URL. Shown here and never again — anyone holding it can trade the hook's accounts. Lost or leaked: rotate.","example":"https://api.fxapis.com/hooks/tradingview/3q2-7ZkT0d8m1sQe9yVbW4nX6pLr5aHcUgJf0oKxQx4w"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/alert-hooks/{id}/enable":{"post":{"summary":"Enable an alert hook","tags":["Alerts"],"description":"Alerts are traded again from the next one. Safe to repeat.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/alert-hooks/{id}/disable":{"post":{"summary":"Disable an alert hook","tags":["Alerts"],"description":"Alerts are refused — answered 409 and recorded as `rejected` — until it is enabled again. The URL stays the same, so nothing changes in TradingView. Safe to repeat.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"accountIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"One account places an ordinary order; several place a multi-account order."},"defaults":{"type":"object","properties":{"volume":{"type":"string","description":"Lots, used when an alert does not send `volume`.","example":"0.10"},"deviationPoints":{"type":["null","integer"],"description":"Maximum slippage in points. Null leaves it to the terminal.","example":20},"symbolMap":{"type":"object","additionalProperties":{"type":"string"},"description":"TradingView symbol (after the exchange prefix is removed) → your broker's symbol. Checked before the suffix.","example":{"XAUUSD":"XAUUSD.a","US30":"DJ30"}},"symbolSuffix":{"type":"string","description":"Appended to symbols the map does not name — for brokers that decorate every symbol, like `EURUSD.a`.","example":".a"},"stripExchangePrefix":{"type":"boolean","description":"Turn `OANDA:XAUUSD` into `XAUUSD`. On by default."},"allowClose":{"type":"boolean","description":"Whether `close`, `flat` and `close_all` alerts are acted on. On by default."},"onlyTradingViewIps":{"type":"boolean","description":"Refuse alerts that do not come from TradingView's published webhook addresses. On by default."}}},"enabled":{"type":"boolean"},"urlHint":{"type":"string","description":"The URL with its secret elided, for telling hooks apart. The full URL is returned only by create and rotate.","example":"https://api.fxapis.com/hooks/tradingview/…Qx4w"},"lastUsedAt":{"type":["null","string"],"format":"date-time","description":"When an alert last arrived, to the minute."},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/alert-hooks/{id}/deliveries":{"get":{"summary":"Alerts a hook received, and what became of each","tags":["Alerts"],"description":"Newest first, kept for 30 days. The first place to look when an alert did not trade: every alert that reached a hook is here — refused, ignored and duplicate ones included — with the reason in words.\n\nA hook takes at most 30 alerts a minute; past that, one row records the refusal and the rest of that minute's alerts are not recorded.","parameters":[{"schema":{"type":"string","enum":["pending","accepted","rejected","duplicate","ignored"]},"in":"query","name":"status","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"cursor","required":false,"description":"The previous page's `nextCursor`."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"receivedAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["pending","accepted","rejected","duplicate","ignored"],"description":"`pending`: taken, being sent. `accepted`: at least one order reached the broker — see `orderIds` for how each went. `rejected`: nothing was sent, and `reason` says why. `duplicate`: a repeat of an alert already taken. `ignored`: understood, and deliberately not traded (a partial exit, nothing to close, closing switched off)."},"reason":{"type":["null","string"]},"action":{"type":["null","string"],"example":"buy"},"symbol":{"type":["null","string"],"description":"The broker symbol it resolved to.","example":"XAUUSD.a"},"payload":{"type":["null","string"],"description":"The alert's message as received, up to 2 KB."},"orderIds":{"type":"array","items":{"type":"string","format":"uuid"}},"waveId":{"type":["null","string"],"format":"uuid","description":"Set when the alert became a multi-account order."},"completedAt":{"type":["null","string"],"format":"date-time"}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"]}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks":{"get":{"summary":"List webhook endpoints","tags":["Webhooks"],"description":"Newest first. Deleted endpoints are not listed. Secrets are never returned here.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Create a webhook endpoint","tags":["Webhooks"],"description":"Events are POSTed to `url` as JSON — `{ id, type, createdAt, data }` — signed in the `fxapis-signature` header with the returned `secret`. **The secret is returned once**, here. Retried over about 44.6 hours on failure (jittered; the last wait alone can run up to about 28.8 hours); switched off after 20 failures in a row. Up to 10 endpoints per workspace.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"additionalProperties":false,"properties":{"url":{"type":"string","maxLength":2048,"description":"HTTPS on port 443, a public host, no credentials.","example":"https://example.com/fxapis/webhooks"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event.","uniqueItems":true},"description":{"type":["string","null"],"maxLength":200}}}}}},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Verifies the `fxapis-signature` header on every delivery. Shown here and never again; lost or leaked, rotate it.","example":"whsec_3q2-7ZkT0d8m1sQe9yVbW4nX6pLr5aHcUgJf0oKxQx4w"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}":{"get":{"summary":"Read one webhook endpoint","tags":["Webhooks"],"description":"With its health: the last delivery, failures in a row, and why it was switched off if it was.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"lastDelivery":{"type":["null","object"],"properties":{"at":{"type":"string","format":"date-time"},"succeeded":{"type":"boolean"},"statusCode":{"type":["null","integer"]},"error":{"type":["null","string"]}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"patch":{"summary":"Change a webhook endpoint","tags":["Webhooks"],"description":"Change its `url`, `events` or `description`. The secret stays the same.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"url":{"type":"string","maxLength":2048,"description":"HTTPS on port 443, a public host, no credentials.","example":"https://example.com/fxapis/webhooks"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event.","uniqueItems":true},"description":{"type":["string","null"],"maxLength":200}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"delete":{"summary":"Delete a webhook endpoint","tags":["Webhooks"],"description":"Nothing more is sent to it, including retries in progress. Cannot be undone.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/enable":{"post":{"summary":"Enable a webhook endpoint","tags":["Webhooks"],"description":"Events are sent again from the next one, and the failure count starts from zero. Deliveries that were waiting when it was switched off resume on their schedule. Events recorded while it was off are not sent automatically — replay them (`POST /v1/webhooks/{id}/replay`, failed-only by default), or read them from `GET /v1/events`. Safe to repeat.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/disable":{"post":{"summary":"Disable a webhook endpoint","tags":["Webhooks"],"description":"Events stop being sent to it until it is enabled again. Deliveries already waiting are kept, not dropped; events recorded meanwhile can be replayed once it is back. Safe to repeat.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/rotate":{"post":{"summary":"Rotate a webhook endpoint's secret","tags":["Webhooks"],"description":"Issues a new `secret`, returned **once**. For 24 hours every delivery is signed with both the new and the old secret — two `v1=` values in `fxapis-signature` — so you can deploy the new one without missing an event.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://example.com/fxapis/webhooks"},"description":{"type":["null","string"],"example":"Copier"},"events":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"description":"The events this endpoint receives. Empty means every event."},"enabled":{"type":"boolean","description":"Whether events are being sent. False when you disabled it, or when we did after 20 failed deliveries in a row — see `disabledReason`."},"disabledAt":{"type":["null","string"],"format":"date-time","description":"When we switched it off for failing. Null when you disabled it yourself."},"disabledReason":{"type":["null","string"],"example":"20 deliveries in a row failed"},"consecutiveFailures":{"type":"integer","description":"Failed deliveries since the last success."},"secretHint":{"type":["null","string"],"description":"The signing secret's last characters, to tell secrets apart.","example":"whsec_…Qx4w"},"previousSecretExpiresAt":{"type":["null","string"],"format":"date-time","description":"After a rotation, deliveries are signed with the old secret too until this time."},"problem":{"type":["null","object"],"description":"Something on our side that stops deliveries. Null when there is none.","properties":{"code":{"type":"string","enum":["SIGNING_SECRET_UNAVAILABLE"]},"message":{"type":"string"},"since":{"type":"string","format":"date-time"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Verifies the `fxapis-signature` header on every delivery. Shown here and never again; lost or leaked, rotate it.","example":"whsec_3q2-7ZkT0d8m1sQe9yVbW4nX6pLr5aHcUgJf0oKxQx4w"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/test":{"post":{"summary":"Send a test event","tags":["Webhooks"],"description":"Sends a `webhook.test` event to this endpoint only, within a few seconds. Check the delivery log for the result.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"eventId":{"type":"string","format":"uuid"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/deliveries":{"get":{"summary":"Delivery attempts to a webhook endpoint","tags":["Webhooks"],"description":"Every attempt, newest first, kept 30 days: what was sent, what your endpoint answered, and how long it took.","parameters":[{"schema":{"type":"string","enum":["succeeded","failed"]},"in":"query","name":"status","required":false},{"schema":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected","webhook.test"]},"in":"query","name":"eventType","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string","maxLength":200},"in":"query","name":"cursor","required":false,"description":"The previous page's `nextCursor`."},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid","description":"The event's id, as in the body and `fxapis-event-id`."},"eventType":{"type":"string","example":"order.filled"},"attempt":{"type":"integer","description":"1 for the first attempt."},"state":{"type":"string","enum":["succeeded","failed","sending"],"description":"`sending` while the attempt is in flight."},"succeeded":{"type":"boolean","description":"Your endpoint answered 2xx."},"statusCode":{"type":["null","integer"],"description":"Null when no answer arrived."},"durationMs":{"type":["null","integer"]},"error":{"type":["null","string"],"example":"HTTP 500"},"eventAvailable":{"type":"boolean","description":"The event is still in this workspace's event history, so it can be redelivered. False once it has aged out: the attempt's log is kept longer than events are on some plans."},"createdAt":{"type":"string","format":"date-time"}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"]}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/deliveries/{deliveryId}":{"get":{"summary":"One delivery attempt, in full","tags":["Webhooks"],"description":"The request as sent — URL, headers (signature included) and exact body — and what your endpoint answered: status, headers and the first 4 KB of the body. Latency is `durationMs`. Kept 30 days on every plan, even once the event itself has aged out of your event history.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"deliveryId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string","format":"uuid","description":"The event's id, as in the body and `fxapis-event-id`."},"eventType":{"type":"string","example":"order.filled"},"attempt":{"type":"integer","description":"1 for the first attempt."},"state":{"type":"string","enum":["succeeded","failed","sending"],"description":"`sending` while the attempt is in flight."},"succeeded":{"type":"boolean","description":"Your endpoint answered 2xx."},"statusCode":{"type":["null","integer"],"description":"Null when no answer arrived."},"durationMs":{"type":["null","integer"]},"error":{"type":["null","string"],"example":"HTTP 500"},"eventAvailable":{"type":"boolean","description":"The event is still in this workspace's event history, so it can be redelivered. False once it has aged out: the attempt's log is kept longer than events are on some plans."},"createdAt":{"type":"string","format":"date-time"},"request":{"type":"object","properties":{"url":{"type":["null","string"]},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"type":["null","string"],"description":"The JSON body exactly as sent."}}},"response":{"type":["null","object"],"description":"Null when no answer arrived (a timeout, a refused connection).","properties":{"statusCode":{"type":"integer"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"type":"string","description":"The first 4 KB of the answer."}}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/deliveries/{eventId}/redeliver":{"post":{"summary":"Redeliver an event","tags":["Webhooks"],"description":"Queues the event to this endpoint again, with a fresh retry schedule. Same event id, so your deduplication still works.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true},{"schema":{"type":"string","format":"uuid"},"in":"path","name":"eventId","required":true}],"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"eventId":{"type":"string","format":"uuid"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/webhooks/{id}/replay":{"post":{"summary":"Replay events to an endpoint","tags":["Webhooks"],"description":"Queues this window's events, of the types this endpoint receives, oldest first, with their original ids. By default (`include: \"failed\"`) only events it did not receive — deliveries it gave up on, and events recorded while it was switched off — so repeating a call sends nothing twice. `include: \"all\"` also re-sends what it already received: deduplicate on `id` first. Types follow the endpoint's events now: if you added a type later, its events recorded since the endpoint was created are sent too — never sent to it before, but older than what it has received. Up to 10,000 per call; `nextSince` says where to continue. Events written at one exact moment are never split across calls, so in the rare case of more than that at one moment, a call queues them all. For code that catches up by itself, read `GET /v1/events?after=<last listed id>` instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["since"],"additionalProperties":false,"properties":{"since":{"type":"string","format":"date-time","description":"From this time (inclusive), within the event history your plan keeps. Read to the microsecond: pass `nextSince` back exactly as given."},"until":{"type":"string","format":"date-time","description":"Up to this time (exclusive). Defaults to now."},"types":{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"uniqueItems":true,"description":"Only these types. Default: every type this endpoint receives."},"include":{"type":"string","enum":["failed","all"],"default":"failed","description":"`failed` (default): only events this endpoint did not receive — given up on, or recorded while it was off (or, for a type added to it later, recorded since it was created). `all`: also re-send events it already received. **A copy-trading or order-handling receiver must deduplicate on `id` before you use `all`.**"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"queued":{"type":"integer","description":"Events queued to this endpoint by this call. Over the cap only when more events than that share one moment."},"include":{"type":"string","enum":["failed","all"]},"since":{"type":"string","format":"date-time"},"until":{"type":"string","format":"date-time"},"nextSince":{"type":["null","string"],"format":"date-time","description":"Set when the cap was reached: call again with this as `since`. Null when the window is done."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/events":{"get":{"summary":"List events","tags":["Events"],"description":"Everything that happened in this workspace while its plan included webhooks, exactly as webhooks deliver it, kept 7, 30 or 90 days by plan — whether or not a webhook endpoint was listening. Events from a time the plan did not include webhooks are not recorded, so they are not listed.\n\nAn event appears in the list a few seconds after it happens, and only once every earlier event has, so a page never moves past one that has not appeared yet — except an event stuck more than 15 minutes before it could be prepared for sending (rare; we alert on it), which stops holding the list back and so, once it does appear, may fall behind an `after=` loop that already paged past its moment.\n\n**Catching up after downtime:** keep an anchor id taken only from the last item of a list page you processed — never from a webhook: webhooks do not arrive in list order (sends run in parallel and retries are spread out), so a webhook's id can be newer than an event still retrying. On start, call `?after=<anchor>` and keep calling with the last id of each page until a page comes back empty. Then check `delivery_status=failed`, or run a replay, for anything given up on. Deduplicate on `id`. With `after`, events come oldest first. Without it, newest first, paged by `nextCursor`. An `after` id older than your plan keeps answers `400 EVENT_NOT_IN_HISTORY`: resume from `since` instead.","parameters":[{"schema":{"type":"string"},"in":"query","name":"after","required":false,"description":"An event id: return the events after it, oldest first. To catch up, pass the id of the last event of a list page you processed — never a webhook's id, since webhooks can arrive out of order."},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"since","required":false,"description":"Events at or after this time."},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"until","required":false,"description":"Events before this time."},{"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]}}]},"in":"query","name":"type","required":false,"description":"Only these types: repeat it (`type=a&type=b`) or separate with commas."},{"schema":{"type":"string","format":"uuid"},"in":"query","name":"account_id","required":false,"description":"Events about this MT5 account, including multi-account orders with a leg on it."},{"schema":{"type":"string","enum":["failed"]},"in":"query","name":"delivery_status","required":false,"description":"`failed`: events at least one of your endpoints has not received — given up on, or still retrying after a failure."},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string","maxLength":200},"in":"query","name":"cursor","required":false,"description":"Without `after`: the previous page's `nextCursor`."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","description":"Exactly the body a webhook delivery carries: one handler can process both.","properties":{"id":{"type":"string","format":"uuid","description":"The same id webhooks send in the body and `fxapis-event-id`. Deduplicate on it."},"type":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"createdAt":{"type":"string","format":"date-time"},"data":{"type":"object","additionalProperties":true,"description":"The resource as the REST API presented it when the event was sent out."}}}},"page":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["null","string"]}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/events/{id}":{"get":{"summary":"Read one event","tags":["Events"],"description":"Exactly as a webhook delivery carried it.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"Exactly the body a webhook delivery carries: one handler can process both.","properties":{"id":{"type":"string","format":"uuid","description":"The same id webhooks send in the body and `fxapis-event-id`. Deduplicate on it."},"type":{"type":"string","enum":["order.filled","order.rejected","order.unresolved","order.resolved","order.cancelled","position.opened","position.closed","account.state_changed","wave.settled","wave.updated","copy.executed","copy.skipped","copy.failed","copy.subscription_stopped","copy.drift_corrected","copy.master_disconnected"]},"createdAt":{"type":"string","format":"date-time"},"data":{"type":"object","additionalProperties":true,"description":"The resource as the REST API presented it when the event was sent out."}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/members":{"get":{"summary":"List this workspace's members","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nEveryone in this workspace, with their role, when they joined, and how many unrevoked API keys they made (`keysCreated`). Removed members are not listed.","x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"]},"you":{"type":"boolean","description":"True for the member making the request."},"keysCreated":{"type":"integer","description":"How many unrevoked API keys this member made in this workspace. Demoting an admin to member revokes them all, as removing or suspending them does."},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/members/{id}":{"patch":{"summary":"Change a member's role","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nOnly the owner changes roles, and the owner's own role cannot be changed here. Takes effect on the member's next request.\n\nMaking an admin a member also revokes every API key they made in this workspace, in the same change: a member cannot make keys, so none they made may outlive the role. Each revocation is audited, the owner is emailed the list, and `keysRevoked` says how many there were. Keys made by anyone else, or with no recorded maker, are not touched. Making a member an admin revokes nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["role"],"additionalProperties":false,"properties":{"role":{"type":"string","enum":["admin","member"]}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"]},"you":{"type":"boolean","description":"True for the member making the request."},"keysCreated":{"type":"integer","description":"How many unrevoked API keys this member made in this workspace. Demoting an admin to member revokes them all, as removing or suspending them does."},"createdAt":{"type":"string","format":"date-time"},"keysRevoked":{"type":"integer","description":"API keys this member made that the change revoked: all of them when an admin becomes a member, otherwise 0."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/members/{id}/remove":{"post":{"summary":"Remove a member","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nSigns them out everywhere at once, deletes their password, and revokes every API key they made (each revocation is audited, and the owner is emailed the list). Keys made by anyone else are not touched. What they did stays attributed to them.\n\nThe owner cannot be removed. An admin may remove plain members only.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/members/invitations":{"get":{"summary":"List open invitations","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nUnaccepted, unrevoked and unexpired.","x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]},"url":{"type":"string","description":"The link to send them. The same link every time it is asked for, until it is accepted, revoked or expires."},"invitedBy":{"type":["null","string"],"description":"Name of the member who sent it."},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}},"post":{"summary":"Invite someone","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nReturns a link to send them; there is no email yet. An address that already has an open invitation gets that invitation back — the same link, not a new one — with `handedBack: true`. To change the role on it, revoke it and invite again.\n\nThe owner may invite admins and members; an admin may invite members.\n\n`402 QUOTA_EXCEEDED` on a plan with a members limit (Personal, Personal Demo: owner only).\n\n`429 INVITATIONS_LIMITED` past the workspace's invitations a day (new and sent again): 5 on a trial, 20 otherwise.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","role"],"additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254},"role":{"type":"string","enum":["admin","member"]}}}}}},"x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]},"url":{"type":"string","description":"The link to send them. The same link every time it is asked for, until it is accepted, revoked or expires."},"invitedBy":{"type":["null","string"],"description":"Name of the member who sent it."},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"handedBack":{"type":"boolean","description":"True when this address already had an open invitation and that one was returned instead."}}}}}}}},"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]},"url":{"type":"string","description":"The link to send them. The same link every time it is asked for, until it is accepted, revoked or expires."},"invitedBy":{"type":["null","string"],"description":"Name of the member who sent it."},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"handedBack":{"type":"boolean","description":"True when this address already had an open invitation and that one was returned instead."}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"402":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/members/invitations/{id}/revoke":{"post":{"summary":"Withdraw an invitation","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nIts link stops working immediately. Safe to repeat.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}},"/v1/members/invitations/{id}/resend":{"post":{"summary":"Send an invitation again","tags":["Members"],"description":"**Console only — not available with API keys.** Signed-in owners and admins use this from the fxapis console. It is not in the SDKs or the Postman collection.\n\nThe same link, emailed again — for one that was not received. At most once a minute per invitation, and it counts toward the workspace's invitations a day (`429 INVITATIONS_LIMITED`).","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"x-fxapis-audience":"console","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"sentTo":{"type":"string"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, machine-readable. Match on this, not on the message."},"message":{"type":"string","description":"For a human. May change between releases."},"details":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["code","message"]},"requestId":{"type":"string","description":"Also on every response. Quote it in a support request and the whole call can be found."}}}}}}}}}},"servers":[{"url":"https://api.fxapis.com","description":"Production"}],"security":[{"apiKey":[]}],"tags":[{"name":"Accounts","description":"Connecting MT5 accounts and reading their state."},{"name":"Lifecycle","description":"Bringing an account online, taking it offline, and changing how it stays connected."},{"name":"Instruments","description":"Markets named once — `XAUUSD`, `US30`, `BTCUSD` — and how each maps onto an account's broker symbols. An order can name an `instrument` instead of a `symbol`, and trades that account's own symbol for it."},{"name":"Trading","description":"Placing orders and reading positions. The endpoints that move money."},{"name":"Market data","description":"Prices from each account's own broker, read live from its terminal. Each broker quotes differently, and these are the prices that account trades at."},{"name":"History","description":"The durable record: every order, every deal the broker recorded, and what it returned. Includes deals no order of yours caused."},{"name":"Waves","description":"Multi-account orders: one trade placed on many accounts at once, with a result for each account. For signals that should reach every follower at the same moment."},{"name":"Copy trading","description":"Managed copy trading: mark an always-on account as a strategy, subscribe other accounts in this workspace, and fxapis repeats the master's opens, closes, partial closes and stop moves on every follower, sized for each, with no code on your side. Every decision is an execution with its reason. Hedging accounts only."},{"name":"Alerts","description":"TradingView alert hooks: a secret URL that turns TradingView alerts into orders on your accounts, with no EA and no VPS. The URL is returned once, when a hook is created or rotated."},{"name":"Webhooks","description":"Event webhooks: a signed POST to your HTTPS endpoint when an order fills or is rejected, a position opens or closes, an account changes state, or a multi-account order finishes. Retried over about 44.6 hours (jittered), with a delivery log and redelivery. The signing secret is returned once, when an endpoint is created or rotated. Needs `webhooks:write`. See the webhooks guide for event types and verifying signatures."},{"name":"Events","description":"The event log: every event in this workspace, exactly as webhooks deliver it, kept 7, 30 or 90 days by plan. To catch up after downtime, ask for everything `after` the last event you read from this list (not the last webhook: webhooks arrive out of order). Needs `history:read`, on plans with webhooks."},{"name":"Workspace","description":"The workspace a credential belongs to: its plan, and whether trading is switched off."},{"name":"Billing","description":"Plans, usage, what the month would cost, invoices, and paying for a plan."},{"name":"Members","description":"Who is in this workspace, who has been invited, and what each may do. **Console only:** managed by a signed-in owner or admin in the fxapis console. Every API key and admin key is refused, so these operations are not in the SDKs or the Postman collection."},{"name":"API keys","description":"Issuing, renaming, re-scoping and revoking this workspace's ordinary keys. Needs an admin key (`fx_admin_…`) — or a signed-in owner or admin in the console; ordinary keys are refused. A key's secret is returned once, by the request that creates it, and never again."},{"name":"Health","description":"Liveness and readiness. No key required."}]}