{
  "asyncapi": "3.0.0",
  "info": {
    "title": "etoro WebSocket API",
    "version": "v1.400.0",
    "description": "etoro's public WebSocket service provides real-time streaming access to market data and trading events over a single persistent connection, using a JSON message envelope. Public market topics (`instrument:<instrumentId>`) need no authentication; the `private` topic requires authenticating first.\n\n## Connecting and subscribing\n\n1. **Connect** to `wss://ws.etoro.com/ws`.\n2. **Authenticate** (only required for the `private` topic) by sending an `Authenticate` request with your `userKey` and `apiKey`.\n3. **Subscribe** to one or more topics. Each request carries a client-generated `id` (GUID); the server replies with an acknowledgement that echoes that `id`.\n4. **Receive** push messages: the server streams `{ \"messages\": [ { \"topic\", \"content\", \"id\", \"type\" } ] }`. The `content` field is a JSON-encoded **string** — parse it to obtain the typed object described by each message's `contentSchema`.\n5. **Unsubscribe** when you no longer need a topic, and close the socket when done. A single binary frame is sent periodically as a heartbeat.\n\n```javascript\nconst ws = new WebSocket(\"wss://ws.etoro.com/ws\");\n\nws.onmessage = (event) => console.log(\"Received:\", event.data);\n\n// Authenticate (required for the private topic)\nws.send(JSON.stringify({\n  id: crypto.randomUUID(),\n  operation: \"Authenticate\",\n  data: { userKey: \"<your user key>\", apiKey: \"<your API key>\" }\n}));\n\n// Subscribe to a market instrument\nws.send(JSON.stringify({\n  id: crypto.randomUUID(),\n  operation: \"Subscribe\",\n  data: { topics: [\"instrument:100000\"], snapshot: false }\n}));\n```\n"
  },
  "defaultContentType": "application/json",
  "servers": {
    "etoro": {
      "host": "ws.etoro.com",
      "pathname": "/ws",
      "protocol": "wss",
      "title": "etoro WebSocket",
      "summary": "etoro public WebSocket service for the current environment.",
      "description": "Connect to `wss://ws.etoro.com/ws`."
    }
  },
  "channels": {
    "connectionAuthenticate": {
      "address": "/ws",
      "description": "All client requests share one JSON envelope: `{ \"id\": \"<guid>\", \"operation\": \"<Authenticate|Subscribe|Unsubscribe>\", \"data\": { ... } }`. The server answers each request on the same connection with an acknowledgement that echoes the `id` and the `operation`. The `id` is a client-generated GUID used to correlate the request with its acknowledgement.",
      "tags": [
        {
          "name": "Session & subscriptions"
        }
      ],
      "bindings": {
        "ws": {
          "method": "GET",
          "bindingVersion": "0.1.0"
        }
      },
      "title": "Authenticate (control channel)",
      "summary": "Client → server. Authenticate the session before subscribing to private topics.",
      "messages": {
        "authenticateRequest": {
          "$ref": "#/components/messages/AuthenticateRequest"
        },
        "operationResponse": {
          "$ref": "#/components/messages/OperationResponse"
        }
      }
    },
    "connectionSubscribe": {
      "address": "/ws",
      "description": "All client requests share one JSON envelope: `{ \"id\": \"<guid>\", \"operation\": \"<Authenticate|Subscribe|Unsubscribe>\", \"data\": { ... } }`. The server answers each request on the same connection with an acknowledgement that echoes the `id` and the `operation`. The `id` is a client-generated GUID used to correlate the request with its acknowledgement.",
      "tags": [
        {
          "name": "Session & subscriptions"
        }
      ],
      "bindings": {
        "ws": {
          "method": "GET",
          "bindingVersion": "0.1.0"
        }
      },
      "title": "Subscribe (control channel)",
      "summary": "Client → server. Subscribe to one or more topics.",
      "messages": {
        "subscribeRequest": {
          "$ref": "#/components/messages/SubscribeRequest"
        },
        "operationResponse": {
          "$ref": "#/components/messages/OperationResponse"
        }
      }
    },
    "connectionUnsubscribe": {
      "address": "/ws",
      "description": "All client requests share one JSON envelope: `{ \"id\": \"<guid>\", \"operation\": \"<Authenticate|Subscribe|Unsubscribe>\", \"data\": { ... } }`. The server answers each request on the same connection with an acknowledgement that echoes the `id` and the `operation`. The `id` is a client-generated GUID used to correlate the request with its acknowledgement.",
      "tags": [
        {
          "name": "Session & subscriptions"
        }
      ],
      "bindings": {
        "ws": {
          "method": "GET",
          "bindingVersion": "0.1.0"
        }
      },
      "title": "Unsubscribe (control channel)",
      "summary": "Client → server. Stop receiving messages for one or more topics.",
      "messages": {
        "unsubscribeRequest": {
          "$ref": "#/components/messages/UnsubscribeRequest"
        },
        "operationResponse": {
          "$ref": "#/components/messages/OperationResponse"
        }
      }
    },
    "instrumentCandles": {
      "address": "/ws",
      "x-topic": "candle:{instrumentId}",
      "title": "Instrument candles",
      "summary": "Real-time OHLC candle updates for a single instrument.",
      "description": "Subscribe with topic `candle:<instrumentId>` (e.g. `candle:100000`). Each push carries a `content` field that is a JSON-encoded string of a `Trading.Instrument.Candle` object (see schema). No authentication required.",
      "tags": [
        {
          "name": "Market data feeds / Candles"
        }
      ],
      "messages": {
        "instrumentCandle": {
          "$ref": "#/components/messages/InstrumentCandleMessage"
        },
        "authenticateRequest": {
          "$ref": "#/components/messages/AuthenticateRequest"
        },
        "subscribeRequest": {
          "$ref": "#/components/messages/SubscribeRequest"
        },
        "unsubscribeRequest": {
          "$ref": "#/components/messages/UnsubscribeRequest"
        },
        "operationResponse": {
          "$ref": "#/components/messages/OperationResponse"
        }
      },
      "bindings": {
        "ws": {
          "method": "GET",
          "bindingVersion": "0.1.0"
        }
      }
    },
    "instrumentRates": {
      "messages": {
        "marketStatus": {
          "$ref": "#/components/messages/InstrumentMarketStatusMessage"
        },
        "instrumentRate": {
          "$ref": "#/components/messages/InstrumentRateMessage"
        },
        "authenticateRequest": {
          "$ref": "#/components/messages/AuthenticateRequest"
        },
        "subscribeRequest": {
          "$ref": "#/components/messages/SubscribeRequest"
        },
        "unsubscribeRequest": {
          "$ref": "#/components/messages/UnsubscribeRequest"
        },
        "operationResponse": {
          "$ref": "#/components/messages/OperationResponse"
        }
      },
      "address": "/ws",
      "x-topic": "instrument:{instrumentId}",
      "title": "Instrument rates",
      "summary": "Real-time market price updates for a single instrument.",
      "description": "Subscribe with topic `instrument:<instrumentId>` (e.g. `instrument:100000`). Each push carries a `content` field that is a JSON-encoded string of a `Trading.Instrument.Rate` object (see schema).",
      "tags": [
        {
          "name": "Market data feeds / Status"
        },
        {
          "name": "Market data feeds / Rates"
        }
      ],
      "bindings": {
        "ws": {
          "method": "GET",
          "bindingVersion": "0.1.0"
        }
      }
    },
    "privatePortfolio": {
      "address": "/ws",
      "x-topic": "private",
      "title": "Private portfolio updates",
      "summary": "Real-time order and transaction updates for the authenticated user.",
      "description": "Subscribe with topic `private` (or its alias `private:real`) for your real account and `private:demo` for your demo account (requires a prior successful Authenticate). The two accounts are separate streams - a demo-account update never arrives on `private` / `private:real`, nor a real-account one on `private:demo` - and each push's `topic` is the name you subscribed to (a session holding both `private` and `private:real` receives a real-account update once under each). Each push carries a `content` field that is a JSON-encoded string of a trading order update (e.g. `Trading.OrderForOpen.Update`, `Trading.OrderForCloseMultiple.Update`).",
      "tags": [
        {
          "name": "Account & portfolio feeds / Orders"
        },
        {
          "name": "Account & portfolio feeds / Positions"
        }
      ],
      "messages": {
        "orderUpdate": {
          "$ref": "#/components/messages/OrderUpdateMessage"
        },
        "positionClosed": {
          "$ref": "#/components/messages/PositionClosedMessage"
        },
        "positionOpened": {
          "$ref": "#/components/messages/PositionOpenedMessage"
        },
        "authenticateRequest": {
          "$ref": "#/components/messages/AuthenticateRequest"
        },
        "subscribeRequest": {
          "$ref": "#/components/messages/SubscribeRequest"
        },
        "unsubscribeRequest": {
          "$ref": "#/components/messages/UnsubscribeRequest"
        },
        "operationResponse": {
          "$ref": "#/components/messages/OperationResponse"
        }
      },
      "bindings": {
        "ws": {
          "method": "GET",
          "bindingVersion": "0.1.0"
        }
      }
    }
  },
  "operations": {
    "authenticate": {
      "action": "send",
      "channel": {
        "$ref": "#/channels/connectionAuthenticate"
      },
      "title": "Authenticate",
      "tags": [
        {
          "name": "Session & subscriptions"
        }
      ],
      "summary": "Client → server. Authenticate the session before subscribing to private topics.",
      "description": "Send your `userKey` and `apiKey`. Required before subscribing to a private topic (`private`, `private:real`, `private:demo`); public market topics (`instrument:*`) can be subscribed to without authenticating.",
      "messages": [
        {
          "$ref": "#/channels/connectionAuthenticate/messages/authenticateRequest"
        }
      ],
      "reply": {
        "channel": {
          "$ref": "#/channels/connectionAuthenticate"
        },
        "messages": [
          {
            "$ref": "#/channels/connectionAuthenticate/messages/operationResponse"
          }
        ]
      },
      "security": [
        {
          "$ref": "#/components/securitySchemes/apiKeyPair"
        }
      ],
      "x-auth-required": false
    },
    "subscribe": {
      "action": "send",
      "channel": {
        "$ref": "#/channels/connectionSubscribe"
      },
      "title": "Subscribe",
      "tags": [
        {
          "name": "Session & subscriptions"
        }
      ],
      "summary": "Client → server. Subscribe to one or more topics.",
      "description": "Topics are logical channels multiplexed over the one connection — e.g. `instrument:100000` (public market rates) or the authenticated user's order/portfolio updates: `private` (or its alias `private:real`) for the real account, `private:demo` for the demo account. Set `snapshot: true` to receive the current state immediately after subscribing.",
      "messages": [
        {
          "$ref": "#/channels/connectionSubscribe/messages/subscribeRequest"
        }
      ],
      "reply": {
        "channel": {
          "$ref": "#/channels/connectionSubscribe"
        },
        "messages": [
          {
            "$ref": "#/channels/connectionSubscribe/messages/operationResponse"
          }
        ]
      },
      "x-auth-required": false
    },
    "unsubscribe": {
      "action": "send",
      "channel": {
        "$ref": "#/channels/connectionUnsubscribe"
      },
      "title": "Unsubscribe",
      "tags": [
        {
          "name": "Session & subscriptions"
        }
      ],
      "summary": "Client → server. Stop receiving messages for one or more topics.",
      "messages": [
        {
          "$ref": "#/channels/connectionUnsubscribe/messages/unsubscribeRequest"
        }
      ],
      "reply": {
        "channel": {
          "$ref": "#/channels/connectionUnsubscribe"
        },
        "messages": [
          {
            "$ref": "#/channels/connectionUnsubscribe/messages/operationResponse"
          }
        ]
      },
      "x-auth-required": false
    },
    "receiveInstrumentCandle": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/instrumentCandles"
      },
      "title": "Instrument candle updates",
      "tags": [
        {
          "name": "Market data feeds / Candles"
        }
      ],
      "summary": "Server -> client. Pushed continuously after subscribing to candle:{instrumentId}.",
      "description": "**Server -> client.** You receive these pushes only after subscribing to the candle topic on the control channel (`/ws`).\n\n**To start this feed**, send a `Subscribe` request with the candle topic. No authentication is required for public market data:\n\n```json\n{\n  \"id\": \"<guid>\",\n  \"operation\": \"Subscribe\",\n  \"data\": { \"topics\": [\"candle:100000\"], \"snapshot\": false }\n}\n```\n\n**To stop it**, send an `Unsubscribe` with the same topic.",
      "messages": [
        {
          "$ref": "#/channels/instrumentCandles/messages/instrumentCandle"
        }
      ],
      "x-auth-required": false
    },
    "receiveInstrumentMarketStatus": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/instrumentRates"
      },
      "title": "Instrument market status",
      "tags": [
        {
          "name": "Market data feeds / Status"
        }
      ],
      "summary": "Server → client. Pushed when an instrument's market status changes (open / closed / halted). (Illustrative example type.)",
      "description": "**Server → client.** Delivered on the `instrument:{instrumentId}` topic you subscribed to (no authentication required). (Illustrative example of an additional market-data message type contributed by its owning team — each type is its own operation + fragment.)",
      "messages": [
        {
          "$ref": "#/channels/instrumentRates/messages/marketStatus"
        }
      ],
      "x-auth-required": false
    },
    "receiveInstrumentRates": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/instrumentRates"
      },
      "title": "Instrument rate updates",
      "tags": [
        {
          "name": "Market data feeds / Rates"
        }
      ],
      "summary": "Server → client. Pushed continuously after subscribing to instrument:{instrumentId}.",
      "description": "**Server → client.** You receive these pushes only after subscribing to the instrument topic on the control channel (`/ws`).\n\n**To start this feed**, send a `Subscribe` request with the instrument topic (set `snapshot: true` to also get the current rate immediately). No authentication is required for public market data:\n\n```json\n{\n  \"id\": \"<guid>\",\n  \"operation\": \"Subscribe\",\n  \"data\": { \"topics\": [\"instrument:100000\"], \"snapshot\": false }\n}\n```\n\n**To stop it**, send an `Unsubscribe` with the same topic. See the `subscribe` operation for the full request schema.",
      "messages": [
        {
          "$ref": "#/channels/instrumentRates/messages/instrumentRate"
        }
      ],
      "x-auth-required": false
    },
    "receiveOrderUpdate": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/privatePortfolio"
      },
      "title": "Order update",
      "tags": [
        {
          "name": "Account & portfolio feeds / Orders"
        }
      ],
      "summary": "Server → client. Order / transaction update on the authenticated `private` topic.",
      "description": "**Server → client.** You receive these pushes only after (1) a successful `Authenticate` and (2) subscribing to a private topic on the control channel (`/ws`): `private` (or its alias `private:real`) for your real account and `private:demo` for your demo account.\n\n**Step 1 — authenticate:**\n\n```json\n{\n  \"id\": \"<guid>\",\n  \"operation\": \"Authenticate\",\n  \"data\": { \"userKey\": \"<your user key>\", \"apiKey\": \"<your API key>\" }\n}\n```\n\n**Step 2 — subscribe to the private topic:**\n\n```json\n{\n  \"id\": \"<guid>\",\n  \"operation\": \"Subscribe\",\n  \"data\": { \"topics\": [\"private\"] }\n}\n```\n\nFor your demo account, subscribe to `private:demo` instead (or as well).\n\n**To stop it**, send an `Unsubscribe` with the same topic.",
      "messages": [
        {
          "$ref": "#/channels/privatePortfolio/messages/orderUpdate"
        }
      ],
      "x-auth-required": true,
      "security": [
        {
          "$ref": "#/components/securitySchemes/apiKeyPair"
        }
      ]
    },
    "receivePositionClosed": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/privatePortfolio"
      },
      "title": "Position closed",
      "tags": [
        {
          "name": "Account & portfolio feeds / Positions"
        }
      ],
      "summary": "Server -> client. Pushed when a position is closed for the authenticated user.",
      "description": "**Server -> client.** Delivered on the authenticated `private` topic. To receive it, `Authenticate` then `Subscribe` with `{ \"topics\": [\"private\"] }`.",
      "messages": [
        {
          "$ref": "#/channels/privatePortfolio/messages/positionClosed"
        }
      ],
      "x-auth-required": true,
      "security": [
        {
          "$ref": "#/components/securitySchemes/apiKeyPair"
        }
      ]
    },
    "receivePositionOpened": {
      "action": "receive",
      "channel": {
        "$ref": "#/channels/privatePortfolio"
      },
      "title": "Position opened",
      "tags": [
        {
          "name": "Account & portfolio feeds / Positions"
        }
      ],
      "summary": "Server → client. Pushed when a new position is opened. (Illustrative example type.)",
      "description": "**Server → client.** Delivered on the authenticated `private` topic. To receive it, `Authenticate` then `Subscribe` with `{ \"topics\": [\"private\"] }`. (Illustrative example of an additional private message type contributed by its owning team — each type is its own operation + fragment.)",
      "messages": [
        {
          "$ref": "#/channels/privatePortfolio/messages/positionOpened"
        }
      ],
      "x-auth-required": true,
      "security": [
        {
          "$ref": "#/components/securitySchemes/apiKeyPair"
        }
      ]
    },
    "instrumentCandlesAuthenticate": {
      "action": "send",
      "title": "Authenticate",
      "summary": "Authenticate the connection. Required before subscribing to `candle:{instrumentId}`.",
      "channel": {
        "$ref": "#/channels/instrumentCandles"
      },
      "messages": [
        {
          "$ref": "#/channels/instrumentCandles/messages/authenticateRequest"
        }
      ]
    },
    "instrumentCandlesSubscribe": {
      "action": "send",
      "title": "Subscribe",
      "summary": "Subscribe to `candle:{instrumentId}`.",
      "channel": {
        "$ref": "#/channels/instrumentCandles"
      },
      "messages": [
        {
          "$ref": "#/channels/instrumentCandles/messages/subscribeRequest"
        }
      ]
    },
    "instrumentCandlesUnsubscribe": {
      "action": "send",
      "title": "Unsubscribe",
      "summary": "Unsubscribe from `candle:{instrumentId}`.",
      "channel": {
        "$ref": "#/channels/instrumentCandles"
      },
      "messages": [
        {
          "$ref": "#/channels/instrumentCandles/messages/unsubscribeRequest"
        }
      ]
    },
    "instrumentRatesAuthenticate": {
      "action": "send",
      "title": "Authenticate",
      "summary": "Authenticate the connection. Required before subscribing to `instrument:{instrumentId}`.",
      "channel": {
        "$ref": "#/channels/instrumentRates"
      },
      "messages": [
        {
          "$ref": "#/channels/instrumentRates/messages/authenticateRequest"
        }
      ]
    },
    "instrumentRatesSubscribe": {
      "action": "send",
      "title": "Subscribe",
      "summary": "Subscribe to `instrument:{instrumentId}`.",
      "channel": {
        "$ref": "#/channels/instrumentRates"
      },
      "messages": [
        {
          "$ref": "#/channels/instrumentRates/messages/subscribeRequest"
        }
      ]
    },
    "instrumentRatesUnsubscribe": {
      "action": "send",
      "title": "Unsubscribe",
      "summary": "Unsubscribe from `instrument:{instrumentId}`.",
      "channel": {
        "$ref": "#/channels/instrumentRates"
      },
      "messages": [
        {
          "$ref": "#/channels/instrumentRates/messages/unsubscribeRequest"
        }
      ]
    },
    "privatePortfolioAuthenticate": {
      "action": "send",
      "title": "Authenticate",
      "summary": "Authenticate the connection. Required before subscribing to `private`.",
      "channel": {
        "$ref": "#/channels/privatePortfolio"
      },
      "messages": [
        {
          "$ref": "#/channels/privatePortfolio/messages/authenticateRequest"
        }
      ]
    },
    "privatePortfolioSubscribe": {
      "action": "send",
      "title": "Subscribe",
      "summary": "Subscribe to `private`.",
      "channel": {
        "$ref": "#/channels/privatePortfolio"
      },
      "messages": [
        {
          "$ref": "#/channels/privatePortfolio/messages/subscribeRequest"
        }
      ]
    },
    "privatePortfolioUnsubscribe": {
      "action": "send",
      "title": "Unsubscribe",
      "summary": "Unsubscribe from `private`.",
      "channel": {
        "$ref": "#/channels/privatePortfolio"
      },
      "messages": [
        {
          "$ref": "#/channels/privatePortfolio/messages/unsubscribeRequest"
        }
      ]
    }
  },
  "components": {
    "messages": {
      "OperationResponse": {
        "name": "OperationResponse",
        "title": "Operation acknowledgement",
        "summary": "Server acknowledgement for an Authenticate / Subscribe / Unsubscribe request.",
        "description": "**Server -> client.** Acknowledgement of an `Authenticate`, `Subscribe` or `Unsubscribe` request. The `id` echoes the client-generated `id` of the request it answers, which is how a client correlates a reply with its request when several are in flight. Inspect it to confirm the request succeeded before relying on the subscription.",
        "tags": [
          {
            "name": "Session & subscriptions"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/OperationResponse"
        },
        "examples": [
          {
            "name": "success",
            "payload": {
              "id": "ed72693c-1545-4fa1-8a10-aca7cf5419a6",
              "success": true,
              "operation": "Authenticate"
            }
          },
          {
            "name": "failure",
            "payload": {
              "id": "ed72693c-1545-4fa1-8a10-aca7cf5419a6",
              "success": false,
              "operation": "Authenticate",
              "errorMessage": "Key is invalid",
              "errorCode": "InvalidKey"
            }
          }
        ]
      },
      "AuthenticateRequest": {
        "name": "AuthenticateRequest",
        "title": "Authenticate request",
        "summary": "Authenticate the WebSocket session with your API credentials.",
        "description": "**Client -> server.** Opening request of an authenticated session. Carries the `userKey` / `apiKey` pair in `data`; the credentials travel in this payload over the already-open socket, never as an HTTP header. The server replies with an `OperationResponse` echoing the client-generated `id`. Required before subscribing to a private topic (`private`, `private:real`, `private:demo`); public market topics (`instrument:<instrumentId>`) need no authentication.",
        "tags": [
          {
            "name": "Session & subscriptions"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/AuthenticateEnvelope"
        },
        "examples": [
          {
            "name": "authenticate",
            "payload": {
              "id": "ed72693c-1545-4fa1-8a10-aca7cf5419a6",
              "operation": "Authenticate",
              "data": {
                "userKey": "<your user key>",
                "apiKey": "<your API key>"
              }
            }
          }
        ]
      },
      "SubscribeRequest": {
        "name": "SubscribeRequest",
        "title": "Subscribe request",
        "summary": "Subscribe to one or more topics.",
        "description": "**Client -> server.** Starts delivery of one or more topics named in `data.topics`. Set `data.snapshot` to request the current state up front in addition to subsequent updates. The server replies with an `OperationResponse` echoing the client-generated `id`; push messages for the topic follow on the matching channel.",
        "tags": [
          {
            "name": "Session & subscriptions"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/SubscribeEnvelope"
        },
        "examples": [
          {
            "name": "subscribe-instrument",
            "payload": {
              "id": "ed72693c-1545-4fa1-8a10-aca7cf5419a6",
              "operation": "Subscribe",
              "data": {
                "topics": [
                  "instrument:100000"
                ],
                "snapshot": false
              }
            }
          }
        ]
      },
      "UnsubscribeRequest": {
        "name": "UnsubscribeRequest",
        "title": "Unsubscribe request",
        "summary": "Stop receiving messages for one or more topics.",
        "description": "**Client -> server.** Stops delivery of the topics named in `data.topics`, leaving the socket open and other subscriptions untouched. The server replies with an `OperationResponse` echoing the client-generated `id`.",
        "tags": [
          {
            "name": "Session & subscriptions"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/UnsubscribeEnvelope"
        },
        "examples": [
          {
            "name": "unsubscribe-instrument",
            "payload": {
              "id": "ed72693c-1545-4fa1-8a10-aca7cf5419a6",
              "operation": "Unsubscribe",
              "data": {
                "topics": [
                  "instrument:100000"
                ]
              }
            }
          }
        ]
      },
      "InstrumentCandleMessage": {
        "name": "InstrumentCandleMessage",
        "title": "Instrument candle push",
        "summary": "A batch of one or more instrument candle updates.",
        "description": "**Server -> client.** A batch of one or more OHLC candle updates for instruments you have subscribed to, delivered on the `instrument:<instrumentId>` topic. Public market data - no authentication required. Each envelope entry's `content` is a JSON-encoded **string**: parse it to obtain the typed object described by the message's payload schema.",
        "tags": [
          {
            "name": "Market data feeds / Candles"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InstrumentCandleEnvelope"
        },
        "examples": [
          {
            "name": "instrument-candle",
            "payload": {
              "messages": [
                {
                  "topic": "candle:100000",
                  "content": "{\"InstrumentID\":100000,\"Interval\":\"1m\",\"Open\":83900.10,\"High\":84200.55,\"Low\":83850.00,\"Close\":84072.94,\"Volume\":12.348,\"OpenTime\":\"2025-04-01T08:36:00Z\",\"CloseTime\":\"2025-04-01T08:37:00Z\"}",
                  "id": "c92e5f3b-8d4a-4b71-9e23-6f7a8b9c0d12",
                  "type": "Trading.Instrument.Candle"
                }
              ]
            }
          }
        ]
      },
      "InstrumentMarketStatusMessage": {
        "name": "InstrumentMarketStatusMessage",
        "title": "Instrument market status",
        "summary": "Pushed when an instrument's market opens, closes or is halted. (Illustrative example type.)",
        "description": "**Server -> client.** Pushed when a subscribed instrument's market opens, closes or is halted, on the `instrument:<instrumentId>` topic. Public market data - no authentication required. Use it to gate order entry and to explain why rate updates have stopped for an instrument. Each envelope entry's `content` is a JSON-encoded **string** - parse it to obtain the typed object.",
        "tags": [
          {
            "name": "Market data feeds / Status"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InstrumentMarketStatusEnvelope"
        },
        "examples": [
          {
            "name": "market-status",
            "payload": {
              "messages": [
                {
                  "topic": "instrument:100000",
                  "content": "{\"InstrumentID\":100000,\"Status\":\"Open\",\"IsTradable\":true,\"AsOf\":\"2025-04-01T08:00:00Z\"}",
                  "id": "a3b1c2d4-5e6f-7081-92a3-b4c5d6e7f809",
                  "type": "Trading.Instrument.MarketStatus"
                }
              ]
            }
          }
        ]
      },
      "InstrumentRateMessage": {
        "name": "InstrumentRateMessage",
        "title": "Instrument rate push",
        "summary": "A batch of one or more instrument rate updates.",
        "description": "**Server -> client.** A batch of one or more bid/ask rate updates for instruments you have subscribed to, delivered on the `instrument:<instrumentId>` topic. Public market data - no authentication required. This is the highest-frequency feed; expect batching. Each envelope entry's `content` is a JSON-encoded **string** - parse it to obtain the typed object.",
        "tags": [
          {
            "name": "Market data feeds / Rates"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/InstrumentRateEnvelope"
        },
        "examples": [
          {
            "name": "instrument-rate",
            "payload": {
              "messages": [
                {
                  "topic": "instrument:100000",
                  "content": "{\"Ask\":\"84917.73\",\"Bid\":\"83232.21\",\"LastExecution\":\"84072.94\",\"Date\":\"2025-04-01T08:36:02.8305456Z\",\"PriceRateID\":\"106439224591\"}",
                  "id": "f1992278-2c4a-4b8f-92d6-8b99f5e1cb00",
                  "type": "Trading.Instrument.Rate"
                }
              ]
            }
          }
        ]
      },
      "OrderUpdateMessage": {
        "name": "OrderUpdateMessage",
        "title": "Order update push",
        "summary": "A batch of one or more order / transaction updates for the authenticated user.",
        "description": "**Server -> client.** A batch of one or more order and transaction updates for the authenticated user, scoped to your account topic. Requires a successful `Authenticate` and a subscription to your private topic. Each envelope entry's `content` is a JSON-encoded **string** - parse it to obtain the typed object described by the payload schema.",
        "tags": [
          {
            "name": "Account & portfolio feeds / Orders"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/OrderUpdateEnvelope"
        },
        "examples": [
          {
            "name": "order-update",
            "payload": {
              "messages": [
                {
                  "topic": "private",
                  "content": "{\"OrderID\":981286176,\"OrderType\":20,\"CID\":32612044,\"StatusID\":11,\"InstrumentID\":1111,\"RequestGuid\":\"fca38698-1fcf-407d-b930-3222e57274fa\",\"RequestOccurred\":\"2025-04-01T08:55:53.6910145Z\",\"ErrorCode\":0,\"RequestedUnits\":13.859902,\"ExecutedUnits\":0.0}",
                  "id": "5263070a-c52f-436b-8ca8-10b3bd6d2970",
                  "type": "Trading.OrderForCloseMultiple.Update"
                }
              ]
            }
          }
        ]
      },
      "PositionClosedMessage": {
        "name": "PositionClosedMessage",
        "title": "Position closed",
        "summary": "Pushed when a position is closed for the authenticated user.",
        "description": "**Server -> client.** Pushed when a position is closed for the authenticated user, scoped to your account topic. Requires a successful `Authenticate` and a subscription to your private topic. Each envelope entry's `content` is a JSON-encoded **string** - parse it to obtain the typed object described by the payload schema.",
        "tags": [
          {
            "name": "Account & portfolio feeds / Positions"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/PositionClosedEnvelope"
        },
        "examples": [
          {
            "name": "position-closed",
            "payload": {
              "messages": [
                {
                  "topic": "private",
                  "content": "{\"PositionID\":2980225895,\"InstrumentID\":1001,\"CloseRate\":188.42,\"NetProfit\":30.62,\"CloseReason\":1,\"CloseDateTime\":\"2025-04-01T09:42:11.1234567Z\"}",
                  "id": "b81d4e2a-7c3f-4a90-9d12-5e6f7a8b9c01",
                  "type": "Trading.Position.Closed"
                }
              ]
            }
          }
        ]
      },
      "PositionOpenedMessage": {
        "name": "PositionOpenedMessage",
        "title": "Position opened",
        "summary": "Pushed when a new position is opened for the authenticated user. (Illustrative example of an additional private message type.)",
        "description": "**Server -> client.** Pushed when a new position is opened for the authenticated user, scoped to your account topic. Requires a successful `Authenticate` and a subscription to your private topic. Each envelope entry's `content` is a JSON-encoded **string** - parse it to obtain the typed object described by the payload schema.",
        "tags": [
          {
            "name": "Account & portfolio feeds / Positions"
          }
        ],
        "contentType": "application/json",
        "payload": {
          "$ref": "#/components/schemas/PositionOpenedEnvelope"
        },
        "examples": [
          {
            "name": "position-opened",
            "payload": {
              "messages": [
                {
                  "topic": "private",
                  "content": "{\"PositionID\":2980225895,\"InstrumentID\":1001,\"IsBuy\":true,\"OpenRate\":182.30,\"Amount\":500.0,\"Leverage\":2,\"OpenDateTime\":\"2025-04-01T08:55:53.6910145Z\"}",
                  "id": "7c2f0a1b-9d3e-4f6a-8b21-2c4a6e8f1d00",
                  "type": "Trading.Position.Opened"
                }
              ]
            }
          }
        ]
      }
    },
    "schemas": {
      "OperationResponse": {
        "type": "object",
        "description": "Acknowledgement returned for each control request.",
        "required": [
          "id",
          "success",
          "operation"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Echoes the `id` of the request being acknowledged."
          },
          "success": {
            "type": "boolean"
          },
          "operation": {
            "type": "string",
            "enum": [
              "Authenticate",
              "Subscribe",
              "Unsubscribe"
            ]
          },
          "errorMessage": {
            "type": "string",
            "description": "Present when success is false.",
            "examples": [
              "Key is invalid"
            ]
          },
          "errorCode": {
            "type": "string",
            "description": "Present when success is false.",
            "examples": [
              "InvalidKey",
              "Unauthorized",
              "TooManyRequests",
              "Forbidden",
              "DataRequired",
              "ApiKeyRequired",
              "UserKeyRequired",
              "SessionAlreadyAuthenticated",
              "UnhandledException"
            ]
          }
        }
      },
      "AuthenticateEnvelope": {
        "type": "object",
        "description": "Client request envelope for the Authenticate operation.",
        "required": [
          "id",
          "operation",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Client-generated correlation id, echoed back on the acknowledgement.",
            "examples": [
              "ed72693c-1545-4fa1-8a10-aca7cf5419a6"
            ]
          },
          "operation": {
            "type": "string",
            "enum": [
              "Authenticate"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/AuthenticateData"
          }
        }
      },
      "AuthenticateData": {
        "type": "object",
        "required": [
          "userKey",
          "apiKey"
        ],
        "properties": {
          "userKey": {
            "type": "string",
            "description": "Your etoro user key (x-user-key)."
          },
          "apiKey": {
            "type": "string",
            "description": "Your etoro API key (x-api-key)."
          }
        }
      },
      "SubscribeEnvelope": {
        "type": "object",
        "description": "Client request envelope for the Subscribe operation.",
        "required": [
          "id",
          "operation",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "examples": [
              "ed72693c-1545-4fa1-8a10-aca7cf5419a6"
            ]
          },
          "operation": {
            "type": "string",
            "enum": [
              "Subscribe"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/SubscribeData"
          }
        }
      },
      "SubscribeData": {
        "type": "object",
        "required": [
          "topics"
        ],
        "properties": {
          "topics": {
            "type": "array",
            "description": "Topics to subscribe to. e.g. `instrument:<instrumentId>` for market rates, or the authenticated user's order/portfolio updates: `private` (or its alias `private:real`) for the real account, `private:demo` for the demo account.",
            "items": {
              "type": "string",
              "examples": [
                "instrument:100000",
                "private",
                "private:real",
                "private:demo"
              ]
            }
          },
          "snapshot": {
            "type": "boolean",
            "description": "Applies to market-data topics only (e.g. `instrument:*`): when true, the current rate is sent immediately on subscribe. Has no effect on the private topics.",
            "default": false
          }
        }
      },
      "UnsubscribeEnvelope": {
        "type": "object",
        "description": "Client request envelope for the Unsubscribe operation.",
        "required": [
          "id",
          "operation",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "examples": [
              "ed72693c-1545-4fa1-8a10-aca7cf5419a6"
            ]
          },
          "operation": {
            "type": "string",
            "enum": [
              "Unsubscribe"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/UnsubscribeData"
          }
        }
      },
      "UnsubscribeData": {
        "type": "object",
        "required": [
          "topics"
        ],
        "properties": {
          "topics": {
            "type": "array",
            "description": "Topics to unsubscribe from.",
            "items": {
              "type": "string",
              "examples": [
                "instrument:100000"
              ]
            }
          }
        }
      },
      "InstrumentCandleEnvelope": {
        "type": "object",
        "description": "Server push envelope. `messages` holds one or more updates.",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InstrumentCandlePushItem"
            }
          }
        }
      },
      "InstrumentCandlePushItem": {
        "type": "object",
        "required": [
          "topic",
          "content",
          "id",
          "type"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "description": "The subscribed topic this update belongs to.",
            "examples": [
              "candle:100000"
            ]
          },
          "type": {
            "type": "string",
            "description": "Message type discriminator.",
            "examples": [
              "Trading.Instrument.Candle"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique id of this push message."
          },
          "content": {
            "type": "string",
            "description": "A JSON-encoded string. Parse it to obtain a Trading.Instrument.Candle object (described by contentSchema).",
            "contentMediaType": "application/json",
            "contentSchema": {
              "$ref": "#/components/schemas/InstrumentCandle"
            }
          }
        }
      },
      "InstrumentCandle": {
        "type": "object",
        "description": "Decoded `content` of a Trading.Instrument.Candle message. THIS is the only part you actually design.",
        "properties": {
          "InstrumentID": {
            "type": "integer",
            "examples": [
              100000
            ]
          },
          "Interval": {
            "type": "string",
            "description": "Candle interval.",
            "examples": [
              "1m",
              "5m",
              "1h"
            ]
          },
          "Open": {
            "type": "number",
            "format": "float"
          },
          "High": {
            "type": "number",
            "format": "float"
          },
          "Low": {
            "type": "number",
            "format": "float"
          },
          "Close": {
            "type": "number",
            "format": "float"
          },
          "Volume": {
            "type": "number",
            "format": "float"
          },
          "OpenTime": {
            "type": "string",
            "format": "date-time"
          },
          "CloseTime": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "InstrumentMarketStatusEnvelope": {
        "type": "object",
        "description": "Server push envelope. `messages` holds one or more updates.",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InstrumentMarketStatusPushItem"
            }
          }
        }
      },
      "InstrumentMarketStatusPushItem": {
        "type": "object",
        "required": [
          "topic",
          "content",
          "id",
          "type"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "examples": [
              "instrument:100000"
            ]
          },
          "type": {
            "type": "string",
            "description": "Message type discriminator.",
            "examples": [
              "Trading.Instrument.MarketStatus"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "content": {
            "type": "string",
            "description": "A JSON-encoded string. Parse it to obtain a Trading.Instrument.MarketStatus object (described by contentSchema).",
            "contentMediaType": "application/json",
            "contentSchema": {
              "$ref": "#/components/schemas/InstrumentMarketStatus"
            }
          }
        }
      },
      "InstrumentMarketStatus": {
        "type": "object",
        "description": "Decoded `content` of a Trading.Instrument.MarketStatus message. (Illustrative example schema.)",
        "properties": {
          "InstrumentID": {
            "type": "integer",
            "examples": [
              100000
            ]
          },
          "Status": {
            "type": "string",
            "enum": [
              "Open",
              "Closed",
              "Halted"
            ],
            "description": "Current market status for the instrument."
          },
          "IsTradable": {
            "type": "boolean",
            "description": "Whether the instrument can currently be traded."
          },
          "AsOf": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the status change."
          }
        }
      },
      "InstrumentRateEnvelope": {
        "type": "object",
        "description": "Server push envelope. `messages` holds one or more updates.",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InstrumentRatePushItem"
            }
          }
        }
      },
      "InstrumentRatePushItem": {
        "type": "object",
        "required": [
          "topic",
          "content",
          "id",
          "type"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "description": "The subscribed topic this update belongs to.",
            "examples": [
              "instrument:100000"
            ]
          },
          "type": {
            "type": "string",
            "description": "Message type discriminator.",
            "examples": [
              "Trading.Instrument.Rate"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique id of this push message."
          },
          "content": {
            "type": "string",
            "description": "A JSON-encoded string. Parse it to obtain a Trading.Instrument.Rate object (described by contentSchema).",
            "contentMediaType": "application/json",
            "contentSchema": {
              "$ref": "#/components/schemas/InstrumentRate"
            }
          }
        }
      },
      "InstrumentRate": {
        "type": "object",
        "description": "Decoded `content` of a Trading.Instrument.Rate message. Note: on the wire every value is a JSON string.",
        "properties": {
          "Ask": {
            "type": "number",
            "format": "float",
            "description": "Current asking (offer) price — the price at which you can buy.",
            "examples": [
              84917.73
            ]
          },
          "Bid": {
            "type": "number",
            "format": "float",
            "description": "Current bid price — the price at which you can sell.",
            "examples": [
              83232.21
            ]
          },
          "LastExecution": {
            "type": "number",
            "format": "float",
            "description": "Price of the most recent trade execution for this instrument."
          },
          "Date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the price in the system."
          },
          "PriceRateID": {
            "type": "string",
            "description": "Unique identifier of the rate.",
            "examples": [
              "106439224591"
            ]
          },
          "NewUnitMargin": {
            "type": "number",
            "format": "float",
            "description": "(Obsolete) USD equivalent of the instrument price."
          },
          "UnitMarginAsk": {
            "type": "number",
            "format": "float",
            "description": "(Obsolete) USD equivalent of the ask price."
          },
          "UnitMarginBid": {
            "type": "number",
            "format": "float",
            "description": "(Obsolete) USD equivalent of the bid price."
          },
          "BidDiscounted": {
            "type": "number",
            "format": "float",
            "description": "Obsolete."
          },
          "AskDiscounted": {
            "type": "number",
            "format": "float",
            "description": "Obsolete."
          },
          "UnitMarginBidDiscounted": {
            "type": "number",
            "format": "float",
            "description": "Obsolete."
          },
          "UnitMarginAskDiscounted": {
            "type": "number",
            "format": "float",
            "description": "Obsolete."
          }
        }
      },
      "OrderUpdateEnvelope": {
        "type": "object",
        "description": "Server push envelope. `messages` holds one or more updates.",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderUpdatePushItem"
            }
          }
        }
      },
      "OrderUpdatePushItem": {
        "type": "object",
        "required": [
          "topic",
          "content",
          "id",
          "type"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "description": "The private topic you subscribed to: `private` or `private:real` (real account), `private:demo` (demo account).",
            "examples": [
              "private",
              "private:real",
              "private:demo"
            ]
          },
          "type": {
            "type": "string",
            "description": "Message type discriminator.",
            "examples": [
              "Trading.OrderForOpen.Update",
              "Trading.OrderForCloseMultiple.Update"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique id of this push message."
          },
          "content": {
            "type": "string",
            "description": "A JSON-encoded string. Parse it to obtain an order update object (described by contentSchema). Parse it to obtain a `OrderUpdate` object.",
            "contentMediaType": "application/json",
            "contentSchema": {
              "$ref": "#/components/schemas/OrderUpdate"
            }
          }
        }
      },
      "OrderUpdate": {
        "type": "object",
        "description": "Decoded `content` of an order update message.",
        "properties": {
          "OrderID": {
            "type": "integer",
            "format": "int64",
            "description": "Unique order identifier.",
            "examples": [
              981286176
            ]
          },
          "OrderType": {
            "type": "integer",
            "description": "Order type code."
          },
          "CID": {
            "type": "integer",
            "format": "int64",
            "description": "Customer (account) id."
          },
          "StatusID": {
            "type": "integer",
            "description": "Order status code."
          },
          "InstrumentID": {
            "type": "integer",
            "description": "Instrument the order refers to.",
            "examples": [
              1111
            ]
          },
          "RequestGuid": {
            "type": "string",
            "format": "uuid"
          },
          "RequestOccurred": {
            "type": "string",
            "format": "date-time"
          },
          "RequestToken": {
            "type": "string",
            "format": "uuid"
          },
          "ErrorCode": {
            "type": "integer",
            "description": "0 when successful."
          },
          "RequestedUnits": {
            "type": "number",
            "format": "float"
          },
          "ExecutedUnits": {
            "type": "number",
            "format": "float"
          },
          "EndRate": {
            "type": "number",
            "format": "float"
          },
          "NetProfit": {
            "type": "number",
            "format": "float"
          },
          "CloseReason": {
            "type": "integer"
          },
          "PendingClosePositionIDs": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            }
          },
          "OpenDateTime": {
            "type": "string",
            "format": "date-time"
          },
          "IsInMirror": {
            "type": "boolean"
          }
        }
      },
      "PositionClosedEnvelope": {
        "type": "object",
        "description": "Server push envelope. `messages` holds one or more updates.",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PositionClosedPushItem"
            }
          }
        }
      },
      "PositionClosedPushItem": {
        "type": "object",
        "required": [
          "topic",
          "content",
          "id",
          "type"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "examples": [
              "private"
            ]
          },
          "type": {
            "type": "string",
            "description": "Message type discriminator.",
            "examples": [
              "Trading.Position.Closed"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "content": {
            "type": "string",
            "description": "A JSON-encoded string. Parse it to obtain a Trading.Position.Closed object (described by contentSchema).",
            "contentMediaType": "application/json",
            "contentSchema": {
              "$ref": "#/components/schemas/PositionClosed"
            }
          }
        }
      },
      "PositionClosed": {
        "type": "object",
        "description": "Decoded `content` of a Trading.Position.Closed message. THIS is the only part you actually design.",
        "properties": {
          "PositionID": {
            "type": "integer",
            "format": "int64",
            "examples": [
              2980225895
            ]
          },
          "InstrumentID": {
            "type": "integer",
            "examples": [
              1001
            ]
          },
          "CloseRate": {
            "type": "number",
            "format": "float",
            "description": "Rate at which the position was closed."
          },
          "NetProfit": {
            "type": "number",
            "format": "float",
            "description": "Net profit/loss realised on close."
          },
          "CloseReason": {
            "type": "integer",
            "description": "Close reason code."
          },
          "CloseDateTime": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PositionOpenedEnvelope": {
        "type": "object",
        "description": "Server push envelope. `messages` holds one or more updates.",
        "required": [
          "messages"
        ],
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PositionOpenedPushItem"
            }
          }
        }
      },
      "PositionOpenedPushItem": {
        "type": "object",
        "required": [
          "topic",
          "content",
          "id",
          "type"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "examples": [
              "private"
            ]
          },
          "type": {
            "type": "string",
            "description": "Message type discriminator.",
            "examples": [
              "Trading.Position.Opened"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "content": {
            "type": "string",
            "description": "A JSON-encoded string. Parse it to obtain a Trading.Position.Opened object (described by contentSchema).",
            "contentMediaType": "application/json",
            "contentSchema": {
              "$ref": "#/components/schemas/PositionOpened"
            }
          }
        }
      },
      "PositionOpened": {
        "type": "object",
        "description": "Decoded `content` of a Trading.Position.Opened message. (Illustrative example schema.)",
        "properties": {
          "PositionID": {
            "type": "integer",
            "format": "int64",
            "examples": [
              2980225895
            ]
          },
          "InstrumentID": {
            "type": "integer",
            "examples": [
              1001
            ]
          },
          "IsBuy": {
            "type": "boolean",
            "description": "True for a buy (long) position, false for sell (short)."
          },
          "OpenRate": {
            "type": "number",
            "format": "float",
            "description": "Rate at which the position was opened."
          },
          "Amount": {
            "type": "number",
            "format": "float",
            "description": "Invested amount."
          },
          "Leverage": {
            "type": "integer"
          },
          "OpenDateTime": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyPair": {
        "type": "userPassword",
        "description": "etoro API credentials, sent as a pair inside the `Authenticate` request's `data` object -- `userKey` (the user identifier) and `apiKey` (the secret) -- not as an HTTP header. Required before subscribing to the `private` topic; public market topics (`instrument:<instrumentId>`) need no authentication. Both values come from the API key section of etoro account settings, which appears once the account is verified."
      }
    }
  }
}
