{
  "_type": "export",
  "__export_format": 4,
  "__export_date": "2026-05-25T00:00:00.000Z",
  "__export_source": "tickerall.docs:v1",
  "resources": [
    {
      "_id": "wrk_tickerall",
      "_type": "workspace",
      "name": "TickerAll API",
      "description": "Connect and automate your own MT4/MT5 broker accounts. Set the apiKey + accountId environment variables (Manage Environments), then send. Generated from https://tickerall.com/docs.",
      "scope": "collection"
    },
    {
      "_id": "env_tickerall_base",
      "_type": "environment",
      "parentId": "wrk_tickerall",
      "name": "Base environment",
      "data": {
        "baseUrl": "https://api.tickerall.com",
        "wsBaseUrl": "wss://api.tickerall.com",
        "apiKey": "cf_api_xxxxxxxxxxxxxxxxxxxx",
        "accountId": "acc_8Kd3...",
        "ticket": "4072808150"
      },
      "dataPropertyOrder": {
        "&": [
          "baseUrl",
          "wsBaseUrl",
          "apiKey",
          "accountId",
          "ticket"
        ]
      },
      "metaSortKey": 1
    },
    {
      "_id": "fld_sessions",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Sessions",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 0
    },
    {
      "_id": "req_post_v1_sessions",
      "_type": "request",
      "parentId": "fld_sessions",
      "name": "Open a broker session",
      "description": "Connect a broker account. We authenticate and warm a live connection, then hand back an accountId — the handle for THIS broker connection. One API key can hold several broker accounts, so the id lives in this response (and in GET /v1/accounts), NOT in the key. Use it in every later /v1/accounts/:id call. Your password is held in memory only while the connection is live, never saved to disk.\n\n**Body fields**\n- `broker` (\"mt4\" | \"mt5\") — required — Which platform your broker server runs.\n- `server` (string) — required — Broker server name, e.g. \"Exness-MT5Trial14\".\n- `account` (number | string) — required — Your numeric broker login — the account number your broker assigns (e.g. 12345678). NOT your TickerAll email.\n- `password` (string) — required — Broker (investor or master) password. Used once to authenticate; never persisted.\n- `terminalType` (\"MOBILE\" | \"WEB\") — Which client the connection presents AS — MOBILE (default) or WEB. Both expose the full surface (account, quotes, positions, history). Omit for MOBILE. Choosing WEB (or CLIENT) requires a Pro or Enterprise plan.\n- `webTerminalUrl` (string) — The broker’s web-terminal URL, e.g. https://mt5.yourbroker.com. REQUIRED when terminalType is \"WEB\" — web terminals are per-broker-domain, so the URL must be supplied. Ignored for MOBILE.\n- `webEndpoint` (string) — Advanced, optional: an explicit WebSocket endpoint override (e.g. wss://host/path) for the rare broker whose WS host/path differs from the webTerminalUrl derivation. Ignored for MOBILE.\n\n**Notes**\n- On the Free tier, only demo broker accounts are accepted — a real-money login is rejected with FREE_TIER_LIVE_REJECTED.\n- The connection stays warm for a while (see expiresAt). If it cools, calls return BROKER_ACCOUNT_NOT_HOT — just POST /v1/sessions again to reconnect.\n\n**Example response** — 200 OK\n```json\n{\n  \"accountId\": \"acc_8Kd3...\",\n  \"isDemo\": true,\n  \"status\": \"connected\",\n  \"expiresAt\": \"2026-05-22T18:42:10.000Z\"\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/sessions",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"broker\": \"mt5\",\n  \"server\": \"Exness-MT5Trial14\",\n  \"account\": 12345678,\n  \"password\": \"your-broker-password\"\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 0,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_delete_v1_sessions_accountid",
      "_type": "request",
      "parentId": "fld_sessions",
      "name": "Disconnect a session",
      "description": "Disconnect a broker account and release its connection. Returns no body.\n\n**Path parameters**\n- `accountId` (string) — required — The accountId returned by POST /v1/sessions.",
      "method": "DELETE",
      "url": "{{ _.baseUrl }}/v1/sessions/{{ _.accountId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 1,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_accounts",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Accounts",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 1000
    },
    {
      "_id": "req_get_v1_accounts",
      "_type": "request",
      "parentId": "fld_accounts",
      "name": "List connected accounts",
      "description": "List every broker account attached to your API key, with connection state.\n\n**Notes**\n- accountNumber is masked to the last 4 digits. hot=false means the connection cooled — POST /v1/sessions to re-warm it.\n\n**Example response** — 200 OK\n```json\n[\n  {\n    \"id\": \"acc_8Kd3...\",\n    \"broker\": \"mt5\",\n    \"server\": \"Exness-MT5Trial14\",\n    \"accountNumber\": \"****5678\",\n    \"isDemo\": true,\n    \"status\": \"CONNECTED\",\n    \"hot\": true,\n    \"lastHotAt\": \"2026-05-22T18:30:01.000Z\",\n    \"createdAt\": \"2026-05-20T09:11:55.000Z\"\n  }\n]\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 1000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_accounts_id",
      "_type": "request",
      "parentId": "fld_accounts",
      "name": "Get account info + positions",
      "description": "Live account info — balance, equity, margin, leverage — plus the current open positions.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Notes**\n- If the connection has cooled, you get status:\"offline\" with a hint instead of live data — POST /v1/sessions to reconnect.\n- Money fields (equity, margin, freeMargin, marginLevel) may be null on an MT4 account that has not yet pushed a balance frame — null is honest \"not available yet\", never a misleading 0.\n\n**Example response** — 200 OK (status: \"online\")\n```json\n{\n  \"id\": \"acc_8Kd3...\",\n  \"broker\": \"mt5\",\n  \"server\": \"Exness-MT5Trial14\",\n  \"accountNumber\": \"****5678\",\n  \"isDemo\": true,\n  \"status\": \"online\",\n  \"account\": {\n    \"name\": \"Demo Account 12345678\",\n    \"accountType\": \"demo\",\n    \"leverage\": 500,\n    \"balance\": 9871.42,\n    \"currency\": \"USD\",\n    \"equity\": 9863.10,\n    \"margin\": 142.50,\n    \"freeMargin\": 9720.60,\n    \"marginLevel\": 6921.5\n  },\n  \"positions\": [\n    {\n      \"ticket\": 4072808150,\n      \"symbol\": \"BTCUSD\",\n      \"side\": \"BUY\",\n      \"volume\": 0.10,\n      \"entryPrice\": 77512.73,\n      \"stopLoss\": 71000,\n      \"takeProfit\": 84000,\n      \"currentPrice\": 77640.10,\n      \"profit\": 12.74,\n      \"swap\": 0,\n      \"commission\": 0,\n      \"comment\": \"my-strategy\",\n      \"magic\": 0,\n      \"openTime\": \"2026-05-22T17:55:03.000Z\"\n    }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 1001,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_delete_v1_accounts_id",
      "_type": "request",
      "parentId": "fld_accounts",
      "name": "Remove a broker account",
      "description": "Remove a broker account from your roster. We disconnect its live connection and drop it from your account list and from billing — this does NOT touch the broker account itself or any open positions. Reversible: reconnect the same login with POST /v1/sessions to re-add it.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Notes**\n- Idempotent — removing an already-removed account returns the same 200 shape.\n- If the account had always-hot enabled, that per-connection charge stops immediately; billableCount is your remaining always-hot connection count.\n\n**Example response** — 200 OK\n```json\n{\n  \"id\": \"acc_8Kd3...\",\n  \"status\": \"DISCONNECTED\",\n  \"removed\": true,\n  \"billableCount\": 0\n}\n```",
      "method": "DELETE",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 1002,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_post_v1_accounts_id_migrate",
      "_type": "request",
      "parentId": "fld_accounts",
      "name": "POST /v1/accounts/:id/migrate",
      "description": "Switch which terminal type the account presents AS (\"MOBILE\" or \"WEB\"). Your open positions, pending orders and balance live on the broker account, not the connection, so they are preserved across the switch.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Body fields**\n- `to` (\"MOBILE\" | \"WEB\") — required — The transport to switch to.\n\n**Notes**\n- status is \"noop\" when the account is already on the requested transport.\n- Switching runs only when the account is idle (no in-flight trade — otherwise 409).\n- Both terminal types expose the full surface (account, quotes, positions, history).\n- The switch is zero-gap — the new transport is warmed before the old session is dropped — so open positions, orders and balance carry over untouched.\n\n**Example response** — 200 OK\n```json\n{\n  \"id\": \"acc_8Kd3...\",\n  \"terminalType\": \"MOBILE\",\n  \"status\": \"noop\"\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/migrate",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"to\": \"2026-05-29\"\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 1003,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_symbols",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Symbols",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 2000
    },
    {
      "_id": "req_get_v1_accounts_id_symbols",
      "_type": "request",
      "parentId": "fld_symbols",
      "name": "List tradeable symbols",
      "description": "List tradeable symbols on the account, in the broker’s native names (pass-through, no normalization). symbols is the full catalog; watched is the subset that is actively streaming live ticks right now.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Notes**\n- Use a name from symbols when placing orders; subscribe to a name to start it ticking on the WebSocket.\n\n**Example response** — 200 OK\n```json\n{\n  \"symbols\": [\"BTCUSD\", \"ETHUSD\", \"EURUSD\", \"GOLD\", \"USOILm\", \"...\"],\n  \"watched\": [\"BTCUSD\", \"ETHUSD\", \"EURUSD\"]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/symbols",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 2000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_accounts_id_symbol_specs",
      "_type": "request",
      "parentId": "fld_symbols",
      "name": "GET /v1/accounts/:id/symbol-specs",
      "description": "Per-symbol trading specs for the account: the volume constraints (min / max / step) for validating an order size before placing it, plus the base, profit (quote) and margin currency for each instrument. MT5 only; an MT4 account returns an empty list.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Notes**\n- volumeStep is the lot increment — round an order size down to it before placing; volumeMin / volumeMax bound the size.\n- profitCurrency is the quote currency (the currency P&L accrues in). Use it — not the account currency — to denote an instrument.\n- specSource is \"broker\" (authoritative) or \"derived\" (a best-effort fallback when the broker did not supply the spec). Currency fields are absent when unknown.\n\n**Example response** — 200 OK\n```json\n{\n  \"specs\": [\n    {\n      \"name\": \"EURUSD\",\n      \"volumeMin\": 0.01,\n      \"volumeMax\": 200.0,\n      \"volumeStep\": 0.01,\n      \"specSource\": \"broker\",\n      \"baseCurrency\": \"EUR\",\n      \"profitCurrency\": \"USD\",\n      \"marginCurrency\": \"EUR\"\n    }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/symbol-specs",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 2001,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_candles_history",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Candles & history",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 3000
    },
    {
      "_id": "req_get_v1_accounts_id_candles",
      "_type": "request",
      "parentId": "fld_candles_history",
      "name": "Historical OHLC candles (authed)",
      "description": "Fetch historical OHLC bars from your connected broker, for any symbol the broker streams on this account. Two modes: a look-back window (hours) returns the most-recent N hours of bars, or a date range (from + to, ISO-8601) returns the exact [from, to] window. Coarser timeframes (H4, D1, W1, MN1) reach much further back — daily bars typically cover years of history. Every response reports how much of the requested window was actually served (coverage / truncated).\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Query parameters**\n- `symbol` (string) — required — Broker-native symbol name, e.g. \"BTCUSD\". Discover names via GET /v1/accounts/:id/symbols.\n- `hours` (number) — Look-back mode: how many hours of data to return, counted backwards from now. Defaults to 24, capped at ~5 years. Ignored when from and to are supplied.\n- `from` (string (ISO-8601)) — Date-range mode: start of the window, e.g. \"2026-01-01T00:00:00Z\". Pass BOTH from and to (an alternative to hours) to fetch the exact [from, to] window. Supplying only one is a 400 invalid_range.\n- `to` (string (ISO-8601)) — Date-range mode: end of the window. Required with from and must be after it. When both are present, hours is ignored.\n- `timeframe` (\"M1\"|\"M5\"|\"M15\"|\"M30\"|\"H1\"|\"H4\"|\"D1\"|\"W1\"|\"MN1\") — Bar interval. Defaults to \"M5\". Coarser timeframes go back further for the same window.\n\n**Notes**\n- Authed — needs your API key (same as the rest of the customer API). Works for any symbol your broker exposes on the connected account.\n- Two modes: pass hours for a look-back window, OR pass both from and to (ISO-8601) for an exact date range. When from and to are present, hours is ignored, and the response echoes from/to (the requested window) at the top level instead of hours. Supplying only one of from/to, an unparseable date, or from ≥ to returns 400 invalid_range with a message.\n- Each candle is { timestamp, open, high, low, close, bid, tickVolume, spread }. timestamp is the bar OPEN time in Unix seconds (UTC); bid mirrors close. tickVolume (tick count) and spread (price units) are present on recent bars; deep-history bars are bid-only and may omit them (null/absent) — don’t rely on a guaranteed volume.\n- Every response also reports completeness: served ({ from, to } actually returned in ISO-8601, or null when empty), count (number of candles), coverage (\"complete\" when the whole window was served, otherwise \"floor\"/\"partial\"), truncated (boolean — true when the whole requested window was NOT served; the authoritative completeness signal), and stopReason (why the walk stopped, e.g. \"floor\" = no deeper data exists, \"deadline\" = worth retrying, \"unsupported\", \"error\"). A note field is added when stopReason is \"unsupported\".\n- A range larger than the per-request cap (~5 years, or ~100,000 bars at the chosen timeframe) is rejected with 400 range_too_large ({ maxBars, estimatedBars, maxWindowDays }) — narrow the range or coarsen the timeframe.\n- Timeframes: M1, M5, M15, M30, H1, H4, D1, W1, MN1. Daily and coarser reach back years; intraday (M1–H4) covers recent months. One request returns as much history as fits in a few seconds. Deep look-backs are isolated onto a dedicated history connection — a big walk never disturbs your live tick stream.\n- If the broker returns no decodable bars for the symbol/range (e.g. an illiquid pair), the response is a 200 with an empty candles array (served null, truncated true) — never a 500.\n\n**Example response** — 200 OK\n```json\n{\n  \"symbol\": \"BTCUSD\",\n  \"hours\": 17520,\n  \"timeframe\": \"D1\",\n  \"candles\": [\n    { \"timestamp\": 1747699200, \"open\": 104200.10, \"high\": 107840.55, \"low\": 103520.00, \"close\": 106910.73, \"bid\": 106910.73 },\n    { \"timestamp\": 1747785600, \"open\": 106910.73, \"high\": 108100.00, \"low\": 105480.20, \"close\": 107512.40, \"bid\": 107512.40 }\n  ],\n  \"served\": { \"from\": \"2025-05-20T00:00:00.000Z\", \"to\": \"2025-05-21T00:00:00.000Z\" },\n  \"count\": 2,\n  \"coverage\": \"complete\",\n  \"truncated\": false,\n  \"stopReason\": \"floor\"\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/candles",
      "body": {},
      "parameters": [
        {
          "name": "symbol",
          "value": "BTCUSD",
          "description": "Broker-native symbol name, e.g. \"BTCUSD\". Discover names via GET /v1/accounts/:id/symbols.",
          "disabled": false
        },
        {
          "name": "hours",
          "value": "8760",
          "description": "Look-back mode: how many hours of data to return, counted backwards from now. Defaults to 24, capped at ~5 years. Ignored when from and to are supplied.",
          "disabled": false
        },
        {
          "name": "from",
          "value": "2026-05-01",
          "description": "Date-range mode: start of the window, e.g. \"2026-01-01T00:00:00Z\". Pass BOTH from and to (an alternative to hours) to fetch the exact [from, to] window. Supplying only one is a 400 invalid_range.",
          "disabled": false
        },
        {
          "name": "to",
          "value": "2026-05-29",
          "description": "Date-range mode: end of the window. Required with from and must be after it. When both are present, hours is ignored.",
          "disabled": false
        },
        {
          "name": "timeframe",
          "value": "D1",
          "description": "Bar interval. Defaults to \"M5\". Coarser timeframes go back further for the same window.",
          "disabled": false
        }
      ],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 3000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_public_candles",
      "_type": "request",
      "parentId": "fld_candles_history",
      "name": "Historical OHLC candles (public demo)",
      "description": "Unauthenticated read of the always-on demo feed — powers the sparklines and chart on tickerall.com. Limited to TickerAll’s demo symbol list and only callable from tickerall.com (origin-gated). For arbitrary broker symbols from your own code, use GET /v1/accounts/:id/candles above.\n\n**Query parameters**\n- `symbol` (string) — required — One of the demo feed’s symbols (e.g. BTCUSD, ETHUSD, EURUSD, GOLD).\n- `hours` (number) — How many hours of data to return. Defaults to 24, capped at ~5 years.\n- `timeframe` (\"M1\"|\"M5\"|\"M15\"|\"M30\"|\"H1\"|\"H4\"|\"D1\"|\"W1\"|\"MN1\") — Bar interval. Defaults to \"M5\". Coarser timeframes go back further for the same hours value.\n\n**Notes**\n- No API key needed, but origin-gated: this endpoint accepts requests from tickerall.com only and exists to drive the public demo widgets. For programmatic access from your own code use GET /v1/accounts/:id/candles instead — it works on any symbol your broker exposes.\n- Each candle is { timestamp, open, high, low, close, bid }. timestamp is the bar OPEN time in Unix seconds (UTC); bid mirrors close.\n- Only the demo feed’s symbol list is available here. For any other symbol, connect a broker account and call GET /v1/accounts/:id/candles instead.\n\n**Example response** — 200 OK\n```json\n{\n  \"symbol\": \"BTCUSD\",\n  \"hours\": 17520,\n  \"timeframe\": \"D1\",\n  \"candles\": [\n    { \"timestamp\": 1747699200, \"open\": 104200.10, \"high\": 107840.55, \"low\": 103520.00, \"close\": 106910.73, \"bid\": 106910.73 },\n    { \"timestamp\": 1747785600, \"open\": 106910.73, \"high\": 108100.00, \"low\": 105480.20, \"close\": 107512.40, \"bid\": 107512.40 }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/public/candles",
      "body": {},
      "parameters": [
        {
          "name": "symbol",
          "value": "BTCUSD",
          "description": "One of the demo feed’s symbols (e.g. BTCUSD, ETHUSD, EURUSD, GOLD).",
          "disabled": false
        },
        {
          "name": "hours",
          "value": "8760",
          "description": "How many hours of data to return. Defaults to 24, capped at ~5 years.",
          "disabled": false
        },
        {
          "name": "timeframe",
          "value": "D1",
          "description": "Bar interval. Defaults to \"M5\". Coarser timeframes go back further for the same hours value.",
          "disabled": false
        }
      ],
      "headers": [],
      "authentication": {},
      "metaSortKey": 3001,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_orders",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Orders",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 4000
    },
    {
      "_id": "req_post_v1_accounts_id_orders",
      "_type": "request",
      "parentId": "fld_orders",
      "name": "Place an order",
      "description": "Place a market order (fills immediately) or a pending limit/stop order (rests until price is hit).\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Body fields**\n- `type` (\"market\" | \"limit\" | \"stop\") — required — The base order type — market (fills now) or limit / stop (rests until price is hit). Do NOT pass MetaTrader-style combined names like \"BUY_STOP\" here: those are only ever returned by GET /orders. On input, split the intent into type + side — e.g. a buy-stop is type:\"stop\" + side:\"BUY\".\n- `symbol` (string) — required — Broker-native symbol, e.g. \"BTCUSD\".\n- `side` (\"BUY\" | \"SELL\") — required — Trade direction — uppercase BUY or SELL. Combined with type it expresses the order, e.g. type:\"limit\" + side:\"SELL\" is a sell-limit.\n- `volume` (number) — required — Lots, e.g. 0.10. Must be positive.\n- `price` (number) — Trigger price. Required for limit and stop; ignored for market.\n- `stopLoss` (number) — Stop-loss price. Omit for none.\n- `takeProfit` (number) — Take-profit price. Omit for none.\n- `comment` (string (≤ 31 chars)) — Optional strategy tag stored on the order.\n\n**Notes**\n- Requires an Idempotency-Key header (see Conventions). Re-sending the same key returns the original response without placing a second order.\n- Pending orders are expressed as two separate fields, not one combined name: a buy-stop is type:\"stop\" + side:\"BUY\"; a sell-limit is type:\"limit\" + side:\"SELL\". The write API does NOT accept MetaTrader-style combined names (BUY_STOP, SELL_LIMIT, …) — passing type:\"BUY_STOP\" is a 400 VALIDATION_ERROR. GET /v1/accounts/:id/orders reports that combined name in its own type field for readability, but that is a read-only convenience: do not echo it back here — use its orderType (LIMIT/STOP) lowercased as type, plus side.\n- status is \"open\" for market orders and \"pending\" for limit/stop orders.\n- A broker rejection (bad volume, market closed, stop-level too tight, insufficient margin) comes back as 422 BROKER_REJECTED with the broker’s reason in message.\n\n**Example response** — 201 Created\n```json\n{\n  \"ticket\": 4072808150,\n  \"symbol\": \"BTCUSD\",\n  \"side\": \"BUY\",\n  \"type\": \"market\",\n  \"volume\": 0.10,\n  \"price\": null,\n  \"stopLoss\": 71000,\n  \"takeProfit\": 84000,\n  \"comment\": \"my-strategy\",\n  \"status\": \"open\",\n  \"timestamp\": \"2026-05-22T17:55:03.000Z\"\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/orders",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"type\": \"market\",\n  \"symbol\": \"BTCUSD\",\n  \"side\": \"BUY\",\n  \"volume\": 0.1,\n  \"stopLoss\": 71000,\n  \"takeProfit\": 84000\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 4000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_accounts_id_orders",
      "_type": "request",
      "parentId": "fld_orders",
      "name": "List pending orders",
      "description": "List the account’s working pending orders — LIMIT and STOP orders resting until their trigger price is hit. A market order is never pending: it becomes an open position immediately (see GET /v1/accounts/:id/positions). Returns an empty list when nothing is resting.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Notes**\n- Working (pending) orders only. When a pending order triggers it leaves this list and becomes an open position — find it under GET /v1/accounts/:id/positions.\n- type is one of BUY_LIMIT, SELL_LIMIT, BUY_STOP, SELL_STOP, BUY_STOP_LIMIT, SELL_STOP_LIMIT; orderType collapses that to LIMIT / STOP / STOP_LIMIT and side to BUY / SELL. ticket is a string; price is the trigger (activation) level; limitPrice is set only on STOP_LIMIT variants; expirationTime is null for good-till-cancelled.\n- This combined type (e.g. BUY_STOP) is READ-ONLY. To place or modify an order, use the split form — type (market/limit/stop) + side (BUY/SELL) — from POST /v1/accounts/:id/orders; the write API does not accept BUY_STOP-style names.\n- For live updates instead of polling, subscribe to the orders channel over the WebSocket (see the WebSocket section) — it pushes the full pending-order list on subscribe and on every change.\n- Optional ?waitMs=<0–10000> adds a settle window for a just-warmed connection’s first pending snapshot; omit for an immediate read.\n- Also reachable at the alias GET /v1/accounts/:id/orders/pending.\n\n**Example response** — 200 OK\n```json\n{\n  \"orders\": [\n    {\n      \"ticket\": \"4072809988\",\n      \"symbol\": \"BTCUSD\",\n      \"type\": \"BUY_LIMIT\",\n      \"side\": \"BUY\",\n      \"orderType\": \"LIMIT\",\n      \"volume\": 0.10,\n      \"price\": 68000,\n      \"limitPrice\": null,\n      \"stopLoss\": 66000,\n      \"takeProfit\": 72000,\n      \"setTime\": \"2026-08-14T09:12:44.000Z\",\n      \"expirationTime\": null\n    }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/orders",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 4001,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_delete_v1_accounts_id_orders_ticket",
      "_type": "request",
      "parentId": "fld_orders",
      "name": "Cancel a pending order",
      "description": "Cancel a resting pending order (LIMIT or STOP) by its ticket.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n- `ticket` (number) — required — Ticket of the pending order to cancel (from GET /v1/accounts/:id/orders).\n\n**Notes**\n- Requires an Idempotency-Key header.\n- ticket is the pending order’s ticket from GET /v1/accounts/:id/orders — not a position. If the order has already triggered it is now an open position; close it with DELETE /v1/accounts/:id/positions/:ticket instead.\n- If the ticket is not a resting pending order on this account you get 404 TICKET_NOT_FOUND.\n- Pending-order management is an MT5 feature; on an account that does not support it the call returns 400.\n\n**Example response** — 200 OK\n```json\n{\n  \"ticket\": 4072809988,\n  \"symbol\": \"BTCUSD\",\n  \"side\": \"BUY\",\n  \"cancelled\": true,\n  \"timestamp\": \"2026-08-14T09:12:44.000Z\"\n}\n```",
      "method": "DELETE",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/orders/{{ _.ticket }}",
      "body": {},
      "parameters": [],
      "headers": [
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 4002,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_patch_v1_accounts_id_orders_ticket",
      "_type": "request",
      "parentId": "fld_orders",
      "name": "Modify a pending order",
      "description": "Modify a resting pending order’s trigger price, stop-loss or take-profit. Any field you omit is preserved at its current value.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n- `ticket` (number) — required — Ticket of the pending order to modify (from GET /v1/accounts/:id/orders).\n\n**Body fields**\n- `price` (number) — New trigger (activation) price. Omit to keep the current trigger.\n- `stopLoss` (number) — New stop-loss. Omit to keep the current SL.\n- `takeProfit` (number) — New take-profit. Omit to keep the current TP.\n\n**Notes**\n- Requires an Idempotency-Key header.\n- Provide at least one of price, stopLoss or takeProfit — an empty body is a 400. Omitted fields keep their current value.\n- If the ticket is not a resting pending order on this account you get 404 TICKET_NOT_FOUND.\n\n**Example response** — 200 OK\n```json\n{\n  \"ticket\": 4072809988,\n  \"symbol\": \"BTCUSD\",\n  \"side\": \"BUY\",\n  \"price\": 66000,\n  \"stopLoss\": 64000,\n  \"takeProfit\": 72000,\n  \"timestamp\": \"2026-08-14T09:12:44.000Z\"\n}\n```",
      "method": "PATCH",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/orders/{{ _.ticket }}",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"stopLoss\": 71000,\n  \"takeProfit\": 84000\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 4003,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_delete_v1_accounts_id_positions_ticket",
      "_type": "request",
      "parentId": "fld_orders",
      "name": "Close a position",
      "description": "Close an open position. Omit volume for a full close, or pass a smaller volume for a partial close.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n- `ticket` (number) — required — Ticket of the position to close (from the order response or GET /v1/accounts/:id).\n\n**Body fields**\n- `volume` (number) — Partial-close volume in lots. If omitted, the whole position is closed.\n\n**Notes**\n- Requires an Idempotency-Key header.\n- If the ticket is not an open position on this account you get 404 TICKET_NOT_FOUND.\n\n**Example response** — 200 OK\n```json\n{\n  \"ticket\": 4072808150,\n  \"symbol\": \"BTCUSD\",\n  \"side\": \"BUY\",\n  \"volume\": 0.10,\n  \"closed\": true,\n  \"timestamp\": \"2026-05-22T18:10:44.000Z\"\n}\n```",
      "method": "DELETE",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/positions/{{ _.ticket }}",
      "body": {},
      "parameters": [],
      "headers": [
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 4004,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_patch_v1_accounts_id_positions_ticket",
      "_type": "request",
      "parentId": "fld_orders",
      "name": "Modify stop-loss / take-profit",
      "description": "Modify the stop-loss and/or take-profit of an open position. Provide at least one of stopLoss / takeProfit.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n- `ticket` (number) — required — Ticket of the position to modify.\n\n**Body fields**\n- `stopLoss` (number) — New stop-loss price. Omit to leave unchanged.\n- `takeProfit` (number) — New take-profit price. Omit to leave unchanged.\n\n**Notes**\n- Requires an Idempotency-Key header.\n- You must supply at least one of stopLoss or takeProfit; sending neither is a VALIDATION_ERROR.\n- Some brokers enforce a minimum stop distance (stop level). Too-tight values come back as 422 BROKER_REJECTED.\n\n**Example response** — 200 OK\n```json\n{\n  \"ticket\": 4072808150,\n  \"symbol\": \"BTCUSD\",\n  \"side\": \"BUY\",\n  \"volume\": 0.10,\n  \"stopLoss\": 72000,\n  \"takeProfit\": 85000,\n  \"timestamp\": \"2026-05-22T18:12:09.000Z\"\n}\n```",
      "method": "PATCH",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/positions/{{ _.ticket }}",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"stopLoss\": 71000,\n  \"takeProfit\": 84000\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 4005,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_trade_history",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Trade history",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 5000
    },
    {
      "_id": "req_get_v1_accounts_id_history",
      "_type": "request",
      "parentId": "fld_trade_history",
      "name": "Closed-trade history",
      "description": "Closed-trade history for the account — executed trades paired into round-trips (entry + exit), the equivalent of MT5’s history_deals_get. Returns the recent window your broker provides on connect plus any trades closed live during the session. Filter by symbol and close-time range.\n\n**Path parameters**\n- `id` (string) — required — accountId.\n\n**Query parameters**\n- `symbol` (string) — Narrow to one broker-native symbol, e.g. \"ETHUSD\". Omit for all symbols.\n- `from` (ISO-8601 | epoch seconds) — Only trades closed at/after this time.\n- `to` (ISO-8601 | epoch seconds) — Only trades closed at/before this time.\n- `limit` (number) — Max rows returned, newest-first. Defaults to 500, capped at 5000.\n- `waitMs` (number) — How long to wait (ms) for history to populate on a just-connected account. Defaults to 4000; pass 0 to skip the wait on a warm connection.\n\n**Notes**\n- Returns the recent window your broker pushes on connect (typically the last few weeks) plus trades closed live during the current session. from/to filter those rows — they do not fetch further back than the broker’s window.\n- Each row is a round-trip: ticket is the open/position ticket; closeTicket is the closing deal (may be null for a trade closed live this session). profit is realised P/L in the account currency.\n- complete=true is a confirmed round-trip with trustworthy P/L. complete=false marks an incomplete/unmatched row, where profit is reported as null rather than a misleading 0.\n- swap and commission are reported as 0 (not carried in this data set).\n- A cheap read that never disturbs your live tick stream. On a connection that has cooled you get 409 BROKER_ACCOUNT_NOT_HOT — POST /v1/sessions to reconnect.\n\n**Example response** — 200 OK\n```json\n{\n  \"trades\": [\n    {\n      \"ticket\": \"4072808150\",\n      \"symbol\": \"ETHUSD\",\n      \"side\": \"BUY\",\n      \"volume\": 0.10,\n      \"openPrice\": 2500.50,\n      \"closePrice\": 2510.25,\n      \"openTime\": \"2026-05-20T10:00:00.000Z\",\n      \"closeTime\": \"2026-05-20T12:30:00.000Z\",\n      \"profit\": 0.98,\n      \"swap\": 0,\n      \"commission\": 0,\n      \"stopLoss\": 0,\n      \"takeProfit\": 0,\n      \"closeTicket\": \"4072808151\",\n      \"complete\": true\n    }\n  ],\n  \"count\": 1,\n  \"limit\": 500\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/accounts/{{ _.accountId }}/history",
      "body": {},
      "parameters": [
        {
          "name": "symbol",
          "value": "BTCUSD",
          "description": "Narrow to one broker-native symbol, e.g. \"ETHUSD\". Omit for all symbols.",
          "disabled": false
        },
        {
          "name": "from",
          "value": "2026-05-01",
          "description": "Only trades closed at/after this time.",
          "disabled": false
        },
        {
          "name": "to",
          "value": "2026-05-29",
          "description": "Only trades closed at/before this time.",
          "disabled": false
        },
        {
          "name": "limit",
          "value": "50",
          "description": "Max rows returned, newest-first. Defaults to 500, capped at 5000.",
          "disabled": false
        },
        {
          "name": "waitMs",
          "value": "4000",
          "description": "How long to wait (ms) for history to populate on a just-connected account. Defaults to 4000; pass 0 to skip the wait on a warm connection.",
          "disabled": false
        }
      ],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 5000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_bulk",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Bulk",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 6000
    },
    {
      "_id": "req_post_v1_bulk_orders",
      "_type": "request",
      "parentId": "fld_bulk",
      "name": "Bulk place orders",
      "description": "Place an order across many of your accounts in one request — one call fans out to every account you name, and each account’s outcome is reported separately. Requires a Pro or Enterprise plan.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Body fields**\n- `orders` (object[]) — required — The orders to place — 1 to 50, one object per target: { accountId, type?, symbol, side, volume, price?, stopLoss?, takeProfit?, comment? }. accountId is the account to trade; type defaults to \"market\" (\"limit\"/\"stop\" need a price for a pending order); symbol, side and volume are required; stopLoss / takeProfit / comment are optional. Each entry mirrors the single-account POST /v1/accounts/:id/orders body.\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403.\n- Requires an Idempotency-Key header (see Conventions). Re-sending the same key replays the original response without placing any order a second time.\n- Partial success — a mix of filled and failed accounts still returns 200. Read each account’s outcome in results: status is \"filled\" (with its ticket and fill price) or \"failed\" (with a code and human-readable reason). summary tallies total / filled / failed.\n- Demo accounts only for now — live-account bulk placement is coming soon. A live account included in the batch comes back failed rather than placing.\n\n**Example response** — 200 OK\n```json\n{\n  \"results\": [\n    { \"accountId\": \"acc_8Kd3...\", \"status\": \"filled\", \"ticket\": 4072808150, \"price\": 77512.73, \"symbol\": \"BTCUSD\" },\n    { \"accountId\": \"acc_9Lm4...\", \"status\": \"failed\", \"symbol\": \"BTCUSD\", \"code\": \"BROKER_REJECTED\", \"reason\": \"Not enough money\" }\n  ],\n  \"summary\": { \"total\": 2, \"filled\": 1, \"failed\": 1 }\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/bulk/orders",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"orders\": [\n    {\n      \"accountId\": \"acc_8Kd3...\",\n      \"type\": \"market\",\n      \"symbol\": \"BTCUSD\",\n      \"side\": \"BUY\",\n      \"volume\": 0.1\n    },\n    {\n      \"accountId\": \"acc_9Lm4...\",\n      \"type\": \"market\",\n      \"symbol\": \"BTCUSD\",\n      \"side\": \"BUY\",\n      \"volume\": 0.1\n    }\n  ]\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 6000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_post_v1_bulk_positions_close",
      "_type": "request",
      "parentId": "fld_bulk",
      "name": "Bulk close positions",
      "description": "Close positions across many accounts in one request — either an explicit list of positions, or a per-account intent that flattens each account (optionally narrowed by its own broker-native symbol or side). Requires a Pro or Enterprise plan.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Body fields**\n- `items` (object[]) — Explicit mode: the exact positions to close, one object each: { accountId, ticket, volume? }. Omit volume for a full close, or pass a smaller volume for a partial close. Use this OR the intent fields below — not both.\n- `targets` (object[]) — Intent mode: a per-account list, one object each: { accountId, symbol?, side? }. Every open position on that account is closed unless narrowed by its own symbol and/or side. Each target carries its own broker-native symbol, so a mixed-broker roster (Exness EURUSDm + XM EURUSD) works in one call. Use this OR items.\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403.\n- Requires an Idempotency-Key header. Re-sending the same key replays the original response without closing anything twice.\n- Two modes: pass items for an explicit per-position list, OR targets for a per-account intent (each { accountId, symbol?, side? }, with its own broker-native symbol). Supplying neither is a 400.\n- Partial success — each position’s outcome is in results: status \"ok\" (closed true) or \"failed\" (with a code and reason). summary tallies total / ok / failed.\n\n**Example response** — 200 OK\n```json\n{\n  \"results\": [\n    { \"accountId\": \"acc_8Kd3...\", \"ticket\": 4072808150, \"status\": \"ok\", \"symbol\": \"BTCUSD\", \"side\": \"BUY\", \"volume\": 0.10, \"closed\": true },\n    { \"accountId\": \"acc_9Lm4...\", \"ticket\": 4072809002, \"status\": \"failed\", \"symbol\": \"BTCUSD\", \"side\": \"SELL\", \"volume\": 0.20, \"closed\": false, \"code\": \"TICKET_NOT_FOUND\", \"reason\": \"Position not open\" }\n  ],\n  \"summary\": { \"total\": 2, \"ok\": 1, \"failed\": 1 }\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/bulk/positions/close",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"items\": [\n    {\n      \"accountId\": \"acc_8Kd3...\",\n      \"ticket\": 4072808150\n    }\n  ]\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 6001,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_post_v1_bulk_positions_modify",
      "_type": "request",
      "parentId": "fld_bulk",
      "name": "Bulk modify positions",
      "description": "Modify the stop-loss and/or take-profit on positions across many accounts in one request. Requires a Pro or Enterprise plan.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Body fields**\n- `items` (object[]) — required — The positions to modify, one object each: { accountId, ticket, stopLoss?, takeProfit? }. Provide at least one of stopLoss / takeProfit per item; an omitted field keeps its current value.\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403.\n- Requires an Idempotency-Key header.\n- Each item must carry at least one of stopLoss / takeProfit; an omitted field is preserved at its current value.\n- Partial success — per-position outcome in results: status \"ok\" (modified true) or \"failed\" (with a code and reason). summary tallies total / ok / failed.\n\n**Example response** — 200 OK\n```json\n{\n  \"results\": [\n    { \"accountId\": \"acc_8Kd3...\", \"ticket\": 4072808150, \"status\": \"ok\", \"symbol\": \"BTCUSD\", \"side\": \"BUY\", \"modified\": true },\n    { \"accountId\": \"acc_9Lm4...\", \"ticket\": 4072809002, \"status\": \"failed\", \"symbol\": \"BTCUSD\", \"side\": \"SELL\", \"modified\": false, \"code\": \"BROKER_REJECTED\", \"reason\": \"Invalid stops\" }\n  ],\n  \"summary\": { \"total\": 2, \"ok\": 1, \"failed\": 1 }\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/bulk/positions/modify",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"items\": [\n    {\n      \"accountId\": \"acc_8Kd3...\",\n      \"ticket\": 4072808150\n    }\n  ]\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 6002,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_post_v1_bulk_orders_cancel",
      "_type": "request",
      "parentId": "fld_bulk",
      "name": "Bulk cancel pending orders",
      "description": "Cancel resting pending orders (LIMIT / STOP) across many accounts in one request — an explicit list, or a per-account intent that cancels the pending orders on each account (optionally narrowed by its own broker-native symbol). Requires a Pro or Enterprise plan.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Body fields**\n- `items` (object[]) — Explicit mode: the pending orders to cancel, one object each: { accountId, ticket }. Use this OR the intent fields below.\n- `targets` (object[]) — Intent mode: a per-account list, one object each: { accountId, symbol? }. Cancels every resting pending order on that account, narrowed by its own broker-native symbol. Use this OR items.\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403.\n- Requires an Idempotency-Key header.\n- Two modes: items for an explicit list, OR targets for a per-account intent (each { accountId, symbol? }, with its own broker-native symbol). Supplying neither is a 400.\n- Partial success — per-order outcome in results: status \"ok\" (cancelled true) or \"failed\" (with a code and reason). summary tallies total / ok / failed.\n- Pending-order management is an MT5 feature; an entry on an account that does not support it comes back failed.\n\n**Example response** — 200 OK\n```json\n{\n  \"results\": [\n    { \"accountId\": \"acc_8Kd3...\", \"ticket\": 4072809988, \"status\": \"ok\", \"cancelled\": true },\n    { \"accountId\": \"acc_9Lm4...\", \"ticket\": 4072809991, \"status\": \"failed\", \"cancelled\": false, \"code\": \"TICKET_NOT_FOUND\", \"reason\": \"Not a resting pending order\" }\n  ],\n  \"summary\": { \"total\": 2, \"ok\": 1, \"failed\": 1 }\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/bulk/orders/cancel",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"items\": [\n    {\n      \"accountId\": \"acc_8Kd3...\",\n      \"ticket\": 4072808150\n    }\n  ]\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 6003,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_post_v1_bulk_orders_modify",
      "_type": "request",
      "parentId": "fld_bulk",
      "name": "Bulk modify pending orders",
      "description": "Modify resting pending orders (trigger price, stop-loss, take-profit) across many accounts in one request. Requires a Pro or Enterprise plan.\n\nRequires an `Idempotency-Key` header — a unique string per logical action, so a retried request never double-fires.\n\n**Body fields**\n- `items` (object[]) — required — The pending orders to modify, one object each: { accountId, ticket, price?, stopLoss?, takeProfit? }. Provide at least one of price / stopLoss / takeProfit per item; an omitted field keeps its current value.\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403.\n- Requires an Idempotency-Key header.\n- Each item must carry at least one of price / stopLoss / takeProfit; an omitted field is preserved at its current value.\n- Partial success — per-order outcome in results: status \"ok\" (modified true) or \"failed\" (with a code and reason). summary tallies total / ok / failed.\n\n**Example response** — 200 OK\n```json\n{\n  \"results\": [\n    { \"accountId\": \"acc_8Kd3...\", \"ticket\": 4072809988, \"status\": \"ok\", \"modified\": true },\n    { \"accountId\": \"acc_9Lm4...\", \"ticket\": 4072809991, \"status\": \"failed\", \"modified\": false, \"code\": \"TICKET_NOT_FOUND\", \"reason\": \"Not a resting pending order\" }\n  ],\n  \"summary\": { \"total\": 2, \"ok\": 1, \"failed\": 1 }\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/bulk/orders/modify",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"items\": [\n    {\n      \"accountId\": \"acc_8Kd3...\",\n      \"ticket\": 4072808150\n    }\n  ]\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        },
        {
          "name": "Idempotency-Key",
          "value": "{% uuid 'v4' %}"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 6004,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_bulk_accounts",
      "_type": "request",
      "parentId": "fld_bulk",
      "name": "Bulk read accounts",
      "description": "Read live state for many accounts in one request — connection status, account financials and open positions for your whole roster (or a subset) in a single call. Requires a Pro or Enterprise plan.\n\n**Query parameters**\n- `ids` (string) — Comma-separated accountIds to read, e.g. \"acc_8Kd3...,acc_9Lm4...\". Omit to read every account on your key.\n- `include` (string) — Comma-separated list of what to include per account: \"account\", \"positions\". Defaults to both — e.g. include=account to skip positions and get a smaller response.\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403.\n- Not idempotent and takes no body — pass ids and include as query-string parameters.\n- One round-trip for your whole roster. Each account’s status is \"online\" (its account and positions blocks are present, per include) or \"offline\" (the connection has cooled — POST /v1/sessions to re-warm it; the account/positions blocks are omitted).\n- include controls the per-account payload: \"account\" adds the financials block, \"positions\" adds open positions; both are included by default. Drop one to make the response smaller.\n- Any ids you pass that are not on your key come back in notFound. summary tallies total / online / offline.\n\n**Example response** — 200 OK\n```json\n{\n  \"accounts\": [\n    {\n      \"id\": \"acc_8Kd3...\",\n      \"broker\": \"mt5\",\n      \"server\": \"Exness-MT5Trial14\",\n      \"accountNumber\": \"****5678\",\n      \"externalRef\": null,\n      \"isDemo\": true,\n      \"hot\": true,\n      \"poolId\": \"pool_3\",\n      \"terminalType\": \"MOBILE\",\n      \"alwaysHot\": false,\n      \"lastHotAt\": \"2026-08-29T09:30:01.000Z\",\n      \"createdAt\": \"2026-08-20T09:11:55.000Z\",\n      \"status\": \"online\",\n      \"account\": { \"balance\": 9871.42, \"currency\": \"USD\", \"equity\": 9863.10, \"margin\": 142.50, \"freeMargin\": 9720.60, \"marginLevel\": 6921.5, \"leverage\": 500 },\n      \"positions\": [\n        { \"ticket\": 4072808150, \"symbol\": \"BTCUSD\", \"side\": \"BUY\", \"volume\": 0.10, \"entryPrice\": 77512.73, \"currentPrice\": 77640.10, \"profit\": 12.74 }\n      ]\n    },\n    {\n      \"id\": \"acc_9Lm4...\",\n      \"broker\": \"mt5\",\n      \"server\": \"ICMarketsSC-Demo\",\n      \"accountNumber\": \"****3311\",\n      \"externalRef\": null,\n      \"isDemo\": true,\n      \"hot\": false,\n      \"poolId\": null,\n      \"terminalType\": \"WEB\",\n      \"alwaysHot\": false,\n      \"lastHotAt\": \"2026-08-29T08:05:44.000Z\",\n      \"createdAt\": \"2026-08-21T14:02:10.000Z\",\n      \"status\": \"offline\"\n    }\n  ],\n  \"notFound\": [],\n  \"summary\": { \"total\": 2, \"online\": 1, \"offline\": 1 }\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/bulk/accounts",
      "body": {},
      "parameters": [
        {
          "name": "ids",
          "value": "acc_8Kd3...,acc_9Lm4...",
          "description": "Comma-separated accountIds to read, e.g. \"acc_8Kd3...,acc_9Lm4...\". Omit to read every account on your key.",
          "disabled": false
        },
        {
          "name": "include",
          "value": "account,positions",
          "description": "Comma-separated list of what to include per account: \"account\", \"positions\". Defaults to both — e.g. include=account to skip positions and get a smaller response.",
          "disabled": false
        }
      ],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 6005,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "fld_copy_trading",
      "_type": "request_group",
      "parentId": "wrk_tickerall",
      "name": "Copy Trading",
      "description": "",
      "environment": {},
      "environmentPropertyOrder": null,
      "metaSortKey": 7000
    },
    {
      "_id": "req_post_v1_copy_sets",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Create a copy set",
      "description": "Create a copy set — one master account whose trades are mirrored to your follower accounts, each scaled and risk-clamped to its own size. All accounts are your own. Requires a Pro or Enterprise plan.\n\n**Body fields**\n- `name` (string) — required — A label for the set.\n- `masterAccountId` (string) — required — The account whose trades are copied. Must be one of your own accounts (and never also a follower).\n- `failurePolicy` (string) — What to do when a follower copy fails: \"retry\" (a few backoff attempts, the default) or \"skip\".\n- `webhookUrl` (string) — Optional. A public https:// URL that receives an HMAC-signed POST for every mirror outcome (see \"Copy-event delivery\" below).\n- `webhookSecret` (string) — Optional HMAC-SHA256 signing key (16+ chars) for the X-Tickerall-Signature header. Write-only — never returned.\n- `followers` (object[]) — Optional followers to attach now, one object each: { followerAccountId, ...config }. Per-follower settings, all optional: sizingMethod (\"proportional\" — scale by the follower÷master equity ratio, the default | \"multiplier\" | \"fixed\" | \"risk_percent\") and sizingValue (the multiplier factor, fixed lots, or risk %); minLot / maxLot (clamp + snap the copied volume to the follower broker’s lot step); maxOpenTrades / maxExposureLots (caps); symbolAllow / symbolBlock (string arrays of follower symbols); dailyLossStop (auto-pause on loss); reverse (inverse copy — sell when the master buys); maxSlippagePips (skip if the follower price moved too far from the master fill); minMasterLot (ignore the master’s tiny trades); copyDelayMs; symbolOverrides (a { \"MASTERSYMBOL\": \"followerSymbol\" } map for cross-broker names the auto-normalizer can’t resolve).\n\n**Notes**\n- Requires a Pro or Enterprise plan — on the Free and Trader plans this call returns 403 (COPY_REQUIRES_PRO).\n- Self-copy only — the master and every follower must be your own accounts. A follower cannot also be the master.\n- A new set is created paused (enabled false). Arm it with PATCH /v1/copy/sets/:setId { \"enabled\": true } once you’re happy with the followers.\n- While live copying is being rolled out, mirrored trades run on demo followers; managing sets and reading stats works on all accounts.\n\n**Example response** — 201 Created\n```json\n{\n  \"id\": \"cset_7Hb2...\",\n  \"ownerId\": \"usr_9Kd3...\",\n  \"name\": \"My desk\",\n  \"masterAccountId\": \"acc_master\",\n  \"enabled\": false,\n  \"failurePolicy\": \"retry\",\n  \"webhookUrl\": null,\n  \"hasWebhookSecret\": false,\n  \"createdAt\": \"2026-08-29T12:00:00.000Z\",\n  \"updatedAt\": \"2026-08-29T12:00:00.000Z\",\n  \"followers\": [\n    { \"id\": \"cf_1\", \"followerAccountId\": \"acc_1\", \"sizingMethod\": \"proportional\", \"reverse\": false, \"enabled\": true }\n  ]\n}\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/copy/sets",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"name\": \"My desk\",\n  \"masterAccountId\": \"acc_master...\",\n  \"followers\": [\n    {\n      \"followerAccountId\": \"acc_1...\",\n      \"sizingMethod\": \"proportional\"\n    },\n    {\n      \"followerAccountId\": \"acc_2...\",\n      \"sizingMethod\": \"multiplier\",\n      \"sizingValue\": 0.5\n    }\n  ]\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7000,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_copy_sets",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "List copy sets",
      "description": "List your copy sets, each with a follower count. Requires a Pro or Enterprise plan.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n\n**Example response** — 200 OK\n```json\n{\n  \"sets\": [\n    { \"id\": \"cset_7Hb2...\", \"name\": \"My desk\", \"masterAccountId\": \"acc_master\", \"enabled\": true, \"failurePolicy\": \"retry\", \"_count\": { \"followers\": 3 }, \"createdAt\": \"2026-08-29T12:00:00.000Z\", \"updatedAt\": \"2026-08-29T12:00:00.000Z\" }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/copy/sets",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7001,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_copy_sets_setid",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Get a copy set",
      "description": "Get one copy set with its full follower list + config. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- Returns 404 if the set is not yours.\n\n**Example response** — 200 OK\n```json\n{\n  \"id\": \"cset_7Hb2...\",\n  \"name\": \"My desk\",\n  \"masterAccountId\": \"acc_master\",\n  \"enabled\": true,\n  \"failurePolicy\": \"retry\",\n  \"followers\": [\n    { \"id\": \"cf_1\", \"followerAccountId\": \"acc_1\", \"sizingMethod\": \"multiplier\", \"sizingValue\": 0.5, \"maxLot\": 1, \"reverse\": false, \"enabled\": true }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7002,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_patch_v1_copy_sets_setid",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Update / arm / pause a set",
      "description": "Update a set — rename, change the failure policy, or arm / pause it. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n\n**Body fields**\n- `name` (string) — New label.\n- `failurePolicy` (string) — \"retry\" or \"skip\".\n- `enabled` (boolean) — Arm (true) — start mirroring — or pause (false). Pausing leaves existing follower positions untouched.\n- `webhookUrl` (string | null) — Set the copy-event webhook (public https:// URL), or null to clear it.\n- `webhookSecret` (string | null) — Set the HMAC signing key (16+ chars), or null to clear it. Write-only.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- Provide at least one field. Arming is just enabled: true.\n\n**Example response** — 200 OK\n```json\n{ \"id\": \"cset_7Hb2...\", \"name\": \"My desk\", \"enabled\": true, \"failurePolicy\": \"retry\", \"followers\": [ ... ] }\n```",
      "method": "PATCH",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7003,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_delete_v1_copy_sets_setid",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Delete a copy set",
      "description": "Delete a copy set (and its followers, position map, and log). Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- Open follower positions are NOT closed — deleting a set only stops future mirroring.",
      "method": "DELETE",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7004,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_post_v1_copy_sets_setid_followers",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Add a follower",
      "description": "Add a follower to a set. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n\n**Body fields**\n- `followerAccountId` (string) — required — The account to mirror to (one of your own; not the master, not already a follower).\n- `...config` (object) — Per-follower settings, all optional: sizingMethod (\"proportional\" — scale by the follower÷master equity ratio, the default | \"multiplier\" | \"fixed\" | \"risk_percent\") and sizingValue (the multiplier factor, fixed lots, or risk %); minLot / maxLot (clamp + snap the copied volume to the follower broker’s lot step); maxOpenTrades / maxExposureLots (caps); symbolAllow / symbolBlock (string arrays of follower symbols); dailyLossStop (auto-pause on loss); reverse (inverse copy — sell when the master buys); maxSlippagePips (skip if the follower price moved too far from the master fill); minMasterLot (ignore the master’s tiny trades); copyDelayMs; symbolOverrides (a { \"MASTERSYMBOL\": \"followerSymbol\" } map for cross-broker names the auto-normalizer can’t resolve).\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- The follower must be your own account, not the master, and not already in the set.\n\n**Example response** — 201 Created\n```json\n{ \"id\": \"cf_4\", \"copySetId\": \"cset_7Hb2...\", \"followerAccountId\": \"acc_4\", \"sizingMethod\": \"proportional\", \"reverse\": true, \"maxSlippagePips\": 3, \"enabled\": true }\n```",
      "method": "POST",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}/followers",
      "body": {
        "mimeType": "application/json",
        "text": "{\n  \"followerAccountId\": \"...\"\n}"
      },
      "parameters": [],
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        }
      ],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7005,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_patch_v1_copy_sets_setid_followers_followerid",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Update a follower",
      "description": "Update a follower’s config — only the fields you send change. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n- `followerId` (string) — required — The follower id (cf_...), from the set’s followers list.\n\n**Body fields**\n- `...config` (object) — Any subset of Per-follower settings, all optional: sizingMethod (\"proportional\" — scale by the follower÷master equity ratio, the default | \"multiplier\" | \"fixed\" | \"risk_percent\") and sizingValue (the multiplier factor, fixed lots, or risk %); minLot / maxLot (clamp + snap the copied volume to the follower broker’s lot step); maxOpenTrades / maxExposureLots (caps); symbolAllow / symbolBlock (string arrays of follower symbols); dailyLossStop (auto-pause on loss); reverse (inverse copy — sell when the master buys); maxSlippagePips (skip if the follower price moved too far from the master fill); minMasterLot (ignore the master’s tiny trades); copyDelayMs; symbolOverrides (a { \"MASTERSYMBOL\": \"followerSymbol\" } map for cross-broker names the auto-normalizer can’t resolve). Send a field as null to clear it.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n\n**Example response** — 200 OK\n```json\n{ \"id\": \"cf_4\", \"copySetId\": \"cset_7Hb2...\", \"followerAccountId\": \"acc_4\", \"sizingMethod\": \"fixed\", \"sizingValue\": 0.02, \"maxLot\": 1 }\n```",
      "method": "PATCH",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}/followers/{{ _.followerId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7006,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_delete_v1_copy_sets_setid_followers_followerid",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Remove a follower",
      "description": "Remove a follower from a set. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n- `followerId` (string) — required — The follower id (cf_...).\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- Open positions the follower already holds are NOT closed.",
      "method": "DELETE",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}/followers/{{ _.followerId }}",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7007,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_copy_sets_setid_stats",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Copy set stats",
      "description": "Dashboard stats for a set — totals, replication rate, and per-follower rollups. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- Derived from the copy log: totals tally ok / skipped / failed; replicationRate is ok ÷ (ok + failed). Per follower: outcome counts, current open copied positions, and average fill latency.\n\n**Example response** — 200 OK\n```json\n{\n  \"set\": { \"id\": \"cset_7Hb2...\", \"name\": \"My desk\", \"enabled\": true, \"masterAccountId\": \"acc_master\", \"failurePolicy\": \"retry\", \"followerCount\": 3 },\n  \"totals\": { \"ok\": 128, \"skipped\": 4, \"failed\": 2, \"replicationRate\": 0.9846 },\n  \"byAction\": { \"open\": 66, \"close\": 60, \"modify\": 8 },\n  \"followers\": [\n    { \"followerAccountId\": \"acc_1\", \"enabled\": true, \"sizingMethod\": \"proportional\", \"ok\": 44, \"skipped\": 1, \"failed\": 0, \"openPositions\": 2, \"avgLatencyMs\": 138 }\n  ]\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}/stats",
      "body": {},
      "parameters": [],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7008,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "req_get_v1_copy_sets_setid_log",
      "_type": "request",
      "parentId": "fld_copy_trading",
      "name": "Copy set log",
      "description": "The copy log for a set — every mirrored action and its outcome, newest first. Requires a Pro or Enterprise plan.\n\n**Path parameters**\n- `setId` (string) — required — The copy set id.\n\n**Query parameters**\n- `limit` (number) — Query param. Page size, 1–200 (default 50).\n- `before` (string) — Query param. An ISO timestamp — return entries older than this. Use the response’s nextBefore to page.\n\n**Notes**\n- Requires a Pro or Enterprise plan.\n- Newest first. limit and before are query-string parameters; page by passing the previous response’s nextBefore back as before (null means the end).\n- result is \"ok\", \"skipped\" (with a reason — e.g. filtered by a rule), or \"failed\" (with a reason). action is open / close / partial_close / modify / pending_place / pending_cancel / pending_modify.\n\n**Example response** — 200 OK\n```json\n{\n  \"entries\": [\n    { \"id\": \"clg_9\", \"followerAccountId\": \"acc_1\", \"action\": \"open\", \"masterTicket\": \"4072808150\", \"followerTicket\": \"5510022931\", \"symbol\": \"EURUSDm\", \"mappedSymbol\": \"EURUSD\", \"volume\": 0.01, \"result\": \"ok\", \"latencyMs\": 132, \"createdAt\": \"2026-08-29T12:34:56.000Z\" },\n    { \"id\": \"clg_8\", \"followerAccountId\": \"acc_2\", \"action\": \"open\", \"symbol\": \"XAUUSDm\", \"volume\": null, \"result\": \"skipped\", \"reason\": \"XAUUSD is on the block list\", \"createdAt\": \"2026-08-29T12:34:56.000Z\" }\n  ],\n  \"nextBefore\": \"2026-08-29T12:34:56.000Z\"\n}\n```",
      "method": "GET",
      "url": "{{ _.baseUrl }}/v1/copy/sets/{{ _.setId }}/log",
      "body": {},
      "parameters": [
        {
          "name": "limit",
          "value": "50",
          "description": "Query param. Page size, 1–200 (default 50).",
          "disabled": false
        },
        {
          "name": "before",
          "value": "...",
          "description": "Query param. An ISO timestamp — return entries older than this. Use the response’s nextBefore to page.",
          "disabled": false
        }
      ],
      "headers": [],
      "authentication": {
        "type": "bearer",
        "token": "{{ _.apiKey }}"
      },
      "metaSortKey": 7009,
      "settingStoreCookies": true,
      "settingSendCookies": true,
      "settingDisableRenderRequestBody": false,
      "settingEncodeUrl": true,
      "settingRebuildPath": true,
      "settingFollowRedirects": "global"
    },
    {
      "_id": "ws_tickerall_stream",
      "_type": "websocket_request",
      "parentId": "wrk_tickerall",
      "name": "Stream (ticks / positions / account)",
      "description": "Realtime data over a single long-lived WebSocket.\n\nConnect to `{{ _.wsBaseUrl }}/v1/stream` and authenticate with the same bearer token — either as an `Authorization: Bearer <key>` header on the upgrade, or `?token={{ _.apiKey }}` in the URL where headers are awkward (browser clients).\n\nAfter connecting, send a subscribe frame listing the channels you want:\n```json\n{\n  \"type\": \"subscribe\",\n  \"channels\": [\n    {\n      \"kind\": \"ticks\",\n      \"accountId\": \"{{ _.accountId }}\",\n      \"symbols\": [\n        \"BTCUSD\",\n        \"ETHUSD\"\n      ]\n    },\n    {\n      \"kind\": \"positions\",\n      \"accountId\": \"{{ _.accountId }}\"\n    },\n    {\n      \"kind\": \"account\",\n      \"accountId\": \"{{ _.accountId }}\"\n    }\n  ],\n  \"correlationId\": \"sub-1\"\n}\n```\n\nThe server streams `tick`, `position_update`, and `account_update` frames, plus a `subscribed` acknowledgement. Send `{ \"type\": \"ping\" }` to get a `pong` and keep the connection alive.",
      "url": "{{ _.wsBaseUrl }}/v1/stream?token={{ _.apiKey }}",
      "headers": [
        {
          "name": "Authorization",
          "value": "Bearer {{ _.apiKey }}"
        }
      ],
      "authentication": {},
      "parameters": [],
      "metaSortKey": 8000
    }
  ]
}