{
  "components": {
    "examples": {},
    "headers": {},
    "parameters": {},
    "requestBodies": {},
    "responses": {},
    "schemas": {
      "AccessTokenItem": {
        "properties": {
          "expiresAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "permissions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": ["expiresAt", "permissions", "name", "id"],
        "type": "object"
      },
      "AccessTokenResult": {
        "properties": {
          "id": {
            "type": "string"
          },
          "token": {
            "type": "string"
          }
        },
        "required": ["id", "token"],
        "type": "object"
      },
      "AddSessionCompleteChallengeParams": {
        "properties": {
          "challengeId": {
            "type": "string"
          },
          "challengeResponse": {
            "type": "string"
          }
        },
        "required": ["challengeResponse", "challengeId"],
        "type": "object"
      },
      "AddSessionParams": {
        "properties": {
          "brokerName": {
            "$ref": "#/components/schemas/BrokerName"
          },
          "env": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": ["password", "username", "env", "brokerName"],
        "type": "object"
      },
      "Amount": {
        "properties": {
          "currency": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "date": {
            "$ref": "#/components/schemas/DateString",
            "description": "If the amount is valid at a given calendar date (without daytime information), this can be set."
          },
          "isRealtime": {
            "description": "If this is present and true, a \"value is provided in realtime\" indicator can be displayed.\nIf this is present and false, a \"value is provided delayed\" indicator can be displayed.\nIf this is not present, no such indication is available.",
            "type": "boolean"
          },
          "maxDecimals": {
            "format": "int32",
            "type": "integer"
          },
          "minDecimals": {
            "format": "int32",
            "type": "integer"
          },
          "timestamp": {
            "description": "If the amount is valid at a given point in time, this can be set (e.g. for quotes). This is a UNIX timestamp in milliseconds.",
            "format": "int64",
            "type": "integer"
          },
          "value": {
            "format": "double",
            "type": "number"
          }
        },
        "type": "object"
      },
      "AuthInfo": {
        "properties": {
          "allOperationsRequireSessionTan": {
            "description": "If this is present and true, the only operation that the AuthMethods can be used to is to activate Session TAN (`session.authorizeSessionTan`).\nAll other operations (e.g. order creation etc.) require Session TAN to be activated first.",
            "type": "boolean"
          },
          "authMethods": {
            "items": {
              "$ref": "#/components/schemas/AuthMethod"
            },
            "type": "array"
          },
          "sessionTanActive": {
            "type": "boolean"
          },
          "sessionTanCanBeEnded": {
            "description": "If this is true, session TAN can be ended using the `EndSessionTan` endpoint when it is no longer needed, leaving the\nsession active. This is not supported by all brokers.",
            "type": "boolean"
          },
          "sessionTanSupported": {
            "type": "boolean"
          }
        },
        "required": ["authMethods", "sessionTanCanBeEnded"],
        "type": "object"
      },
      "AuthMethod": {
        "discriminator": {
          "mapping": {
            "CHALLENGE_RESPONSE": "#/components/schemas/AuthMethodChallengeResponse",
            "DECOUPLED": "#/components/schemas/AuthMethodDecoupled",
            "TAN": "#/components/schemas/AuthMethodTan"
          },
          "propertyName": "flow"
        },
        "properties": {
          "flow": {
            "$ref": "#/components/schemas/AuthMethodFlow"
          }
        },
        "required": ["flow"],
        "type": "object"
      },
      "AuthMethodChallengeResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AuthMethod"
          },
          {
            "$ref": "#/components/schemas/AuthMethodChallengeResponseSpecifics"
          }
        ],
        "description": "With the `CHALLENGE_RESPONSE` flow, to execute an operation, a challenge has to be created as the first step\nand the response to the challenge will be provided with the actual operation as a second API call:\n\n1) The end user requests challenge with a button labelled `getChallengeLabel`, which triggers the `createXYZChallenge` endpoint (e.g. `CreateSessionTanChallenge`)\n2) The challenge is then presented to the user. It may be a code to look up from a sheet of paper, a photoTAN to scan with the\n   broker's mobile app or anything else (details are described in `Challenge`).\n3) `AuthMethod.challengeResponseIsOnlyConfirmation` determines if and how the user must actually enter a response text:\n   - If `challengeResponseIsOnlyConfirmation=true`: the final API call (e.g. `EnableSessionTan`) is only a confirmation of some second factor (i.e. the user tells us they\n     have allowed the action in their broker's mobile app). In this case, the `challengeResponse` must be sent as an empty string once\n     the user clicks the corresponding confirm button.\n   - Otherwise, the user is expected to provide a textual `challengeResponse`. In this case, a text field for the `challengeResponse` must be displayed\n     and labelled with `tanFieldLabel`. The  `challengeResponse` is sent as entered by the user to the actual action endpoint (e.g. `EnableSessionTan`)",
        "required": ["tanFieldLabel", "getChallengeLabel", "label", "flow", "id"],
        "type": "object"
      },
      "AuthMethodChallengeResponseSpecifics": {
        "properties": {
          "challengeLabel": {
            "type": "string"
          },
          "challengeResponseIsOnlyConfirmation": {
            "type": "boolean"
          },
          "getChallengeLabel": {
            "type": "string"
          },
          "hideOnPhones": {
            "description": "If this is true, the auth method should not be offered to users on phones (e.g. for photoTAN, where the TAN has to\nbe scanned with a phone).",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "isDefaultMethod": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          },
          "tanFieldLabel": {
            "type": "string"
          }
        }
      },
      "AuthMethodDecoupled": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AuthMethod"
          },
          {
            "$ref": "#/components/schemas/AuthMethodDecoupledSpecifics"
          }
        ],
        "description": "With the `DECOUPLED` flow, the operation is created right away without creating a challenge first. The operation's\nresponse will include a `decoupledOperationId` which can be subscribed to using `GetDecoupledOperationStatus` and via\na WebSocket subscription. Also, the operation can be cancelled by the user using `CancelDecoupledOperation`.",
        "required": ["label", "flow", "id"],
        "type": "object"
      },
      "AuthMethodDecoupledSpecifics": {
        "properties": {
          "hideOnPhones": {
            "description": "If this is true, the auth method should not be offered to users on phones (e.g. for photoTAN, where the TAN has to\nbe scanned with a phone).",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "isDefaultMethod": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          }
        }
      },
      "AuthMethodFlow": {
        "enum": ["TAN", "DECOUPLED", "CHALLENGE_RESPONSE"],
        "nullable": false,
        "type": "string"
      },
      "AuthMethodTan": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AuthMethod"
          },
          {
            "$ref": "#/components/schemas/AuthMethodTanSpecifics"
          }
        ],
        "description": "With the `TAN` flow, a TAN can be sent with the operation right away, i.e. without creating a challenge first.\nThis may be the case for brokers that provide a fixed trading password or a list of TANs where the user\nmay select an arbitrary TAN from the list.",
        "required": ["tanFieldLabel", "label", "flow", "id"],
        "type": "object"
      },
      "AuthMethodTanSpecifics": {
        "properties": {
          "hideOnPhones": {
            "description": "If this is true, the auth method should not be offered to users on phones (e.g. for photoTAN, where the TAN has to\nbe scanned with a phone).",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "isDefaultMethod": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          },
          "tanFieldLabel": {
            "type": "string"
          }
        }
      },
      "AvailablePermissionsNode": {
        "properties": {
          "children": {
            "items": {
              "$ref": "#/components/schemas/AvailablePermissionsNode"
            },
            "type": "array"
          },
          "description": {
            "type": "string"
          },
          "permission": {
            "type": "string"
          }
        },
        "required": ["description", "permission"],
        "type": "object"
      },
      "BitpandaClientCfg": {
        "properties": {
          "clientIdProduction": {
            "type": "string"
          },
          "clientIdStaging": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "BrokerClientCfg": {
        "properties": {
          "bitpanda": {
            "$ref": "#/components/schemas/BitpandaClientCfg"
          },
          "coinbase": {
            "$ref": "#/components/schemas/CoinbaseClientCfg"
          }
        },
        "type": "object"
      },
      "BrokerEnvFilterMap": {
        "additionalProperties": {
          "$ref": "#/components/schemas/BrokerEnvFilterType"
        },
        "properties": {},
        "type": "object"
      },
      "BrokerEnvFilterType": {
        "enum": ["NONE", "ALL_AVAILABLE", "TESTING_ONLY", "PRODUCTION_ONLY"],
        "type": "string"
      },
      "BrokerEnvironment": {
        "properties": {
          "id": {
            "type": "string"
          },
          "isTestingEnvironment": {
            "type": "boolean"
          },
          "label": {
            "type": "string"
          }
        },
        "required": ["isTestingEnvironment", "label", "id"],
        "type": "object"
      },
      "BrokerLoginForm": {
        "description": "If a login form can be shown for the broker, describes the fields to show.",
        "properties": {
          "passwordField": {
            "$ref": "#/components/schemas/BrokerLoginFormField"
          },
          "usernameField": {
            "$ref": "#/components/schemas/BrokerLoginFormField"
          }
        },
        "required": ["passwordField", "usernameField"],
        "type": "object"
      },
      "BrokerLoginFormField": {
        "properties": {
          "label": {
            "type": "string"
          },
          "type": {
            "enum": ["string", "password"],
            "type": "string"
          }
        },
        "required": ["label", "type"],
        "type": "object"
      },
      "BrokerMeta": {
        "properties": {
          "brokerName": {
            "$ref": "#/components/schemas/BrokerName"
          },
          "displayName": {
            "type": "string"
          },
          "envLabel": {
            "description": "If the user may choose the environment, it should usually be displayed as a select box in UIs.\nThe field's label explains what the meaning of environment is in the broker's context.",
            "type": "string"
          },
          "envs": {
            "items": {
              "$ref": "#/components/schemas/BrokerEnvironment"
            },
            "type": "array"
          },
          "features": {
            "properties": {
              "orderExchangeNames": {
                "description": "If set and `true`, orders retrieved in order lists or individually via `GetOrder` are expected to contain the `exchangeName` field.\nSome brokers do not provide this information, so it is fine to hide the column in the UI if this is not true.",
                "type": "boolean"
              },
              "positionProfitLossAbsPrevClose": {
                "description": "If set and `true`, `Position.profitLossAbsPrevClose` is generally available for positions of this broker.",
                "type": "boolean"
              },
              "positionProfitLossRel": {
                "description": "If set and `true`, `Position.profitLossRel` is generally available for positions of this broker.",
                "type": "boolean"
              },
              "positionProfitLossRelPrevClose": {
                "description": "If set and `true`, `Position.profitLossRelPrevClose` is generally available for positions of this broker.",
                "type": "boolean"
              },
              "supportedOrderStatuses": {
                "items": {
                  "$ref": "#/components/schemas/OrderStatus"
                },
                "type": "array"
              }
            },
            "required": ["supportedOrderStatuses"],
            "type": "object"
          },
          "images": {
            "properties": {
              "dark": {
                "type": "string"
              },
              "darkSquare": {
                "type": "string"
              },
              "light": {
                "type": "string"
              },
              "lightSquare": {
                "type": "string"
              }
            },
            "required": ["lightSquare", "darkSquare", "light", "dark"],
            "type": "object"
          },
          "loginForm": {
            "$ref": "#/components/schemas/BrokerLoginForm"
          },
          "supportsOAuthLogin": {
            "description": "If true, the user can login at the broker via OAuth (this involves browser redirects). Use `prepareOAuthRedirect` to obtain a URL to redirect to.",
            "type": "boolean"
          }
        },
        "required": ["features", "images", "displayName", "envLabel", "envs", "brokerName"],
        "type": "object"
      },
      "BrokerName": {
        "type": "string"
      },
      "CancelOrderChallengeParams": {
        "properties": {
          "authMethod": {
            "type": "string"
          }
        },
        "required": ["authMethod"],
        "type": "object"
      },
      "CancelOrderChallengeResponse": {
        "additionalProperties": false,
        "allOf": [
          {
            "$ref": "#/components/schemas/CancelOrderParams"
          },
          {
            "$ref": "#/components/schemas/CancelOrderChallengeResponseSpecifics"
          }
        ],
        "required": ["mode", "challengeResponse"],
        "type": "object"
      },
      "CancelOrderChallengeResponseSpecifics": {
        "properties": {
          "authMethod": {
            "type": "string"
          },
          "challengeId": {
            "type": "string"
          },
          "challengeResponse": {
            "type": "string"
          },
          "reportingTag": {
            "description": "An optional client-defined tag which will appear in order reports. Note that the number of tags is limited per client and\nif you use more tags, they will not be recorded.",
            "type": "string"
          }
        }
      },
      "CancelOrderDecoupled": {
        "additionalProperties": false,
        "allOf": [
          {
            "$ref": "#/components/schemas/CancelOrderParams"
          },
          {
            "$ref": "#/components/schemas/CancelOrderDecoupledSpecifics"
          }
        ],
        "required": ["mode"],
        "type": "object"
      },
      "CancelOrderDecoupledSpecifics": {
        "properties": {
          "authMethod": {
            "type": "string"
          },
          "reportingTag": {
            "description": "An optional client-defined tag which will appear in order reports. Note that the number of tags is limited per client and\nif you use more tags, they will not be recorded.",
            "type": "string"
          }
        }
      },
      "CancelOrderParams": {
        "discriminator": {
          "mapping": {
            "challengeResponse": "#/components/schemas/CancelOrderChallengeResponse",
            "decoupled": "#/components/schemas/CancelOrderDecoupled",
            "sessionTan": "#/components/schemas/CreateModeSessionTan"
          },
          "propertyName": "mode"
        },
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CancelOrderParamsMode"
          }
        },
        "required": ["mode"],
        "type": "object"
      },
      "CancelOrderParamsMode": {
        "enum": ["sessionTan", "challengeResponse", "decoupled"],
        "nullable": false,
        "type": "string"
      },
      "CancelOrderResponse": {
        "properties": {
          "decoupledOperationId": {
            "description": "If a decoupled method is used to cancel the order, the cancellation process can be observed through the\n`decoupledOperationId`.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "CashAccount": {
        "properties": {
          "currency": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "displayName": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "isHiddenDefaultAccount": {
            "type": "boolean"
          }
        },
        "required": ["currency", "isHiddenDefaultAccount", "displayName", "id"],
        "type": "object"
      },
      "CashAccountQuotes": {
        "properties": {
          "balance": {
            "$ref": "#/components/schemas/Amount"
          },
          "buyingPower": {
            "$ref": "#/components/schemas/Amount"
          },
          "hideInOverviews": {
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "CashAccountQuotesById": {
        "additionalProperties": {
          "$ref": "#/components/schemas/CashAccountQuotes"
        },
        "description": "Quotes each cash account, mapped by the account's id.",
        "properties": {},
        "type": "object"
      },
      "CashQuotation": {
        "description": "For some exchanges, this can be added to an order:\n\n- `K` Kassa\n- `O` Only Opening Auction\n- `C` Only Closing Auction",
        "enum": ["O", "K", "C"],
        "type": "string"
      },
      "Challenge": {
        "properties": {
          "challengeExplanation": {
            "description": "If the challenge needs further explanation, this may contain additional information to display to the user.",
            "type": "string"
          },
          "challengeId": {
            "type": "string"
          },
          "challengePrompt": {
            "type": "string"
          },
          "challengePromptType": {
            "enum": ["text", "base64png"],
            "type": "string"
          }
        },
        "required": ["challengePrompt", "challengePromptType", "challengeId"],
        "type": "object"
      },
      "ChangeOrderChallengeParams": {
        "properties": {
          "authMethod": {
            "type": "string"
          },
          "changes": {
            "$ref": "#/components/schemas/OrderChanges"
          }
        },
        "required": ["changes", "authMethod"],
        "type": "object"
      },
      "ChangeOrderParams": {
        "properties": {
          "authMethod": {
            "type": "string"
          },
          "challengeId": {
            "type": "string"
          },
          "challengeResponse": {
            "type": "string"
          },
          "changes": {
            "$ref": "#/components/schemas/OrderChanges"
          },
          "reportingTag": {
            "description": "An optional client-defined tag which will appear in order reports. Note that the number of tags is limited per client and\nif you use more tags, they will not be recorded.",
            "type": "string"
          }
        },
        "required": ["changes"],
        "type": "object"
      },
      "ChangeOrderResponse": {
        "properties": {
          "decoupledOperationId": {
            "description": "If a decoupled method is used to change the order, the cancellation process can be observed through the\n`decoupledOperationId`.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ClientConfig": {
        "description": "The client configuration as it appears in API endpoints.",
        "properties": {
          "allowRequestsWithoutOrigin": {
            "type": "boolean"
          },
          "allowedOrigins": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "allowedOriginsRegularExpressions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "brokerEnvFilter": {
            "$ref": "#/components/schemas/BrokerEnvFilterMap"
          },
          "cognitoClientIds": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "cryptoTradingAllowed": {
            "description": "If this is true, crypto trading is allowed for this client. If this is true, clients must send\nsome requests to the crypto trading service (for crypto orders) which is controlled by the flag `tradingViaCryptoService`.",
            "type": "boolean"
          },
          "enabled": {
            "type": "boolean"
          },
          "guestUserInactivityTimeoutSeconds": {
            "format": "int32",
            "type": "integer"
          },
          "guestUserLifetime": {
            "$ref": "#/components/schemas/GuestUserLifetime",
            "description": "How long guest users of this client may be used. Note that the actual lifetime is calculated upon\ncreation of the user. We prefer expirations during nighttimes and/or weekends, so that users\nare not disturbed during their work.\n\nThe default value is `ONE_DAY`, which usually means that the user will expire during the next night.\n\nNote that the user may be expired way earlier if a `guestUserInactivityTimeoutSeconds` is defined."
          },
          "hideOfflinePortfolios": {
            "description": "If true, portfolios that have no active session usable by the current user token will\nbe filtered from /portfolio/ endpoints. This is useful for applications that do not\nwant to offer viewing data that is not from the currently logged in broker sessions.\n\nDefault is false.",
            "type": "boolean"
          },
          "legalEntityName": {
            "type": "string"
          },
          "maintenanceStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MaintenanceStatus"
              }
            ],
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "oAuthLoginForm": {
            "$ref": "#/components/schemas/OAuthLoginFormConfig"
          },
          "oAuthReturnToRegularExpressions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "oAuthReturnToUrls": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "page": {},
          "readonly": {
            "description": "If true, users of this client cannot create or change trades.",
            "type": "boolean"
          },
          "reportingFlags": {
            "description": "These flags are used in supporting the reporting logic",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tradingSessionInactivityTimeoutSeconds": {
            "format": "int32",
            "nullable": true,
            "type": "integer"
          },
          "tradingSessionLifetime": {
            "$ref": "#/components/schemas/TradingSessionLifetime",
            "description": "How long trading sessions of this client may be used. Note that the actual lifetime is calculated upon\ncreation of the trading_sessions. We prefer expirations during nighttimes and/or weekends, so that users\nare not disturbed during their work.\n\nThe default value is undefined, which means the trading sessions live as long as the owning user.\n\nThe value `ONE_DAY` usually means that the user will expire during the \"next night\".\nThe value `ONE_WEEK` usually means that the user will expire the next weekend.\n\nNote that the trading session may be expired earlier if a `tradingSessionInactivityTimeoutSeconds` is defined.\nThe combination of `guestUserInactivityTimeoutSeconds` together with an undefined lifetime\nfor keeping the trading session as long as the user exists, while the user interacts with the application frequently enough."
          }
        },
        "required": [
          "page",
          "enabled",
          "oAuthReturnToRegularExpressions",
          "oAuthReturnToUrls",
          "cognitoClientIds",
          "brokerEnvFilter",
          "allowRequestsWithoutOrigin",
          "allowedOrigins",
          "legalEntityName",
          "name"
        ],
        "type": "object"
      },
      "ClientConfigUpdate": {
        "description": "A client configuration *update* (i.e. fields that are not modified can be left out).",
        "properties": {
          "allowRequestsWithoutOrigin": {
            "type": "boolean"
          },
          "allowedOrigins": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "allowedOriginsRegularExpressions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "brokerClientIds": {
            "$ref": "#/components/schemas/BrokerClientCfg"
          },
          "brokerEnvFilter": {
            "$ref": "#/components/schemas/BrokerEnvFilterMap"
          },
          "clientSecrets": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "cognitoClientIds": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "cryptoTradingAllowed": {
            "description": "If this is true, crypto trading is allowed for this client.",
            "type": "boolean"
          },
          "enabled": {
            "type": "boolean"
          },
          "guestUserInactivityTimeoutSeconds": {
            "format": "int32",
            "nullable": true,
            "type": "integer"
          },
          "guestUserLifetime": {
            "$ref": "#/components/schemas/GuestUserLifetime",
            "description": "How long guest users of this client may be used. Note that the actual lifetime is calculated upon\ncreation of the user. We prefer expirations during nighttimes and/or weekends, so that users\nare not disturbed during their work.\n\nThe default value is `ONE_DAY`, which usually means that the user will expire during the next night.\n\nNote that the user may be expired way earlier if a `guestUserInactivityTimeoutSeconds` is defined."
          },
          "hideOfflinePortfolios": {
            "description": "If true, portfolios that have no active session usable by the current user token will\nbe filtered from /portfolio/ endpoints. This is useful for applications that do not\nwant to offer viewing data that is not from the currently logged in broker sessions.\n\nDefault is false.",
            "type": "boolean"
          },
          "legalEntityName": {
            "type": "string"
          },
          "maintenanceStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MaintenanceStatus"
              }
            ],
            "nullable": true
          },
          "managingUserIds": {
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "oAuthLoginForm": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OAuthLoginFormConfig"
              }
            ],
            "nullable": true
          },
          "oAuthReturnToRegularExpressions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "oAuthReturnToUrls": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "optionalClientSecrets": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "page": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PageConfig"
              }
            ],
            "nullable": true
          },
          "rateLimitPointsToConsume": {
            "properties": {
              "guestUser": {
                "format": "double",
                "type": "number"
              },
              "refreshToken": {
                "format": "double",
                "type": "number"
              }
            },
            "type": "object"
          },
          "readonly": {
            "description": "If true, users of this client cannot create or change trades.",
            "type": "boolean"
          },
          "reportingFlags": {
            "description": "These flags are used in supporting the reporting logic.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tradingSessionInactivityTimeoutSeconds": {
            "format": "int32",
            "nullable": true,
            "type": "integer"
          },
          "tradingSessionLifetime": {
            "$ref": "#/components/schemas/TradingSessionLifetime"
          }
        },
        "type": "object"
      },
      "ClientsResponse": {
        "items": {
          "properties": {
            "clientId": {
              "type": "string"
            },
            "config": {
              "$ref": "#/components/schemas/ClientConfig"
            },
            "lastUsedAt": {
              "format": "date-time",
              "nullable": true,
              "type": "string"
            }
          },
          "required": ["config", "lastUsedAt", "clientId"],
          "type": "object"
        },
        "type": "array"
      },
      "CoinbaseClientCfg": {
        "properties": {
          "trackingPrefix": {
            "type": "string"
          }
        },
        "required": ["trackingPrefix"],
        "type": "object"
      },
      "ConfirmOAuthParams": {
        "properties": {
          "code": {
            "type": "string"
          },
          "reportingTag": {
            "nullable": true,
            "type": "string"
          },
          "ticketId": {
            "type": "string"
          }
        },
        "required": ["code", "ticketId"],
        "type": "object"
      },
      "ConfirmOAuthResponse": {
        "properties": {
          "sessionId": {
            "type": "string"
          }
        },
        "required": ["sessionId"],
        "type": "object"
      },
      "CostDetailsLink": {
        "properties": {
          "footerText": {
            "type": "string"
          },
          "linkTitle": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreateAccessTokenParams": {
        "properties": {
          "expiresInDays": {
            "description": "Number of days the token should be valid. Currently, values between 1 and 180 are allowed.",
            "format": "double",
            "type": "number"
          },
          "name": {
            "description": "unique name of the access token",
            "type": "string"
          },
          "permissions": {
            "description": "permissions the access token should have. The following permissions are currently supported:\n\n- `admin-report:all` (gives access to all order reports that the user has management access to)\n- `admin-report:<clientId>` (gives access to order reports for the given client if the user has management access)\n- `admin-urls:all` (allows the user to manage OAuth URLs and origins for all clients that the user has management access to)\n- `admin-urls:<clientId>` (allows the user to manage OAuth URLs and origins for the given client if the user has management access)",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": ["expiresInDays", "permissions", "name"],
        "type": "object"
      },
      "CreateGuestUserResponse": {
        "properties": {
          "access_token": {
            "description": "The bearer token that can be used to access the API.",
            "type": "string"
          },
          "expires_in": {
            "description": "Expiration time of the token in seconds from now.",
            "format": "double",
            "type": "number"
          },
          "idToken": {
            "deprecated": true,
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "refresh_token_expires_in": {
            "description": "If applicable, expiration time of the refresh token in seconds from now.\nNote that this is optional and may not be provided in all cases.",
            "format": "double",
            "type": "number"
          },
          "refresh_token_without_tradingsession": {
            "description": "If applicable for the client configuration, another refresh token which does not have\naccess to the current trading session. It can be used to acquire a new trading session, which will belong to the\nsame user, but have separate active broker sessions.",
            "type": "string"
          },
          "refresh_token_without_tradingsession_expires_in": {
            "format": "double",
            "type": "number"
          },
          "token_type": {
            "description": "The OAuth token_type. Currently always `\"bearer\"`.",
            "type": "string"
          }
        },
        "required": ["token_type", "access_token", "idToken"],
        "type": "object"
      },
      "CreateModeSessionTan": {
        "additionalProperties": false,
        "allOf": [
          {
            "$ref": "#/components/schemas/CancelOrderParams"
          },
          {
            "$ref": "#/components/schemas/CreateModeSessionTanSpecifics"
          }
        ],
        "required": ["mode"],
        "type": "object"
      },
      "CreateModeSessionTanSpecifics": {
        "properties": {
          "reportingTag": {
            "description": "An optional client-defined tag which will appear in order reports. Note that the number of tags is limited per client and\nif you use more tags, they will not be recorded.",
            "type": "string"
          }
        }
      },
      "CreateOrderChallengeParams": {
        "properties": {
          "acceptHintId": {
            "description": "If the order has been rejected with code `MUST_ACCEPT_HINT` before, the order creation can be retried with setting the\n`acceptHintId` accordingly after letting the user accept the hint.",
            "type": "string"
          },
          "authMethod": {
            "type": "string"
          },
          "order": {
            "$ref": "#/components/schemas/OrderCreate"
          }
        },
        "required": ["order"],
        "type": "object"
      },
      "CreateOrderParams": {
        "additionalProperties": false,
        "properties": {
          "acceptHintId": {
            "description": "If the order has been rejected with code `MUST_ACCEPT_HINT` before, the order creation can be retried with setting the\n`acceptHintId` accordingly after letting the user accept the hint.",
            "type": "string"
          },
          "authMethod": {
            "type": "string"
          },
          "challengeId": {
            "type": "string"
          },
          "challengeResponse": {
            "type": "string"
          },
          "order": {
            "$ref": "#/components/schemas/OrderCreate"
          },
          "reportingTag": {
            "description": "An optional client-defined tag which will appear in order reports. Note that the number of tags is limited per client and\nif you use more tags, they will not be recorded.",
            "type": "string"
          }
        },
        "required": ["order"],
        "type": "object"
      },
      "CreateRecoveryPhraseParams": {
        "properties": {
          "name": {
            "description": "A name for the RecoveryPhrase. Must be unique for the user so that they can identify it in the list\nof RecoveryPhrases.",
            "type": "string"
          }
        },
        "required": ["name"],
        "type": "object"
      },
      "CreateRecoveryPhraseResult": {
        "properties": {
          "recoveryPhrase": {
            "type": "string"
          }
        },
        "required": ["recoveryPhrase"],
        "type": "object"
      },
      "CreateTanChallengeParams": {
        "properties": {
          "authMethod": {
            "type": "string"
          }
        },
        "required": ["authMethod"],
        "type": "object"
      },
      "CreateTradeResponse": {
        "properties": {
          "decoupledOperationId": {
            "description": "If a decoupled method is used to create the trade, the creation process can be observed through the\n`decoupledOperationId`. In this case, no `orderId` is returned.",
            "type": "string"
          },
          "orderId": {
            "description": "The id of the created order, if applicable. Some brokers don't return an orderId in all cases, so\nfrontends should be able to just show a generic \"order has been created\" message in this case.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreatedResponseBody": {
        "properties": {
          "accountName": {
            "type": "string"
          },
          "id": {
            "type": "string"
          }
        },
        "required": ["accountName", "id"],
        "type": "object"
      },
      "CurrencyCode": {
        "description": "- ISO code (e.g. EUR for Euro), if it is a monetary amount\n- or 'USDT' if its Tether (https://en.wikipedia.org/wiki/Tether_(cryptocurrency)\n- or 'XXX' if it is pieces\n- or 'PRC' if it is a percentage\n- or 'PRM' if it is permil\n- or 'XXP' if it is points (as for indices)\n- or 'GRAMS' if it is grams (as for precious metals)",
        "type": "string"
      },
      "DateString": {
        "description": "Date in the format YYYY-MM-DD for validityType: 'GTD'\nDate in the format Date ISO string YYYY-MM-DDThh:mm:ss.fffZ for validityType: 'GTDT'",
        "type": "string"
      },
      "DecoupledOperationState": {
        "enum": [
          "AUTHORIZATION_ABORTED",
          "AUTHORIZATION_INITIAL",
          "AUTHORIZATION_USER_ACCEPTED",
          "AUTHORIZATION_USER_CANCELED"
        ],
        "type": "string"
      },
      "DecoupledOperationStatus": {
        "properties": {
          "createdOrderId": {
            "description": "If:\n- the decoupled operation is an order creation\n- *AND* it is in the state `AUTHORIZATION_USER_ACCEPTED`\n- *AND* the broker supports retrieving this information\n\nThis is the id of the created order. Note that depending on the broker, it is possible\n(as with non-decoupled order creations as well), that the broker does not return this id, but\ninstead will add the order to the order book asynchronously. In this case it is not possible to directly\nshow an order receipt, but just a message (e.g. \"Order has been created successfully - check order list for updates\").",
            "type": "string"
          },
          "isCancellable": {
            "description": "If this is `true`, clients may show a \"cancel\" button which triggers the `CancelDecoupledOperation` endpoint.\nSome brokers do not offer cancellation - in that case, do not call the endpoint.",
            "type": "boolean"
          },
          "state": {
            "$ref": "#/components/schemas/DecoupledOperationState"
          },
          "text": {
            "type": "string"
          }
        },
        "required": ["state"],
        "type": "object"
      },
      "DefaultOrderValidityByOrderModel": {
        "additionalProperties": false,
        "properties": {
          "fraction": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "limit": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "market": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "ocoStopLimit": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "ocoStopMarket": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "quote": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "savingsPlan": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "stopLimit": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "stopMarket": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "trailingStopLimit": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "trailingStopMarket": {
            "$ref": "#/components/schemas/OrderValidity"
          },
          "unknown": {
            "$ref": "#/components/schemas/OrderValidity"
          }
        },
        "type": "object"
      },
      "DemoAccount": {
        "properties": {
          "accountId": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "settings": {
            "$ref": "#/components/schemas/DemoAccountSettings"
          }
        },
        "required": ["settings", "accountName", "accountId"],
        "type": "object"
      },
      "DemoAccountSettings": {
        "properties": {
          "authMethodStyle": {
            "description": "Set an `authMethodStyle` to test different auth method behaviors. The following values are currently supported:\n- `default`: the broker will have various methods with different flows\n- `lazy`: the demo account reveals the complete list of auth methods only after the first session TAN challenge request. This also sets `allOperationsRequireSessionTan` to `true` for the account.\n- `one-decoupled`: the account will have *one auth method* with flow `DECOUPLED` (also sets `allOperationsRequireSessionTan=true`)",
            "type": "string"
          },
          "isSinglePortfolio": {
            "description": "Set this to `true` to create a single depot instead of the default two",
            "type": "boolean"
          },
          "lazyAuthMethods": {
            "deprecated": true,
            "description": "Set this to `true` to have the demo account reveal the complete list of auth methods only after\nthe first session TAN challenge request.\n\nThis also sets `allOperationsRequireSessionTan` to `true` for the account.",
            "type": "boolean"
          },
          "seedOrders": {
            "description": "If this is `true`, the first portfolio in the new account will be seeded with an old cancelled order. This can\nbe used to test whether the frontend appropriately reloads orders when the sync is completed over time.\n\nNote that the behavior is not yet specified here and may be refined in the future.",
            "type": "boolean"
          },
          "sessionTanCannotBeEnded": {
            "description": "Set this to `true` to disallow ending session TANs.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "DemoAccountsResponse": {
        "properties": {
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/DemoAccount"
            },
            "type": "array"
          }
        },
        "required": ["accounts"],
        "type": "object"
      },
      "Direction": {
        "enum": ["buy", "sell"],
        "type": "string"
      },
      "EnableSessionTanParams": {
        "discriminator": {
          "mapping": {
            "challengeResponse": "#/components/schemas/EnableSessionTanParamsChallengeResponse",
            "decoupled": "#/components/schemas/EnableSessionTanParamsDecoupled",
            "tan": "#/components/schemas/EnableSessionTanParamsTan"
          },
          "propertyName": "kind"
        },
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/EnableSessionTanParamsKind"
          }
        },
        "required": ["kind"],
        "type": "object"
      },
      "EnableSessionTanParamsChallengeResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/EnableSessionTanParams"
          },
          {
            "$ref": "#/components/schemas/EnableSessionTanParamsChallengeResponseSpecifics"
          }
        ],
        "required": ["challengeResponse", "challengeId", "authMethod", "kind"],
        "type": "object"
      },
      "EnableSessionTanParamsChallengeResponseSpecifics": {
        "properties": {
          "authMethod": {
            "type": "string"
          },
          "challengeId": {
            "type": "string"
          },
          "challengeResponse": {
            "type": "string"
          }
        }
      },
      "EnableSessionTanParamsDecoupled": {
        "allOf": [
          {
            "$ref": "#/components/schemas/EnableSessionTanParams"
          },
          {
            "$ref": "#/components/schemas/EnableSessionTanParamsDecoupledSpecifics"
          }
        ],
        "required": ["authMethod", "kind"],
        "type": "object"
      },
      "EnableSessionTanParamsDecoupledSpecifics": {
        "properties": {
          "authMethod": {
            "type": "string"
          }
        }
      },
      "EnableSessionTanParamsKind": {
        "enum": ["challengeResponse", "decoupled", "tan"],
        "nullable": false,
        "type": "string"
      },
      "EnableSessionTanParamsTan": {
        "allOf": [
          {
            "$ref": "#/components/schemas/EnableSessionTanParams"
          },
          {
            "$ref": "#/components/schemas/EnableSessionTanParamsTanSpecifics"
          }
        ],
        "required": ["tan", "authMethod", "kind"],
        "type": "object"
      },
      "EnableSessionTanParamsTanSpecifics": {
        "properties": {
          "authMethod": {
            "type": "string"
          },
          "tan": {
            "type": "string"
          }
        }
      },
      "EnableSessionTanResponse": {
        "anyOf": [
          {
            "properties": {
              "decoupledOperationId": {
                "type": "string"
              }
            },
            "type": "object"
          },
          {
            "$ref": "#/components/schemas/OkResponseBody"
          }
        ]
      },
      "EndSessionTanResponse": {
        "properties": {
          "message": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ErrorResponse": {
        "properties": {
          "code": {
            "description": "The error code.\nCurrently the following codes are implemented:\n 'TRADING_ERROR', 'AUTH', 'RATE_LIMITED', 'VALIDATION_FAILED', 'MUST_ACCEPT_HINT', 'NO_SESSION_AVAILABLE_FOR_PORTFOLIO',\n 'SECURITY_NOT_FOUND', 'SECURITY_NOT_TRADABLE_AT_EXCHANGE', 'ORDER_REJECTED', 'INTERNAL_SERVER_ERROR', 'MAINTENANCE',\n 'INTERNAL_SERVER_ERROR_BROKER_API' | 'NOT_FOUND' | 'QUOTE_REJECTED_RETRYABLE'",
            "type": "string"
          },
          "hint": {
            "$ref": "#/components/schemas/Hint",
            "description": "Only for error code MUST_ACCEPT_HINT:\nWhen users have to accept hints (code `MUST_ACCEPT_HINT`, this describes the hint to accept)."
          },
          "maintenanceStatus": {
            "$ref": "#/components/schemas/MaintenanceStatus",
            "description": "For code MAINTENANCE: details about the ongoing maintenance."
          },
          "msg": {
            "description": "The human-readable error message. If available, translated to the users's language.\nThis can always be displayed in frontends (if no specific error code handling is available).",
            "type": "string"
          },
          "msgBrokerName": {
            "$ref": "#/components/schemas/BrokerName",
            "description": "If the message was passed-through from the broker directly, this contains the brokerName. This\ncan be used to add the broker name / logo or a link to the error message in frontends."
          },
          "validationDetails": {
            "$ref": "#/components/schemas/ValidationDetails",
            "description": "For validation errors (error code `VALIDATION_FAILED`), a map with the affected field as key and ValidationDetail\nas value."
          }
        },
        "required": ["msg", "code"],
        "type": "object"
      },
      "EstimateChangeOrderCostsParams": {
        "properties": {
          "changes": {
            "$ref": "#/components/schemas/OrderChanges"
          }
        },
        "required": ["changes"],
        "type": "object"
      },
      "Exchange": {
        "additionalProperties": false,
        "description": "An `Exchange` describes the order possibilities for a security at one exchange.",
        "properties": {
          "allowsIfDoneLimit": {
            "description": "If this is true, limit buy orders may have the additional \"ifDoneLimit\" set.",
            "type": "boolean"
          },
          "allowsQuoteModeLimit": {
            "description": "If true, quote orders can be created with quoteMode=limit and quoteOrderOpts.quoteLimit set to a limit. This allows brokers to execute the\nquote order at a different price instead of rejecting the order when the price has changed.",
            "type": "boolean"
          },
          "brokerizeExchangeId": {
            "description": "If the exchange can be mapped to the brokerize exchange list, this contains the id of the corresponding entry. Note that this is optional\nand may be missing if the exchange cannot be mapped.",
            "format": "int32",
            "type": "integer"
          },
          "cashAccountIds": {
            "description": "If defined, the cashAccounts that can be used with this exchange. The list should be presented to the user, so that they can\nselect which account to order with. Usually this is just the list of cash accounts, filtered by currency. However, some\nbrokers may allow to trade with cash accounts in a different currency than the exchange's currency, so this provided list should\nbe used.\n\nIf not defined, all cash accounts assigned to the portfolio can be used (if there is only one or none, the list should not be shown).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "currencyIso": {
            "description": "Quotes for the instrument at this exchange are in this currency. This affects fields like limit, stop etc.",
            "type": "string"
          },
          "defaultValidityByOrderModel": {
            "$ref": "#/components/schemas/DefaultOrderValidityByOrderModel",
            "description": "If present, contains default values for validity based on the orderModel."
          },
          "hideOrderModel": {
            "deprecated": true,
            "description": "only one orderModel is available and it should not be displayed to the user. This is currently the case for buying funds at some\nexchanges, where there is actually not a real order in the background, so the user should just see buy & sell buttons.\n\nDo not use this field anymore! It actually makes UIs unclear and currently is always `false`.",
            "type": "boolean"
          },
          "id": {
            "description": "The id of the exchange, as defined by the *broker*. This is to be used as the `brokerExchangeId` in quote and trade requests.",
            "type": "string"
          },
          "label": {
            "description": "The label of the exchange, as defined by the *broker*.",
            "type": "string"
          },
          "legalMessagesToConfirmByOrderModel": {
            "$ref": "#/components/schemas/StringMapByOrderModel",
            "description": "Legal messages that have to be confirmed by the user actively before creating an order, by orderModel.\nThe legal messages may contain line-breaks (\"\\n\"). Those should be converted, for example to <br> tags if\ndisplayed in HTML views."
          },
          "orderModelsBuy": {
            "description": "The orderModels that are available for order direction `buy`. If this is empty, buying is not allowed on this exchange.",
            "items": {
              "$ref": "#/components/schemas/OrderModel"
            },
            "type": "array"
          },
          "orderModelsSell": {
            "description": "The orderModels that are available for order direction `sell`. If this is empty, selling is not allowed on this exchange.",
            "items": {
              "$ref": "#/components/schemas/OrderModel"
            },
            "type": "array"
          },
          "securityQuotesToken": {
            "description": "If set, this token can be used to retrieve quotes for the security at this exchange using the corresponding API endpoints (`GetSecurityQuotesMeta` and `GetSecurityQuotes`).",
            "type": "string"
          },
          "takeProfitStopLoss": {
            "$ref": "#/components/schemas/TakeProfitStopLossCapabilites",
            "description": "If this is set, it is possible to specifiy takeProfit and/or stopLoss for orders. The value describes the capabilities for those\nvalues in detail."
          },
          "validityTypesByOrderModel": {
            "$ref": "#/components/schemas/OrderValidityTypeByOrderModel",
            "description": "For each supported orderModel, define which kinds of validities are selectable by the user."
          }
        },
        "required": ["id", "label", "orderModelsSell", "orderModelsBuy", "validityTypesByOrderModel", "currencyIso"],
        "type": "object"
      },
      "ExchangeMeta": {
        "properties": {
          "id": {
            "format": "int32",
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "required": ["name", "id"],
        "type": "object"
      },
      "ExchangesResponse": {
        "properties": {
          "exchanges": {
            "items": {
              "$ref": "#/components/schemas/ExchangeMeta"
            },
            "type": "array"
          }
        },
        "required": ["exchanges"],
        "type": "object"
      },
      "GenericTable": {
        "properties": {
          "detailsLink": {
            "$ref": "#/components/schemas/CostDetailsLink"
          },
          "footerHtml": {
            "type": "string"
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/GenericTableRow"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "GenericTableRow": {
        "discriminator": {
          "mapping": {
            "entry": "#/components/schemas/GenericTableRowEntry",
            "subheading": "#/components/schemas/GenericTableRowSubheading",
            "text": "#/components/schemas/GenericTableRowText"
          },
          "propertyName": "type"
        },
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GenericTableRowType"
          }
        },
        "required": ["type"],
        "type": "object"
      },
      "GenericTableRowEntry": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRow"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowEntrySpecifics"
          }
        ],
        "required": ["caption", "type"],
        "type": "object"
      },
      "GenericTableRowEntrySpecifics": {
        "properties": {
          "caption": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "isImportant": {
            "type": "boolean"
          },
          "value": {
            "$ref": "#/components/schemas/GenericTableRowValue"
          }
        }
      },
      "GenericTableRowSubheading": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRow"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowSubheadingSpecifics"
          }
        ],
        "required": ["subheading", "type"],
        "type": "object"
      },
      "GenericTableRowSubheadingSpecifics": {
        "properties": {
          "subheading": {
            "type": "string"
          }
        }
      },
      "GenericTableRowText": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRow"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowTextSpecifics"
          }
        ],
        "required": ["text", "type"],
        "type": "object"
      },
      "GenericTableRowTextSpecifics": {
        "properties": {
          "text": {
            "type": "string"
          }
        }
      },
      "GenericTableRowType": {
        "enum": ["subheading", "text", "entry"],
        "nullable": false,
        "type": "string"
      },
      "GenericTableRowValue": {
        "discriminator": {
          "mapping": {
            "amount": "#/components/schemas/GenericTableRowValueAmount",
            "datetime": "#/components/schemas/GenericTableRowValueDatetime",
            "link": "#/components/schemas/GenericTableRowValueLink",
            "text": "#/components/schemas/GenericTableRowValueText"
          },
          "propertyName": "type"
        },
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GenericTableRowValueType"
          }
        },
        "required": ["type"],
        "type": "object"
      },
      "GenericTableRowValueAmount": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRowValue"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowValueAmountSpecifics"
          }
        ],
        "required": ["value", "type"],
        "type": "object"
      },
      "GenericTableRowValueAmountSpecifics": {
        "properties": {
          "value": {
            "$ref": "#/components/schemas/Amount"
          }
        }
      },
      "GenericTableRowValueDatetime": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRowValue"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowValueDatetimeSpecifics"
          }
        ],
        "required": ["value", "type"],
        "type": "object"
      },
      "GenericTableRowValueDatetimeSpecifics": {
        "properties": {
          "value": {
            "description": "*Milliseconds* since *the epoch*.",
            "format": "int64",
            "type": "integer"
          }
        }
      },
      "GenericTableRowValueLink": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRowValue"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowValueLinkSpecifics"
          }
        ],
        "required": ["value", "type"],
        "type": "object"
      },
      "GenericTableRowValueLinkPortfolio": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRowValueLinkValue"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowValueLinkPortfolioSpecifics"
          }
        ],
        "required": ["text", "portfolioId", "type"],
        "type": "object"
      },
      "GenericTableRowValueLinkPortfolioSpecifics": {
        "properties": {
          "portfolioId": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      },
      "GenericTableRowValueLinkSpecifics": {
        "properties": {
          "value": {
            "$ref": "#/components/schemas/GenericTableRowValueLinkValue"
          }
        }
      },
      "GenericTableRowValueLinkUrl": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRowValueLinkValue"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowValueLinkUrlSpecifics"
          }
        ],
        "required": ["url", "text", "type"],
        "type": "object"
      },
      "GenericTableRowValueLinkUrlSpecifics": {
        "properties": {
          "text": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "GenericTableRowValueLinkValue": {
        "discriminator": {
          "mapping": {
            "portfolio": "#/components/schemas/GenericTableRowValueLinkPortfolio",
            "url": "#/components/schemas/GenericTableRowValueLinkUrl"
          },
          "propertyName": "type"
        },
        "properties": {
          "type": {
            "$ref": "#/components/schemas/GenericTableRowValueLinkValueType"
          }
        },
        "required": ["type"],
        "type": "object"
      },
      "GenericTableRowValueLinkValueType": {
        "enum": ["portfolio", "url"],
        "nullable": false,
        "type": "string"
      },
      "GenericTableRowValueText": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GenericTableRowValue"
          },
          {
            "$ref": "#/components/schemas/GenericTableRowValueTextSpecifics"
          }
        ],
        "required": ["value", "type"],
        "type": "object"
      },
      "GenericTableRowValueTextSpecifics": {
        "properties": {
          "value": {
            "type": "string"
          }
        }
      },
      "GenericTableRowValueType": {
        "enum": ["text", "amount", "datetime", "link"],
        "nullable": false,
        "type": "string"
      },
      "GetAccessTokensResponse": {
        "properties": {
          "tokens": {
            "items": {
              "$ref": "#/components/schemas/AccessTokenItem"
            },
            "type": "array"
          }
        },
        "required": ["tokens"],
        "type": "object"
      },
      "GetActiveTradeDraftsResponse": {
        "properties": {
          "totalCount": {
            "format": "int32",
            "type": "integer"
          },
          "tradeDrafts": {
            "items": {
              "$ref": "#/components/schemas/TradeDraft"
            },
            "type": "array"
          }
        },
        "required": ["totalCount", "tradeDrafts"],
        "type": "object"
      },
      "GetAuthInfoResponse": {
        "properties": {
          "authInfo": {
            "$ref": "#/components/schemas/AuthInfo"
          }
        },
        "required": ["authInfo"],
        "type": "object"
      },
      "GetBrokersResponse": {
        "properties": {
          "brokers": {
            "items": {
              "$ref": "#/components/schemas/BrokerMeta"
            },
            "type": "array"
          }
        },
        "required": ["brokers"],
        "type": "object"
      },
      "GetCostEstimationParams": {
        "properties": {
          "order": {
            "$ref": "#/components/schemas/OrderCreate"
          }
        },
        "required": ["order"],
        "type": "object"
      },
      "GetOrderResponse": {
        "properties": {
          "order": {
            "$ref": "#/components/schemas/Order"
          }
        },
        "required": ["order"],
        "type": "object"
      },
      "GetPortfolioCalendarResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PortfolioCalendarDateRange"
            },
            "type": "array"
          }
        },
        "required": ["data"],
        "type": "object"
      },
      "GetPortfolioOrdersResponse": {
        "properties": {
          "orders": {
            "items": {
              "$ref": "#/components/schemas/Order"
            },
            "type": "array"
          },
          "totalCount": {
            "format": "int32",
            "type": "integer"
          }
        },
        "required": ["totalCount", "orders"],
        "type": "object"
      },
      "GetPortfolioPositionsResponse": {
        "properties": {
          "positions": {
            "items": {
              "$ref": "#/components/schemas/Position"
            },
            "type": "array"
          }
        },
        "required": ["positions"],
        "type": "object"
      },
      "GetPortfolioQuotesResponse": {
        "properties": {
          "cashAccounts": {
            "$ref": "#/components/schemas/CashAccountQuotesById"
          },
          "lastSync": {
            "format": "date-time",
            "type": "string"
          },
          "quotes": {
            "$ref": "#/components/schemas/PortfolioQuotes"
          }
        },
        "type": "object"
      },
      "GetPortfolioTradeStatisticsResponse": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/TradeStatisticsItem"
            },
            "type": "array"
          }
        },
        "required": ["data"],
        "type": "object"
      },
      "GetPortfolioTradesResponse": {
        "properties": {
          "totalCount": {
            "format": "int32",
            "type": "integer"
          },
          "trades": {
            "items": {
              "$ref": "#/components/schemas/SummarizedTrade"
            },
            "type": "array"
          }
        },
        "required": ["totalCount", "trades"],
        "type": "object"
      },
      "GetQuoteParams": {
        "properties": {
          "brokerExchangeId": {
            "type": "string"
          },
          "brokerSecurityId": {
            "description": "The `brokerSecurityId`, as provided by `PreparedTrade`.\n\nThis is only optional temporarily and will be required in the future. So make sure to provide this.",
            "type": "string"
          },
          "cashAccountId": {
            "description": "If this makes a difference for the offer (e.g. bitpanda!), provide a cashAccountId",
            "type": "string"
          },
          "direction": {
            "$ref": "#/components/schemas/Direction"
          },
          "isin": {
            "description": "This will be deprecated and replaced by `brokerSecurityId` in the long term.\nMake sure to fill `brokerSecurityId`.",
            "type": "string"
          },
          "sellPositionId": {
            "description": "If a list of sellPositions has been provided in `PrepareTrade`, this must contain the selected position id to sell from",
            "type": "string"
          },
          "size": {
            "format": "double",
            "type": "number"
          },
          "sizeUnit": {
            "type": "string"
          }
        },
        "required": ["brokerExchangeId", "size", "direction", "isin"],
        "type": "object"
      },
      "GetQuoteResponse": {
        "additionalProperties": false,
        "properties": {
          "costEstimation": {
            "$ref": "#/components/schemas/OrderCostEstimation",
            "description": "If the broker returns a cost estimation together with the quote, it will also be part of the brokerize quote."
          },
          "costEstimationToken": {
            "deprecated": true,
            "description": "If the broker does not return a cost estimation summary, but it is possible to retrieve a cost estimation summary using the token.",
            "type": "string"
          },
          "direction": {
            "$ref": "#/components/schemas/Direction"
          },
          "expiration": {
            "$ref": "#/components/schemas/QuoteExpiration",
            "description": "If provided, the quote's expiration time (may be visualized as some kind of countdown). The quote is expected to not be\navailable any more after the expiration (though it may still be - users *can* try)."
          },
          "isin": {
            "type": "string"
          },
          "quotation": {
            "$ref": "#/components/schemas/Amount",
            "description": "The quote that can be used for trading."
          },
          "quoteId": {
            "description": "Some token that identifies this exact quote response (referenced in the following trade requests).",
            "type": "string"
          },
          "size": {
            "description": "If provided, the maximum available size that can be traded at the given price.",
            "format": "double",
            "type": "number"
          },
          "sourceName": {
            "description": "The human-readable name of the quote's source (e.g. the name of a stock exchange).",
            "type": "string"
          },
          "totalAmount": {
            "$ref": "#/components/schemas/Amount",
            "description": "The total amount of the quote trade, if provided by the broker."
          }
        },
        "required": ["quoteId", "isin", "direction", "quotation"],
        "type": "object"
      },
      "GetRecoveryPhrasesResponse": {
        "properties": {
          "recoveryPhrases": {
            "items": {
              "$ref": "#/components/schemas/RecoveryPhraseItem"
            },
            "type": "array"
          }
        },
        "required": ["recoveryPhrases"],
        "type": "object"
      },
      "GetUserResponse": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "isGuest": {
            "type": "boolean"
          },
          "userId": {
            "type": "string"
          }
        },
        "required": ["createdAt", "isGuest", "userId"],
        "type": "object"
      },
      "GuestUserLifetime": {
        "enum": ["ONE_DAY", "ONE_WEEK", "INFINITE"],
        "type": "string"
      },
      "Hint": {
        "properties": {
          "id": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        },
        "required": ["text", "id"],
        "type": "object"
      },
      "LegalTermConfirmItem": {
        "properties": {
          "html": {
            "type": "string"
          },
          "id": {
            "type": "string"
          }
        },
        "required": ["html", "id"],
        "type": "object"
      },
      "LegalTermsResponse": {
        "properties": {
          "checkboxesHtml": {
            "deprecated": true,
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "confirmItems": {
            "items": {
              "$ref": "#/components/schemas/LegalTermConfirmItem"
            },
            "type": "array"
          },
          "disclaimerHtml": {
            "type": "string"
          }
        },
        "required": ["confirmItems", "checkboxesHtml", "disclaimerHtml"],
        "type": "object"
      },
      "LoginResponse": {
        "discriminator": {
          "mapping": {
            "challenge": "#/components/schemas/LoginResponseChallenge",
            "ready": "#/components/schemas/LoginResponseReady"
          },
          "propertyName": "state"
        },
        "properties": {
          "state": {
            "$ref": "#/components/schemas/LoginResponseState"
          }
        },
        "required": ["state"],
        "type": "object"
      },
      "LoginResponseChallenge": {
        "allOf": [
          {
            "$ref": "#/components/schemas/LoginResponse"
          },
          {
            "$ref": "#/components/schemas/LoginResponseChallengeSpecifics"
          }
        ],
        "required": ["challenge", "state"],
        "type": "object"
      },
      "LoginResponseChallengeSpecifics": {
        "properties": {
          "challenge": {
            "$ref": "#/components/schemas/Challenge"
          }
        }
      },
      "LoginResponseReady": {
        "allOf": [
          {
            "$ref": "#/components/schemas/LoginResponse"
          },
          {
            "$ref": "#/components/schemas/LoginResponseReadySpecifics"
          }
        ],
        "required": ["sessionId", "state"],
        "type": "object"
      },
      "LoginResponseReadySpecifics": {
        "properties": {
          "sessionId": {
            "type": "string"
          }
        }
      },
      "LoginResponseState": {
        "enum": ["ready", "challenge"],
        "nullable": false,
        "type": "string"
      },
      "LogoutOkResponseBody": {
        "properties": {
          "frontendLogoutUrl": {
            "description": "If this is returned, the logout must be completed in the frontend (e.g. when the broker sets cookies for use in their OAuth flow).",
            "type": "string"
          },
          "msg": {
            "description": "A success message to display to the user.",
            "type": "string"
          }
        },
        "required": ["msg"],
        "type": "object"
      },
      "MaintenanceStatus": {
        "properties": {
          "expectedEnd": {
            "format": "date-time",
            "type": "string"
          },
          "msg": {
            "type": "string"
          }
        },
        "required": ["msg"],
        "type": "object"
      },
      "MonetaryValue": {
        "format": "double",
        "type": "number"
      },
      "OAuthLoginFormConfig": {
        "properties": {
          "appName": {
            "type": "string"
          },
          "logoUrlDark": {
            "type": "string"
          },
          "logoUrlLight": {
            "type": "string"
          },
          "redirectStyle": {
            "enum": ["meta", "js", "link"],
            "type": "string"
          },
          "redirectStyleBitpanda": {
            "enum": ["meta", "js", "link"],
            "type": "string"
          }
        },
        "type": "object"
      },
      "ObtainTokenByRecoveryPhraseParams": {
        "properties": {
          "recoveryPhrase": {
            "type": "string"
          }
        },
        "required": ["recoveryPhrase"],
        "type": "object"
      },
      "OkResponseBody": {
        "properties": {
          "msg": {
            "type": "string"
          }
        },
        "required": ["msg"],
        "type": "object"
      },
      "Order": {
        "additionalProperties": false,
        "properties": {
          "allowsCancel": {
            "description": "If `true`, the order can be canceled",
            "type": "boolean"
          },
          "allowsChangeLimit": {
            "description": "If true, the limit of the order can be changed.",
            "type": "boolean"
          },
          "allowsChangeOrderModels": {
            "description": "If set, the orderModel may be changed to one of the given orderModels.",
            "items": {
              "$ref": "#/components/schemas/OrderModel"
            },
            "type": "array"
          },
          "allowsChangeSize": {
            "description": "If `true`, the order size can be changed",
            "type": "boolean"
          },
          "allowsChangeStop": {
            "description": "If true, the stop of the order can be changed.",
            "type": "boolean"
          },
          "allowsChangeStopLimit": {
            "description": "If true, the stop limit of the order can be changed.",
            "type": "boolean"
          },
          "allowsChangeStopLoss": {
            "description": "`true` if the `stopLoss` of the order can be changed.",
            "type": "boolean"
          },
          "allowsChangeTakeProfit": {
            "description": "`true` if the `takeProfit` of the order can be changed.",
            "type": "boolean"
          },
          "allowsChangeTrailingDistance": {
            "description": "If true, the trailing distance of the order can be changed.",
            "type": "boolean"
          },
          "allowsChangeValidityTypes": {
            "description": "If set, the validity of the order can be changed to the given types.",
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "bondCurrencyIso": {
            "description": "If the security is a bond, the currency ISO code to show for the size input field.",
            "type": "string"
          },
          "brokerExchangeId": {
            "type": "string"
          },
          "brokerSecurityId": {
            "description": "The `brokerSecurityId` is the broker-specific identifier for the security to trade. It is provided by the `PreparedTrade` endpoint\nand must be used in the order creation process to identify the security.\n\nThis is only optional temporarily and will be required in the future. It will also replace the fields `isin` and `usTicker` for order creations.",
            "type": "string"
          },
          "cancellationDateTime": {
            "description": "For canceled orders: when the order has been canceled.",
            "format": "date-time",
            "type": "string"
          },
          "cancelledSize": {
            "description": "Already cancelled size of the order.",
            "format": "double",
            "type": "number"
          },
          "cashQuotation": {
            "$ref": "#/components/schemas/CashQuotation"
          },
          "changesHaveCostEstimations": {
            "description": "If set and `true`, the endpoint `getChangeOrderCostEstimation` can be used to retrieve cost estimations\nfor order changes.",
            "type": "boolean"
          },
          "createdAt": {
            "description": "Timestamp of the order creation.",
            "format": "date-time",
            "type": "string"
          },
          "currentStop": {
            "$ref": "#/components/schemas/Amount",
            "description": "For trailing stop orders, the current stop value."
          },
          "detailsCanBeEnhanced": {
            "description": "If this is true, it is possible to get more details about the order (usually execution details) by retrieving the order\nusing the `GetOrder` endpoint.",
            "type": "boolean"
          },
          "direction": {
            "$ref": "#/components/schemas/Direction"
          },
          "displayNo": {
            "description": "The order number to use in the interface to display to the user.\nSome brokers do not assign order numbers, so if this is not present, the order should be displayed without a number.",
            "type": "string"
          },
          "exchangeId": {
            "description": "The mapped exchange id, as retrievable from the `/exchanges` endpoint.",
            "format": "int32",
            "type": "integer"
          },
          "exchangeName": {
            "description": "Name of the exchange as provided by the broker.",
            "type": "string"
          },
          "executedAt": {
            "description": "For fully executed orders: the timestamp of the *latest* execution.",
            "format": "date-time",
            "type": "string"
          },
          "executedSize": {
            "description": "Already executed size of the order",
            "format": "double",
            "type": "number"
          },
          "executions": {
            "description": "If there already have been executions of this order, a list of those.",
            "items": {
              "$ref": "#/components/schemas/OrderExecution"
            },
            "type": "array"
          },
          "hasNoOrderReceipt": {
            "deprecated": true,
            "description": "If this is true, it is not possible to show a receipt for this order (this is the case if order data is incomplete in order lists).",
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "ifDoneLimit": {
            "$ref": "#/components/schemas/MonetaryValue"
          },
          "intent": {
            "description": "Whether this order is supposed to open or close a position. If `PreparedTrade.availableOrderIntents` (and/or the\ncorresponding subscription via `availableOrderIntentsToken`) is available, it should be set.\n\nSet it to `close` for orders that are supposed to close an existing position. Note that this is independent\nof the order's direction (e.g. a short position is closed by a buy order).",
            "enum": ["open", "close"],
            "type": "string"
          },
          "isin": {
            "description": "The ISIN of the security to trade, if applicable. Note that at least one of `isin` and `usTicker` must be set.\n\nNote that we will make isin optional in a future version of the API.",
            "type": "string"
          },
          "limit": {
            "$ref": "#/components/schemas/OrderLimitValue",
            "description": "The limit of an order specifies a maximum (direction buy) or minimum (direction sell) value to execute the\norder at.\n\nA limit can be set for orderModel `limit`"
          },
          "limitCurrencyIso": {
            "description": "limit (and stop etc.) currency to use for this order",
            "type": "string"
          },
          "mayObserveCurrentStop": {
            "description": "If true, the current stop value of this order can be observed. In this case, the stop value can be subcribed via WebSocket (TODO - not implemented yet)",
            "type": "boolean"
          },
          "openSize": {
            "description": "Remaining/open size of the order",
            "format": "double",
            "type": "number"
          },
          "orderExtension": {
            "$ref": "#/components/schemas/OrderExtension",
            "description": "(AllOrNone/Immediate or Cancel/Fill or Kill)"
          },
          "orderModel": {
            "$ref": "#/components/schemas/OrderModel"
          },
          "orderStatusIsAwaitingParentOrder": {
            "description": "If this is `true` (for open orders only), this order is currently awaiting the execution of a parent order.",
            "type": "boolean"
          },
          "portfolioId": {
            "type": "string"
          },
          "profitLossAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "If provided by the broker, the absolute profit/loss this order has produced."
          },
          "profitLossRel": {
            "$ref": "#/components/schemas/MonetaryValue",
            "description": "If provided by the broker, the relative profit/loss this order has produced. 1 means +100%"
          },
          "quoteDecimals": {
            "description": "If present, defines how many decimal places should be displayed for quote values.",
            "format": "int32",
            "type": "integer"
          },
          "quoteLimit": {
            "$ref": "#/components/schemas/OrderQuoteLimitValue",
            "description": "If supported by the broker, an optional limit can be added to a quote trade (`orderModel=quote`)."
          },
          "security": {
            "$ref": "#/components/schemas/Security",
            "description": "Security data, as provided by the broker."
          },
          "showAsDisabled": {
            "description": "Order is visible, but it cannot be interacted with (e.g. because it is the discarded part of a combination order).\nIf this is present and `true`, it should be displayed to the user, but visibily disabled.",
            "type": "boolean"
          },
          "size": {
            "description": "How much of the security should be traded. For stocks, this is the number of stocks. For bonds, this is a monetary amount.",
            "format": "double",
            "type": "number"
          },
          "sizeDecimals": {
            "description": "If present, defines how many decimal places should be displayed for size values.",
            "format": "int32",
            "type": "integer"
          },
          "sizeUnit": {
            "description": "The currency in which the order sizes are provided",
            "type": "string"
          },
          "sourceData": {
            "description": "Contains original broker data (in the broker's data format).",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "statusText": {
            "description": "Order status as text (may be broker-specific, only used for displaying it to users).",
            "type": "string"
          },
          "stop": {
            "$ref": "#/components/schemas/OrderStopValue",
            "description": "The stop of an order specifies a usually higher value than the current quote (direction buy) or a usually lower value than the current quote (direction sell).\n\nFor the orderModel `stop`, the order is executed immediately when the stop is reached.\nFor the orderModel `stopLimit`, the order will only be executed with a limit value of `stopLimit` (so for buy orders the price of execution will not be higher than `stopLimit`, for sell it orders it will not be lower than `stopLimit`)."
          },
          "stopLimit": {
            "$ref": "#/components/schemas/OrderStopLimitValue",
            "description": "The stop limit specifies a limit to use *after stop has been reached*. For buy orders, the stopLimit will be usually higher than stop, for sell orders the stopLimit will usually be lower than stop."
          },
          "stopLoss": {
            "$ref": "#/components/schemas/MonetaryValue",
            "description": "This is usually a next order: when the original order is executed (and a position has been created), a next order is created with the stop loss\nas a stop value. Note that the specific behavior depends on how the broker implements this."
          },
          "takeProfit": {
            "$ref": "#/components/schemas/MonetaryValue",
            "description": "This is usually a next order: when the original order is executed (and a position has been created), a next order is created with the take profit\nas limit. Note that the specific behavior depends on how the broker implements this."
          },
          "tradingViaCryptoService": {
            "description": "If this is `true`, trades for this security must be sent to the external crypto trading service. If applicable for your client,\nthe URL of that endpoint will be provided in the admin panel. The requests `CancelOrder` and `ChangeOrder` must then be\ndirected to that endpoint instead.\n\nIf this is `false` or undefined, trades can be sent directly to the brokerize API.",
            "type": "boolean"
          },
          "trailingDistance": {
            "$ref": "#/components/schemas/TrailingDistance",
            "description": "For orderModels `trailingStopMarket` and `trailingStopLimit`: the distance between the security's quote and the\nstop value to calculate."
          },
          "trailingLimitTolerance": {
            "$ref": "#/components/schemas/OrderTrailingLimitToleranceValue",
            "description": "For orderModel `trailingStopLimit`: when the trailing stop has been reached, the tolerance\nvalue is added to (for buy orders) or subtracted from (for sell orders) the stop value to obtain\na limit value. After that, the order can be regarded as a limit order with that limit value."
          },
          "usTicker": {
            "deprecated": true,
            "description": "The US ticker of the security to trade, if applicable. Note that at least one of `isin` and `usTicker` must be set.",
            "type": "string"
          },
          "validity": {
            "$ref": "#/components/schemas/OrderValidity"
          }
        },
        "required": [
          "size",
          "isin",
          "brokerExchangeId",
          "direction",
          "orderModel",
          "portfolioId",
          "id",
          "status",
          "allowsChangeSize",
          "allowsCancel",
          "createdAt",
          "security"
        ],
        "type": "object"
      },
      "OrderChanges": {
        "additionalProperties": false,
        "properties": {
          "limit": {
            "$ref": "#/components/schemas/OrderLimitValue"
          },
          "orderModel": {
            "$ref": "#/components/schemas/OrderModel"
          },
          "size": {
            "format": "double",
            "type": "number"
          },
          "stop": {
            "$ref": "#/components/schemas/OrderStopValue"
          },
          "stopLimit": {
            "$ref": "#/components/schemas/OrderStopLimitValue"
          },
          "stopLoss": {
            "$ref": "#/components/schemas/MonetaryValue"
          },
          "takeProfit": {
            "$ref": "#/components/schemas/MonetaryValue"
          },
          "trailingDistance": {
            "$ref": "#/components/schemas/TrailingDistance"
          },
          "trailingLimitTolerance": {
            "$ref": "#/components/schemas/OrderTrailingLimitToleranceValue"
          },
          "validity": {
            "$ref": "#/components/schemas/OrderValidity"
          }
        },
        "type": "object"
      },
      "OrderCostEstimation": {
        "additionalProperties": false,
        "properties": {
          "costAcceptancePrompt": {
            "description": "If present, users have to accept this message before creating an order.\nIf accepting the costs and performing the order is one click (which is allowed), the create order button label\nmust contain the information that costs are accepted.",
            "type": "string"
          },
          "costDetailsLink": {
            "$ref": "#/components/schemas/CostDetailsLink",
            "description": "If available, a direct link to cost details."
          },
          "detailedTable": {
            "$ref": "#/components/schemas/GenericTable",
            "description": "If present, a detailed tabular representation of the order cost estimation."
          },
          "entryCosts": {
            "$ref": "#/components/schemas/Amount",
            "description": "Entry costs for the order."
          },
          "expectedCounterValue": {
            "$ref": "#/components/schemas/Amount",
            "description": "Expected counter value when order is executed."
          },
          "orderFees": {
            "$ref": "#/components/schemas/Amount",
            "description": "Orderkosten (Summe aus Provision, Handelsplatzentgelt, Courtage)"
          },
          "orderFeesExplanation": {
            "description": "Detailed explanation for order fees",
            "type": "string"
          },
          "totalCosts": {
            "$ref": "#/components/schemas/Amount",
            "deprecated": true,
            "description": "The total amount spent for this order."
          },
          "transactionTax": {
            "$ref": "#/components/schemas/Amount",
            "description": "Financial transaction tax."
          }
        },
        "type": "object"
      },
      "OrderCreate": {
        "additionalProperties": false,
        "properties": {
          "brokerExchangeId": {
            "type": "string"
          },
          "brokerSecurityId": {
            "description": "The `brokerSecurityId` is the broker-specific identifier for the security to trade. It is provided by the `PreparedTrade` endpoint\nand must be used in the order creation process to identify the security.\n\nThis is only optional temporarily and will be required in the future. It will also replace the fields `isin` and `usTicker` for order creations.",
            "type": "string"
          },
          "cashAccountId": {
            "description": "If a list of cash accounts is provided for the portfolio, this should contain the selected account.",
            "type": "string"
          },
          "cashQuotation": {
            "$ref": "#/components/schemas/CashQuotation"
          },
          "direction": {
            "$ref": "#/components/schemas/Direction"
          },
          "ifDoneLimit": {
            "$ref": "#/components/schemas/MonetaryValue"
          },
          "intent": {
            "description": "Whether this order is supposed to open or close a position. If `PreparedTrade.availableOrderIntents` (and/or the\ncorresponding subscription via `availableOrderIntentsToken`) is available, it should be set.\n\nSet it to `close` for orders that are supposed to close an existing position. Note that this is independent\nof the order's direction (e.g. a short position is closed by a buy order).",
            "enum": ["open", "close"],
            "type": "string"
          },
          "isin": {
            "description": "The ISIN of the security to trade, if applicable. Note that at least one of `isin` and `usTicker` must be set.\n\nNote that we will make isin optional in a future version of the API.",
            "type": "string"
          },
          "limit": {
            "$ref": "#/components/schemas/OrderLimitValue",
            "description": "The limit of an order specifies a maximum (direction buy) or minimum (direction sell) value to execute the\norder at.\n\nA limit can be set for orderModel `limit`"
          },
          "limitCurrencyIso": {
            "description": "limit (and stop etc.) currency to use for this order",
            "type": "string"
          },
          "orderExtension": {
            "$ref": "#/components/schemas/OrderExtension",
            "description": "(AllOrNone/Immediate or Cancel/Fill or Kill)"
          },
          "orderModel": {
            "$ref": "#/components/schemas/OrderModel"
          },
          "portfolioId": {
            "type": "string"
          },
          "quoteId": {
            "description": "For `orderModel=quote`: the quoteId, as retrieved from `GetQuote`.",
            "type": "string"
          },
          "quoteLimit": {
            "$ref": "#/components/schemas/OrderQuoteLimitValue",
            "description": "If supported by the broker, an optional limit can be added to a quote trade (`orderModel=quote`)."
          },
          "sellPositionId": {
            "description": "If a list of sellPositions has been provided in `PrepareTrade`, this must contain the selected position id to sell from",
            "type": "string"
          },
          "size": {
            "description": "How much of the security should be traded. For stocks, this is the number of stocks. For bonds, this is a monetary amount.",
            "format": "double",
            "type": "number"
          },
          "sizeUnit": {
            "description": "The currency in which the order sizes are provided",
            "type": "string"
          },
          "stop": {
            "$ref": "#/components/schemas/OrderStopValue",
            "description": "The stop of an order specifies a usually higher value than the current quote (direction buy) or a usually lower value than the current quote (direction sell).\n\nFor the orderModel `stop`, the order is executed immediately when the stop is reached.\nFor the orderModel `stopLimit`, the order will only be executed with a limit value of `stopLimit` (so for buy orders the price of execution will not be higher than `stopLimit`, for sell it orders it will not be lower than `stopLimit`)."
          },
          "stopLimit": {
            "$ref": "#/components/schemas/OrderStopLimitValue",
            "description": "The stop limit specifies a limit to use *after stop has been reached*. For buy orders, the stopLimit will be usually higher than stop, for sell orders the stopLimit will usually be lower than stop."
          },
          "stopLoss": {
            "$ref": "#/components/schemas/MonetaryValue",
            "description": "This is usually a next order: when the original order is executed (and a position has been created), a next order is created with the stop loss\nas a stop value. Note that the specific behavior depends on how the broker implements this."
          },
          "takeProfit": {
            "$ref": "#/components/schemas/MonetaryValue",
            "description": "This is usually a next order: when the original order is executed (and a position has been created), a next order is created with the take profit\nas limit. Note that the specific behavior depends on how the broker implements this."
          },
          "trailingDistance": {
            "$ref": "#/components/schemas/TrailingDistance",
            "description": "For orderModels `trailingStopMarket` and `trailingStopLimit`: the distance between the security's quote and the\nstop value to calculate."
          },
          "trailingLimitTolerance": {
            "$ref": "#/components/schemas/OrderTrailingLimitToleranceValue",
            "description": "For orderModel `trailingStopLimit`: when the trailing stop has been reached, the tolerance\nvalue is added to (for buy orders) or subtracted from (for sell orders) the stop value to obtain\na limit value. After that, the order can be regarded as a limit order with that limit value."
          },
          "usTicker": {
            "deprecated": true,
            "description": "The US ticker of the security to trade, if applicable. Note that at least one of `isin` and `usTicker` must be set.",
            "type": "string"
          },
          "validity": {
            "$ref": "#/components/schemas/OrderValidity",
            "description": "If for preparedTrade provides `Exchange.validityTypesByOrderModel`, one of the available validities must be provided.\nIf there is no validityType to choose from, do not send this field."
          }
        },
        "required": ["size", "isin", "brokerExchangeId", "direction", "orderModel", "portfolioId"],
        "type": "object"
      },
      "OrderExecution": {
        "properties": {
          "amount": {
            "$ref": "#/components/schemas/Amount",
            "description": "The order amount excluding fees.\nAlways a positive value for both buy and sell transactions.\n\nTypically calculated as `quote.value * size`, usually denominated in the portfolio currency (depending on the broker).\nFees and taxes are not included."
          },
          "crossRate": {
            "$ref": "#/components/schemas/MonetaryValue"
          },
          "executedDateTime": {
            "format": "date-time",
            "type": "string"
          },
          "executionStatusText": {
            "type": "string"
          },
          "fee": {
            "$ref": "#/components/schemas/Amount",
            "description": "Amount of fees for this order execution"
          },
          "id": {
            "type": "string"
          },
          "quote": {
            "$ref": "#/components/schemas/Amount"
          },
          "size": {
            "$ref": "#/components/schemas/Amount"
          },
          "tax": {
            "$ref": "#/components/schemas/Amount",
            "description": "Amount of tax for this order execution"
          },
          "totalAmount": {
            "$ref": "#/components/schemas/Amount",
            "description": "The total amount for this order execution, including fees and taxes.\nAlways a positive value, regardless of whether the transaction is a buy or a sell.\n\n- **Buy transaction:** `totalAmount = amount + fee + tax + transactionTax` (when available)\n- **Sell transaction:** `totalAmount = amount - fee - tax - transactionTax` (when available)"
          },
          "transactionTax": {
            "$ref": "#/components/schemas/Amount",
            "description": "Amount of transaction tax for this order execution"
          }
        },
        "required": ["size"],
        "type": "object"
      },
      "OrderExtension": {
        "description": "Some brokers and exchanges allow adding an order extension that influence how the order is executed.\n\n- `FOK`: Fill or kill\n- `ICO`: Immediate or cancel\n- `AON`: All or None\n- `PEA`: Partial executions allowed",
        "enum": ["FOK", "IOC", "AON", "PEA"],
        "type": "string"
      },
      "OrderIntent": {
        "description": "OrderIntent `open` means that the order is supposed to open a new position. `close` means that the order is supposed to close an existing position.\nNote that this is independent of the order's direction (e.g. a short position is closed by a buy order).",
        "enum": ["open", "close"],
        "type": "string"
      },
      "OrderIntentAvailability": {
        "properties": {
          "buy": {
            "items": {
              "$ref": "#/components/schemas/OrderIntent"
            },
            "type": "array"
          },
          "sell": {
            "items": {
              "$ref": "#/components/schemas/OrderIntent"
            },
            "type": "array"
          }
        },
        "required": ["sell", "buy"],
        "type": "object"
      },
      "OrderLimitValue": {
        "description": "The limit of an order specifies a maximum (direction buy) or minimum (direction sell) value to execute the\norder at.\n\nA limit can be set for orderModel `limit`",
        "format": "double",
        "type": "number"
      },
      "OrderModel": {
        "description": "The `orderModel` defines how the order is executed at an exchange.\nSome of the values cannot be used for creation, i.e. currently `fraction` and `savingsPlan` (those\ntwo values only appear in order lists / receipts).",
        "enum": [
          "quote",
          "fraction",
          "savingsPlan",
          "market",
          "limit",
          "stopMarket",
          "stopLimit",
          "trailingStopMarket",
          "trailingStopLimit",
          "ocoStopMarket",
          "ocoStopLimit",
          "unknown"
        ],
        "type": "string"
      },
      "OrderQuoteLimitValue": {
        "description": "If supported by the broker, an optional limit can be added to a quote trade (`orderModel=quote`).",
        "format": "double",
        "type": "number"
      },
      "OrderStatus": {
        "enum": ["open", "canceled", "executed", "open_executed", "canceled_executed"],
        "type": "string"
      },
      "OrderStopLimitValue": {
        "description": "The stop limit specifies a limit to use *after stop has been reached*. For buy orders, the stopLimit will be usually higher than stop, for sell orders the stopLimit will usually be lower than stop.",
        "format": "double",
        "type": "number"
      },
      "OrderStopValue": {
        "description": "The stop of an order specifies a usually higher value than the current quote (direction buy) or a usually lower value than the current quote (direction sell).\n\nFor the orderModel `stop`, the order is executed immediately when the stop is reached.\nFor the orderModel `stopLimit`, the order will only be executed with a limit value of `stopLimit` (so for buy orders the price of execution will not be higher than `stopLimit`, for sell it orders it will not be lower than `stopLimit`).",
        "format": "double",
        "type": "number"
      },
      "OrderTrailingLimitToleranceValue": {
        "description": "For orderModel `trailingStopLimit`: when the trailing stop has been reached, the tolerance\nvalue is added to (for buy orders) or subtracted from (for sell orders) the stop value to obtain\na limit value. After that, the order can be regarded as a limit order with that limit value.",
        "format": "double",
        "type": "number"
      },
      "OrderValidity": {
        "description": "Defines how long an order is valid.",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/DateString"
          },
          "eom": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/OrderValidityType"
          }
        },
        "required": ["type"],
        "type": "object"
      },
      "OrderValidityType": {
        "description": "Order validity:\n- `AUTO`: choose automatically\n- `GFD`: good for day (*today/current trading day*)\n- `GTC`: good til canceled\n- `GTD` good til given date\n- `GTU` good til ultimo (end of month)\n- `GTDT` good til given date time\n- `IOC` immediate or cancel",
        "enum": ["AUTO", "GFD", "GTC", "GTU", "GTD", "GTDT", "IOC"],
        "type": "string"
      },
      "OrderValidityTypeByOrderModel": {
        "additionalProperties": false,
        "properties": {
          "fraction": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "limit": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "market": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "ocoStopLimit": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "ocoStopMarket": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "quote": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "savingsPlan": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "stopLimit": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "stopMarket": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "trailingStopLimit": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "trailingStopMarket": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          },
          "unknown": {
            "items": {
              "$ref": "#/components/schemas/OrderValidityType"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "PageConfig": {
        "properties": {
          "logoUrlDark": {
            "type": "string"
          },
          "logoUrlLight": {
            "type": "string"
          },
          "themeDark": {},
          "themeLight": {},
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PagesConfigurationResponse": {
        "properties": {
          "clientId": {
            "description": "The brokerize clientId to use for the configured page.",
            "type": "string"
          },
          "page": {}
        },
        "required": ["page", "clientId"],
        "type": "object"
      },
      "Portfolio": {
        "properties": {
          "brokerName": {
            "$ref": "#/components/schemas/BrokerName"
          },
          "cashAccountIds": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "currency": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "id": {
            "type": "string"
          },
          "idHash": {
            "description": "A portfolio idHash is a unique identifier used to represent a portfolio within a user account. The idHash is automatically generated based on the original broker id of the portfolio,\nmeaning that if a portfolio is synchronized into a new user account, it will usually retain the same idHash as in the old account (although it will be assigned a new globally unique id).\nWhen applications use temporary or guest user accounts, it makes sense to use the idHash instead of the id to implement features like \"last used portfolio\" etc. This is because the idHash remains\nthe same even if the portfolio is synchronized into a new user account, whereas a new id will be assigned.\n\nIt's important to note that the `idHash` is unique within a user account, meaning that no two portfolios within the same account can have the same idHash.",
            "type": "string"
          },
          "portfolioName": {
            "type": "string"
          },
          "portfolioNameOriginal": {
            "type": "string"
          },
          "sessionIds": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "syncInfo": {
            "$ref": "#/components/schemas/PortfolioSyncInfo"
          }
        },
        "required": [
          "currency",
          "idHash",
          "syncInfo",
          "cashAccountIds",
          "sessionIds",
          "portfolioNameOriginal",
          "portfolioName",
          "brokerName",
          "id"
        ],
        "type": "object"
      },
      "PortfolioCalendarDateRange": {
        "properties": {
          "dateRange": {
            "$ref": "#/components/schemas/TradeStatisticsDateRange"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/PortfolioCalendarItem"
            },
            "type": "array"
          }
        },
        "required": ["items", "dateRange"],
        "type": "object"
      },
      "PortfolioCalendarItem": {
        "properties": {
          "date": {
            "description": "A date string, formatted as YYYY-MM-DD.\nNote that the date means that day in the timezone `Europe/Berlin`, so it aggregates orders for that\ntimezone.",
            "type": "string"
          },
          "executionCount": {
            "description": "How many order executions have been aggregated.",
            "format": "double",
            "type": "number"
          },
          "transactionVolume": {
            "$ref": "#/components/schemas/Amount",
            "description": "Sum of the order executions' `amount`s."
          }
        },
        "required": ["transactionVolume", "executionCount", "date"],
        "type": "object"
      },
      "PortfolioQuotes": {
        "properties": {
          "availableCash": {
            "$ref": "#/components/schemas/Amount",
            "description": "Cash that can be used for orders. It should probably be renamed to buyingPower to be consistent with the buyingPower Observable. This has to be checked."
          },
          "cashAccountBalance": {
            "$ref": "#/components/schemas/Amount",
            "description": "Booked amount of the cash account assigned to this portfolio."
          },
          "positionValue": {
            "$ref": "#/components/schemas/Amount",
            "description": "Current total amount of the open positions, denoted in the currency of the respective portfolio."
          },
          "profitLossAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "P/L sum of currently open positions."
          },
          "profitLossAbsPrevClose": {
            "$ref": "#/components/schemas/Amount",
            "description": "P/L sum of all open positions, since prevClose (or buy, if that is later than prevClose)."
          },
          "profitLossRel": {
            "description": "Relative P/L of all open positions, since acquisition. 1 means +100%",
            "format": "double",
            "type": "number"
          },
          "profitLossRelPrevClose": {
            "description": "Relative P/L of all open positions, since prevClose (or buy, if that is later than prevClose). 1 means +100%",
            "format": "double",
            "type": "number"
          },
          "totalValue": {
            "$ref": "#/components/schemas/Amount",
            "description": "The total value, usually `cashAccountBalance + positionValue`."
          }
        },
        "type": "object"
      },
      "PortfolioSyncInfo": {
        "discriminator": {
          "mapping": {
            "COMPLETE": "#/components/schemas/PortfolioSyncInfoComplete",
            "ERROR": "#/components/schemas/PortfolioSyncInfoError",
            "INCOMPLETE": "#/components/schemas/PortfolioSyncInfoIncomplete",
            "PENDING": "#/components/schemas/PortfolioSyncInfoPending"
          },
          "propertyName": "status"
        },
        "properties": {
          "status": {
            "$ref": "#/components/schemas/PortfolioSyncInfoStatus"
          }
        },
        "required": ["status"],
        "type": "object"
      },
      "PortfolioSyncInfoComplete": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PortfolioSyncInfo"
          },
          {
            "$ref": "#/components/schemas/PortfolioSyncInfoCompleteSpecifics"
          }
        ],
        "required": ["lastSync", "status"],
        "type": "object"
      },
      "PortfolioSyncInfoCompleteSpecifics": {
        "properties": {
          "lastSync": {
            "format": "date-time",
            "type": "string"
          }
        }
      },
      "PortfolioSyncInfoError": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PortfolioSyncInfo"
          },
          {
            "$ref": "#/components/schemas/PortfolioSyncInfoErrorSpecifics"
          }
        ],
        "required": ["error", "status"],
        "type": "object"
      },
      "PortfolioSyncInfoErrorSpecifics": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/SyncError"
          }
        }
      },
      "PortfolioSyncInfoIncomplete": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PortfolioSyncInfo"
          },
          {
            "$ref": "#/components/schemas/PortfolioSyncInfoIncompleteSpecifics"
          }
        ],
        "required": ["lastSync", "status"],
        "type": "object"
      },
      "PortfolioSyncInfoIncompleteSpecifics": {
        "properties": {
          "lastSync": {
            "format": "date-time",
            "type": "string"
          }
        }
      },
      "PortfolioSyncInfoPending": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PortfolioSyncInfo"
          },
          {
            "$ref": "#/components/schemas/PortfolioSyncInfoPendingSpecifics"
          }
        ],
        "required": ["status"],
        "type": "object"
      },
      "PortfolioSyncInfoPendingSpecifics": {
        "properties": {}
      },
      "PortfolioSyncInfoStatus": {
        "enum": ["PENDING", "INCOMPLETE", "COMPLETE", "ERROR"],
        "nullable": false,
        "type": "string"
      },
      "PortfoliosResponse": {
        "properties": {
          "cashAccounts": {
            "items": {
              "$ref": "#/components/schemas/CashAccount"
            },
            "type": "array"
          },
          "portfolios": {
            "items": {
              "$ref": "#/components/schemas/Portfolio"
            },
            "type": "array"
          }
        },
        "required": ["cashAccounts", "portfolios"],
        "type": "object"
      },
      "Position": {
        "properties": {
          "availableSize": {
            "description": "How much of the position is available for sale.",
            "format": "double",
            "type": "number"
          },
          "brokerExchangeId": {
            "description": "The exchange id as defined by the broker.",
            "type": "string"
          },
          "brokerSecurityId": {
            "description": "The security id, as defined by the broker. For example, this can be used to call `PrepareTrade`, even if the frontend\ndoes not have a mapping for the security.",
            "type": "string"
          },
          "comment": {
            "description": "Textual comment for the position.",
            "type": "string"
          },
          "commentIsEditable": {
            "description": "True if the user may edit a comment for this position.",
            "type": "boolean"
          },
          "currentValuation": {
            "$ref": "#/components/schemas/PositionValuation",
            "description": "Current position quote and value."
          },
          "direction": {
            "$ref": "#/components/schemas/Direction",
            "description": "Some brokers allow positions to be either short (`sell`) or long (`buy`). If `direction` is present for a position,\nthe direction should be displayed accordingly (e.g. frontends can show it as a symbol or a separate column)."
          },
          "exchangeId": {
            "description": "The mapped exchange id, as retrievable in the the `/exchanges` endpoint.",
            "format": "int32",
            "type": "integer"
          },
          "exchangeName": {
            "description": "Name of the exchange, as provided by the broker.",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "prevCloseValuation": {
            "$ref": "#/components/schemas/PositionValuation",
            "description": "\"prevClose\" position quote and value. May also be today, if it was purchased today."
          },
          "profitLossAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "Absolute P/L of the entire position, since acquisition."
          },
          "profitLossAbsPrevClose": {
            "$ref": "#/components/schemas/Amount",
            "description": "Absolute P/L of the entire position, since acquisition."
          },
          "profitLossAbsWithDividends": {
            "$ref": "#/components/schemas/Amount",
            "description": "Absolute P/L of the entire position, since acquisition, but including the dividends booked for this position (see `totalDividends`)."
          },
          "profitLossRel": {
            "description": "Relative P/L of the entire posiiton, since acquisition. 1 means +100%",
            "format": "double",
            "type": "number"
          },
          "profitLossRelPrevClose": {
            "description": "Relative P/L of the entire posiiton, since \"prevClose\". 1 means +100%",
            "format": "double",
            "type": "number"
          },
          "profitLossRelWithDividends": {
            "description": "Relative P/L of the entire position, since acquisition, but including the dividends booked for this position (see `totalDividends`). 1 means +100%",
            "format": "double",
            "type": "number"
          },
          "purchaseDate": {
            "$ref": "#/components/schemas/DateString",
            "description": "Date of position purchase."
          },
          "purchaseDateTime": {
            "description": "Date and time of position purchase. If not set, purchaseDate may at least contain the date.",
            "format": "date-time",
            "type": "string"
          },
          "purchaseValuation": {
            "$ref": "#/components/schemas/PositionValuation",
            "description": "Position quote and value at acquisition."
          },
          "security": {
            "$ref": "#/components/schemas/Security"
          },
          "size": {
            "format": "double",
            "type": "number"
          },
          "sizeDecimals": {
            "description": "If present, defines how many decimal places should be displayed for size values.",
            "format": "int32",
            "type": "integer"
          },
          "sizeUnit": {
            "$ref": "#/components/schemas/CurrencyCode"
          },
          "sourceData": {
            "type": "string"
          },
          "stakingSize": {
            "description": "How much of the position is locked in staking.",
            "format": "double",
            "type": "number"
          }
        },
        "required": ["availableSize", "security", "sizeUnit", "size", "id"],
        "type": "object"
      },
      "PositionValuation": {
        "properties": {
          "crossRate": {
            "description": "CrossRate that was used to convert from quotation to positionValue, if this applies here.",
            "format": "double",
            "type": "number"
          },
          "isDelayed": {
            "type": "boolean"
          },
          "positionValue": {
            "$ref": "#/components/schemas/Amount"
          },
          "quotation": {
            "$ref": "#/components/schemas/Amount"
          }
        },
        "type": "object"
      },
      "PrepareOAuthRedirectParams": {
        "properties": {
          "brokerName": {
            "$ref": "#/components/schemas/BrokerName"
          },
          "env": {
            "type": "string"
          },
          "returnToUrl": {
            "type": "string"
          }
        },
        "required": ["returnToUrl", "env", "brokerName"],
        "type": "object"
      },
      "PrepareOAuthRedirectResponse": {
        "properties": {
          "redirectTo": {
            "type": "string"
          }
        },
        "required": ["redirectTo"],
        "type": "object"
      },
      "PrepareTradeResponse": {
        "properties": {
          "preparedTrade": {
            "$ref": "#/components/schemas/PreparedTrade"
          }
        },
        "required": ["preparedTrade"],
        "type": "object"
      },
      "PreparedTrade": {
        "properties": {
          "availableOrderIntents": {
            "$ref": "#/components/schemas/OrderIntentAvailability",
            "description": "If present, this defines whether order intents can be explicitly selected. This is provided if the broker generally\nsupports short selling. If short selling is supported, the broker may allow contrary positions (i.e. having both a short and\na long position for one instrument *or* only support one direction. This (broker-specific) behavior is encoded here."
          },
          "availableOrderIntentsToken": {
            "description": "If available, the available order intents can be polled/subscribed using this token. In this case,\nthe `availableOrderIntents` field must be regarded as the initial snapshot.",
            "type": "string"
          },
          "brokerSecurityId": {
            "description": "The broker security id is the unique identifier for the security *at the given broker*. It is\nused in subsequent requests in the order creation process to identify the security.",
            "type": "string"
          },
          "costEstimationIsNotAvailable": {
            "description": "True if no cost estimation is available at all for this instrument.",
            "type": "boolean"
          },
          "costEstimationIsOnlyDetailedTable": {
            "description": "Indicates that this cost estimation does not include summary fields\n(e.g. `entryCosts`, `totalCosts`, etc.) and therefore cannot be rendered\ninline within the order form. Instead, only a detailed representation is available.\n\nHistorically, this implied that only `detailedTable` would be provided\n(hence the flag name). However, in modern usage, `costDetailsLink` may be present instead.\n\nIn that case, clients can render an action such as \"Show detailed costs,\" which then loads the cost\nestimartion and either displays the `detailedTable` or navigates to the `costDetailsLink` URL.",
            "type": "boolean"
          },
          "costEstimationMustBeShown": {
            "description": "If this is true, the estimated order costs must be shown before the user can create the order.\nIf this is false, showing the order costs is optional.",
            "type": "boolean"
          },
          "exchanges": {
            "items": {
              "$ref": "#/components/schemas/Exchange"
            },
            "type": "array"
          },
          "noExchangeDefault": {
            "description": "If this is true, frontends are not allowed to set an exchange default. Users must select an exchange explicitly.",
            "type": "boolean"
          },
          "riskClassInfo": {
            "$ref": "#/components/schemas/RiskClassInfo"
          },
          "security": {
            "$ref": "#/components/schemas/Security"
          },
          "securityDetailedInfo": {
            "$ref": "#/components/schemas/SecurityDetailedInfo",
            "description": "If available, contains more specific details about the security which might be relevant for trading (e.g. a link to a product information table).\nIf `securityDetailedInfo.token` is available, the details can be retrieved using the `getSecurityDetailedInfo` endpoint."
          },
          "sellPositions": {
            "description": "If this is set, the user has to select a position to sell from. This may be the case if a position is\nstored in different locations or sub-positions are blocked until some date.\nIf the user does not need to specify the position, this is left undefined.\nIf it is set, user interfaces should offer a dropdown for selecting the position.",
            "items": {
              "$ref": "#/components/schemas/SellPosition"
            },
            "type": "array"
          },
          "sizeMaxDecimalsBySizeUnit": {
            "$ref": "#/components/schemas/SizeMaxDecimalsBySizeUnit",
            "description": "The maximum number of decimal places specified for each sizeUnit.\nIf it is defined for the selected sizeUnit, frontends should limit the number input to this number of decimal places.\nIf it is not defined, the number of decimal places is unknown and frontends should allow any number."
          },
          "sizeUnit": {
            "$ref": "#/components/schemas/CurrencyCode",
            "description": "Default unit in which `size` is provided for orders.\n\n- For stocks and other assets, this is the number of stocks (encoded as `XXX`).\n- For bonds, this is the currency of the bond, so that size is the monetary amount.\n- For crypto currencies, the size may also be a monetary amount.\n\nThere may be more options for the user to specify the order size in. Those options\nare provided in the field `sizeUnitsByCashAccountId` if applicable for the account."
          },
          "sizeUnitConstraints": {
            "description": "If present, this defines which sizeUnits are available for a combination of cashAccountId, orderModel and direction.\nAn entry in this list is considered a match if all specified attributes match.\n\nFor example, if an entry specifies orderModels and directions and both orderModel and direction are included\nin the respective attributes in the constraint, the entry specifies the available sizeUnits.",
            "items": {
              "$ref": "#/components/schemas/SizeUnitConstraint"
            },
            "type": "array"
          },
          "sizeUnitsByCashAccountId": {
            "$ref": "#/components/schemas/sizeUnitsByCashAccountIdMap",
            "description": "If present, this contains the list allowed values for `sizeUnit` which the user may select per cash account.\nFor example, a crypto coin is tradable in sizeUnits `XXX` and `EUR` in one account, and in `USD` and `XXX` in another account.\nIf not present, `sizeUnit` must be used."
          },
          "strikingHint": {
            "description": "If present, this hint must be displayed in the order form. It should be visible during the order\ncreation process, but does not need to be accepted by the user explicitly.",
            "type": "string"
          },
          "tradingViaCryptoService": {
            "description": "If this is `true`, trades for this security must be sent to the external crypto trading service. If applicable for your client,\nthe URL of that endpoint will be provided in the admin panel. The request `CreateTrade` must then be directed to that endpoint instead\nof the brokerize API.\n\nIf this is `false` or undefined, trades can be sent directly to the brokerize API.",
            "type": "boolean"
          }
        },
        "required": [
          "costEstimationIsNotAvailable",
          "costEstimationMustBeShown",
          "exchanges",
          "sizeUnit",
          "security",
          "brokerSecurityId"
        ],
        "type": "object"
      },
      "QuoteExpiration": {
        "properties": {
          "expires": {
            "description": "Timestamp at which the quotation expiration timer ends (after this, the quote order is likely to be rejected).",
            "format": "date-time",
            "type": "string"
          },
          "milliseconds": {
            "description": "Milliseconds to expiration. This can be calculated from `expires - started`, assuming the local clock works correctly.\nSometimes end users have not set their local clock correctly. You can either correct for the clock drift using the\n`Date` HTTP header or just use this value and assume the expiration to happen at `time of receiving the response + milliseconds`.",
            "format": "int32",
            "type": "integer"
          },
          "started": {
            "description": "Timestamp at which the quote expiration timer starts.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": ["milliseconds", "expires", "started"],
        "type": "object"
      },
      "RecoveryPhraseItem": {
        "properties": {
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "expiresAt": {
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "lastUsedAt": {
            "format": "date-time",
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": ["expiresAt", "lastUsedAt", "createdAt", "name", "id"],
        "type": "object"
      },
      "RenderGenericTableParams": {
        "properties": {
          "table": {
            "$ref": "#/components/schemas/GenericTable"
          }
        },
        "required": ["table"],
        "type": "object"
      },
      "RiskClassInfo": {
        "additionalProperties": false,
        "properties": {
          "legalHint": {
            "description": "If set, must be displayed as a static hint (which the user does not need to confirm) before the order button. May contain (some) HTML.",
            "type": "string"
          },
          "msg": {
            "description": "Risk class message to display (may contain a subset of HTML: `<a>` tags for linking to external pages, `<p>`/`<br>` to add paragraphs/line breaks, `<ul><li></li></ul>` to show unuordered lists).\nUsers must accept the message before they can create the order. This can happen before the actual order form is visible.",
            "type": "string"
          },
          "onlySellAllowed": {
            "description": "If true, only sell is allowed for this instrument.",
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "Security": {
        "description": "A security's basic data like symbols and names.",
        "properties": {
          "cryptoCode": {
            "deprecated": true,
            "description": "The crypto code string if the security is `sizeKind=crypto`. E.g. 'BTC'",
            "type": "string"
          },
          "isin": {
            "deprecated": true,
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "priceFactor": {
            "description": "If provided, the security's quote has to be multiplied to get the actual cash counter value. This information\ncan be used to determine whether custom calculations can be done for the security in frontends.",
            "format": "double",
            "type": "number"
          },
          "selector": {
            "$ref": "#/components/schemas/SecuritySelector"
          },
          "sinoTicker": {
            "deprecated": true,
            "description": "The security`s symbol as used by broker \"sino\" (this can be used to implement broker-specific security matching behavior)",
            "type": "string"
          },
          "sizeKind": {
            "description": "If `sizeUnit` is a currency, the corresponding size field in UIs should be labeled with that selected currency.\n- for bonds `sizeKind=\"bond\"`, the label should be (for example) like \"nominal amount in EUR\"\n- for crypto currencies `sizeKind=\"crypto\"`, the label should be (for example) like \"amount in EUR\"",
            "enum": ["bond", "crypto"],
            "type": "string"
          },
          "symbol": {
            "deprecated": true,
            "type": "string"
          },
          "usTicker": {
            "deprecated": true,
            "type": "string"
          },
          "wkn": {
            "deprecated": true,
            "type": "string"
          }
        },
        "required": ["selector"],
        "type": "object"
      },
      "SecurityDetailedInfo": {
        "description": "If available, contains more specific details about the security which might be relevant for trading (e.g. a link to a product information table).\nIf `securityDetailedInfo.token` is available, the details can be retrieved using the `getSecurityDetailedInfo` endpoint.",
        "properties": {
          "label": {
            "type": "string"
          },
          "token": {
            "type": "string"
          }
        },
        "required": ["token", "label"],
        "type": "object"
      },
      "SecurityQuote": {
        "properties": {
          "timestamp": {
            "description": "*Milliseconds* since *the epoch*.",
            "format": "int64",
            "type": "integer"
          },
          "value": {
            "format": "double",
            "type": "number"
          }
        },
        "required": ["value"],
        "type": "object"
      },
      "SecurityQuotes": {
        "properties": {
          "ask": {
            "$ref": "#/components/schemas/SecurityQuote"
          },
          "bid": {
            "$ref": "#/components/schemas/SecurityQuote"
          }
        },
        "type": "object"
      },
      "SecurityQuotesMeta": {
        "properties": {
          "currency": {
            "type": "string"
          },
          "decimals": {
            "format": "double",
            "type": "number"
          },
          "quoteSourceName": {
            "type": "string"
          }
        },
        "required": ["quoteSourceName", "currency", "decimals"],
        "type": "object"
      },
      "SecurityQuotesResponse": {
        "properties": {
          "quotes": {
            "$ref": "#/components/schemas/SecurityQuotes"
          }
        },
        "required": ["quotes"],
        "type": "object"
      },
      "SecuritySelector": {
        "properties": {
          "cryptoCode": {
            "description": "The securities crypto code if it is of type \"crypto\". E.g. 'BTC'",
            "type": "string"
          },
          "cryptoPair": {
            "description": "The securities crypto pair if it is of type \"crypto\". E.g. 'BTC-EUR'",
            "type": "string"
          },
          "isin": {
            "description": "The security's `isin` (International Securities Identification Number).",
            "type": "string"
          },
          "sinoTicker": {
            "description": "The security's symbol as used by the broker `sino` (can be used to implement broker-specific security matching behavior)",
            "type": "string"
          },
          "usTicker": {
            "description": "The security's US Ticker symbol",
            "type": "string"
          },
          "wkn": {
            "description": "The security's `wkn` (Wertpapierkennnummer).",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SellPosition": {
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": ["label", "id"],
        "type": "object"
      },
      "Session": {
        "properties": {
          "authInfo": {
            "$ref": "#/components/schemas/AuthInfo"
          },
          "brokerName": {
            "$ref": "#/components/schemas/BrokerName"
          },
          "env": {
            "description": "Name of the broker environment this session belongs to.",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "lastSuccessfulSync": {
            "deprecated": true,
            "format": "date-time",
            "type": "string"
          },
          "syncError": {
            "$ref": "#/components/schemas/SyncError",
            "deprecated": true
          },
          "syncInfo": {
            "$ref": "#/components/schemas/SessionSyncInfo"
          }
        },
        "required": ["syncInfo", "env", "brokerName", "id"],
        "type": "object"
      },
      "SessionResponse": {
        "properties": {
          "sessions": {
            "items": {
              "$ref": "#/components/schemas/Session"
            },
            "type": "array"
          }
        },
        "required": ["sessions"],
        "type": "object"
      },
      "SessionSyncInfo": {
        "discriminator": {
          "mapping": {
            "ERROR": "#/components/schemas/SessionSyncInfoError",
            "PENDING": "#/components/schemas/SessionSyncInfoPending",
            "SYNCED": "#/components/schemas/SessionSyncInfoSynced"
          },
          "propertyName": "status"
        },
        "properties": {
          "status": {
            "$ref": "#/components/schemas/SessionSyncInfoStatus"
          }
        },
        "required": ["status"],
        "type": "object"
      },
      "SessionSyncInfoError": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SessionSyncInfo"
          },
          {
            "$ref": "#/components/schemas/SessionSyncInfoErrorSpecifics"
          }
        ],
        "required": ["error", "status"],
        "type": "object"
      },
      "SessionSyncInfoErrorSpecifics": {
        "properties": {
          "error": {
            "$ref": "#/components/schemas/SyncError"
          }
        }
      },
      "SessionSyncInfoPending": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SessionSyncInfo"
          },
          {
            "$ref": "#/components/schemas/SessionSyncInfoPendingSpecifics"
          }
        ],
        "required": ["status"],
        "type": "object"
      },
      "SessionSyncInfoPendingSpecifics": {
        "properties": {}
      },
      "SessionSyncInfoStatus": {
        "enum": ["PENDING", "SYNCED", "ERROR"],
        "nullable": false,
        "type": "string"
      },
      "SessionSyncInfoSynced": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SessionSyncInfo"
          },
          {
            "$ref": "#/components/schemas/SessionSyncInfoSyncedSpecifics"
          }
        ],
        "required": ["lastSync", "status"],
        "type": "object"
      },
      "SessionSyncInfoSyncedSpecifics": {
        "properties": {
          "lastSync": {
            "format": "date-time",
            "type": "string"
          }
        }
      },
      "SizeMaxDecimalsBySizeUnit": {
        "additionalProperties": {
          "format": "double",
          "type": "number"
        },
        "description": "The maximum number of decimal places specified for each sizeUnit.\nIf it is defined for the selected sizeUnit, frontends should limit the number input to this number of decimal places.\nIf it is not defined, the number of decimal places is unknown and frontends should allow any number.",
        "properties": {},
        "type": "object"
      },
      "SizeUnitConstraint": {
        "properties": {
          "cashAccountIds": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "directions": {
            "items": {
              "$ref": "#/components/schemas/Direction"
            },
            "type": "array"
          },
          "orderModels": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "sizeUnits": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": ["sizeUnits"],
        "type": "object"
      },
      "StringMapByOrderModel": {
        "additionalProperties": false,
        "properties": {
          "fraction": {
            "type": "string"
          },
          "limit": {
            "type": "string"
          },
          "market": {
            "type": "string"
          },
          "ocoStopLimit": {
            "type": "string"
          },
          "ocoStopMarket": {
            "type": "string"
          },
          "quote": {
            "type": "string"
          },
          "savingsPlan": {
            "type": "string"
          },
          "stopLimit": {
            "type": "string"
          },
          "stopMarket": {
            "type": "string"
          },
          "trailingStopLimit": {
            "type": "string"
          },
          "trailingStopMarket": {
            "type": "string"
          },
          "unknown": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SummarizedTrade": {
        "properties": {
          "closeAvgQuotation": {
            "$ref": "#/components/schemas/Amount"
          },
          "closeDateTime": {
            "format": "date-time",
            "type": "string"
          },
          "details": {
            "type": "string"
          },
          "fees": {
            "$ref": "#/components/schemas/Amount",
            "description": "Fees paid in total for the trade, if available.\nThis value is the sell transaction's fee plus partial fees for the corresponding buys."
          },
          "id": {
            "type": "string"
          },
          "openAvgQuotation": {
            "$ref": "#/components/schemas/Amount"
          },
          "openDateTime": {
            "format": "date-time",
            "type": "string"
          },
          "profitLossAbs": {
            "$ref": "#/components/schemas/Amount"
          },
          "profitLossAbsAfterFees": {
            "$ref": "#/components/schemas/Amount"
          },
          "profitLossRel": {
            "format": "double",
            "type": "number"
          },
          "profitLossRelAfterFees": {
            "format": "double",
            "type": "number"
          },
          "security": {
            "$ref": "#/components/schemas/Security"
          },
          "size": {
            "$ref": "#/components/schemas/Amount"
          },
          "tax": {
            "$ref": "#/components/schemas/Amount",
            "description": "Tax paid in total for the trade, if available.\nThis value is the sell transaction's tax plus partial taxes for the corresponding buys."
          },
          "tradedVolume": {
            "$ref": "#/components/schemas/Amount",
            "description": "Total traded amount (i.e. the amount of the sell + partial amounts of the buy transactions)."
          },
          "transactionTax": {
            "$ref": "#/components/schemas/Amount",
            "description": "Transaction tax paid in total for the trade, if available.\nThis value is the sell transaction's transactionTax plus partial transactionTaxes for the corresponding buys."
          }
        },
        "required": [
          "details",
          "profitLossRel",
          "profitLossAbs",
          "size",
          "closeAvgQuotation",
          "openAvgQuotation",
          "closeDateTime",
          "openDateTime",
          "security",
          "id"
        ],
        "type": "object"
      },
      "SyncError": {
        "properties": {
          "date": {
            "format": "date-time",
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": ["message", "date"],
        "type": "object"
      },
      "TakeProfitStopLossCapabilites": {
        "description": "Describes whether and how takeProfit/stopLoss may be defined for an order.\nFor example, some brokers only allow takeProfit *or* stopLoss, not both.",
        "properties": {
          "exclusive": {
            "description": "If this is `true`, only one of `takeProfit` or `stopLoss` can be set for an order.\nIf this is `false`, both can be set.",
            "type": "boolean"
          },
          "stopLoss": {
            "$ref": "#/components/schemas/TakeProfitStopLossDetail",
            "description": "Constraints for specifiyng a `stopLoss`."
          },
          "takeProfit": {
            "$ref": "#/components/schemas/TakeProfitStopLossDetail",
            "description": "Constraints for specifiyng a `takeProfit`."
          }
        },
        "required": ["stopLoss", "takeProfit", "exclusive"],
        "type": "object"
      },
      "TakeProfitStopLossDetail": {
        "properties": {
          "directions": {
            "description": "The order directions where providing the value is available.",
            "items": {
              "$ref": "#/components/schemas/Direction"
            },
            "type": "array"
          },
          "orderModels": {
            "description": "The orderModels for which the values may be provided.",
            "items": {
              "$ref": "#/components/schemas/OrderModel"
            },
            "type": "array"
          }
        },
        "required": ["directions", "orderModels"],
        "type": "object"
      },
      "TokenParams": {
        "properties": {
          "grant_type": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          }
        },
        "required": ["refresh_token", "grant_type"],
        "type": "object"
      },
      "TokenResponse": {
        "properties": {
          "access_token": {
            "type": "string"
          },
          "expires_in": {
            "format": "double",
            "type": "number"
          },
          "refresh_token": {
            "type": "string"
          },
          "refresh_token_expires_in": {
            "format": "double",
            "type": "number"
          },
          "refresh_token_without_tradingsession": {
            "description": "If applicable for the client configuration, another refresh token which does not have\naccess to the current trading session. It can be used to acquire a new trading session.",
            "type": "string"
          },
          "refresh_token_without_tradingsession_expires_in": {
            "format": "double",
            "type": "number"
          },
          "token_type": {
            "description": "token_type, it should always be \"bearer\"",
            "type": "string"
          }
        },
        "required": ["refresh_token_expires_in", "refresh_token", "expires_in", "access_token", "token_type"],
        "type": "object"
      },
      "TradeDraft": {
        "description": "Trade drafts are orders saved into for the user, to be reviewed and possibly executed at a later time.",
        "properties": {
          "createdAt": {
            "description": "The date when this trade draft was created",
            "format": "date-time",
            "type": "string"
          },
          "description": {
            "description": "Information about the connected order.",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "inactive": {
            "description": "Whether the trade draft is still active. Executing or dismissing the trade turns the flag to `true`",
            "type": "boolean"
          },
          "orderData": {
            "$ref": "#/components/schemas/TradeDraftOrderCreate",
            "description": "The data of the trade draft to be executed"
          },
          "orderId": {
            "description": "If the trade draft is executed, the returned orderId is saved in here",
            "format": "double",
            "type": "number"
          },
          "userId": {
            "format": "double",
            "type": "number"
          }
        },
        "required": ["orderData", "orderId", "createdAt", "inactive", "description", "userId", "id"],
        "type": "object"
      },
      "TradeDraftCreateParams": {
        "properties": {
          "description": {
            "type": "string"
          },
          "orderData": {
            "$ref": "#/components/schemas/TradeDraftOrderCreate"
          }
        },
        "required": ["orderData"],
        "type": "object"
      },
      "TradeDraftOrderCreate": {
        "properties": {
          "cashAccountId": {
            "type": "string"
          },
          "direction": {
            "$ref": "#/components/schemas/Direction"
          },
          "exchangeId": {
            "format": "int32",
            "type": "integer"
          },
          "limit": {
            "$ref": "#/components/schemas/OrderLimitValue"
          },
          "limitCurrencyIso": {
            "description": "limit (and stop etc.) currency to use for this order",
            "type": "string"
          },
          "orderExtension": {
            "$ref": "#/components/schemas/OrderExtension",
            "description": "(AllOrNone/Immediate or Cancel/Fill or Kill)"
          },
          "orderModel": {
            "$ref": "#/components/schemas/OrderModel"
          },
          "portfolioId": {
            "type": "string"
          },
          "quoteLimit": {
            "$ref": "#/components/schemas/OrderQuoteLimitValue"
          },
          "security": {
            "$ref": "#/components/schemas/Security"
          },
          "size": {
            "description": "How much of the security should be traded. For stocks, this is the number of stocks. For bonds, this is a monetary amount.",
            "format": "double",
            "type": "number"
          },
          "sizeUnit": {
            "type": "string"
          },
          "stop": {
            "$ref": "#/components/schemas/OrderStopValue"
          },
          "stopLimit": {
            "$ref": "#/components/schemas/OrderStopLimitValue"
          },
          "validity": {
            "$ref": "#/components/schemas/OrderValidity"
          }
        },
        "required": ["size", "direction", "portfolioId", "orderModel", "security"],
        "type": "object"
      },
      "TradeDraftUpdateParams": {
        "properties": {
          "description": {
            "type": "string"
          },
          "inactive": {
            "type": "boolean"
          },
          "orderId": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "TradeStatistics": {
        "properties": {
          "avgLossAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "The average loss of all losing trades."
          },
          "avgProfitAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "The average profit of all winning trades."
          },
          "avgProfitLossAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "The average profit/loss of all covered trades."
          },
          "bestTrade": {
            "$ref": "#/components/schemas/SummarizedTrade",
            "description": "The trade with the highest profit in the portfolio."
          },
          "hitRate": {
            "description": "Which fraction of the trades where winners. 1 is 100%, so a value of 1 would indicate\n\"all trades were winners\".",
            "format": "double",
            "type": "number"
          },
          "holdingPeriodInDays": {
            "properties": {
              "average": {
                "description": "The average holding period in days.",
                "format": "double",
                "type": "number"
              },
              "max": {
                "description": "The maximum holding period in days.",
                "format": "double",
                "type": "number"
              },
              "min": {
                "description": "The minimum holding period in days.",
                "format": "double",
                "type": "number"
              }
            },
            "required": ["min", "max", "average"],
            "type": "object"
          },
          "longestLosingStreak": {
            "description": "The maximum number of consecutive losing trades in the given list of trades.",
            "format": "int32",
            "type": "integer"
          },
          "longestWinningStreak": {
            "description": "The maximum number of consecutive winning trades in the given list of trades.",
            "format": "int32",
            "type": "integer"
          },
          "loserCount": {
            "description": "How many trades had a negative profit/loss.",
            "format": "int32",
            "type": "integer"
          },
          "profitFactor": {
            "description": "Profits/Losses. E.g. if there were 2000€ profits in winning trades and 1000€ losses in losing trades,\nthe profitFactor would be 2000€ / 1000€ = 2.",
            "format": "double",
            "type": "number"
          },
          "profitLossAbs": {
            "$ref": "#/components/schemas/Amount",
            "description": "The total profit/loss of all covered trades."
          },
          "tradeCount": {
            "description": "How many trades are part of the calculation.",
            "format": "int32",
            "type": "integer"
          },
          "winnerCount": {
            "description": "How many trades had a positive profit/loss.",
            "format": "int32",
            "type": "integer"
          },
          "winnerDaysRatio": {
            "description": "The proportion of trading days that ended with a net profit within the selected timeframe.\n\n- Calculated as the number of profitable trading days divided by the total number of trading days with activity.\n- For example, if trades were executed on 10 days and 2 of those days resulted in a net profit, the ratio would be `0.2`.\n- If no trades occurred during the selected period, the value is `undefined`.",
            "format": "double",
            "type": "number"
          },
          "winnerMonthsRatio": {
            "description": "The proportion of months that ended with a net profit within the selected timeframe.\n\n- Calculated as the number of profitable trading months divided by the total number of trading months with activity.\n- For example, if trades were executed in 10 months and 2 of those months resulted in a net profit, the ratio would be `0.2`.\n- If no trades occurred during the selected period, the value is `undefined`.",
            "format": "double",
            "type": "number"
          },
          "worstTrade": {
            "$ref": "#/components/schemas/SummarizedTrade",
            "description": "The trade with the lowest profit in the portfolio."
          }
        },
        "required": [
          "holdingPeriodInDays",
          "hitRate",
          "longestLosingStreak",
          "longestWinningStreak",
          "loserCount",
          "winnerCount",
          "tradeCount"
        ],
        "type": "object"
      },
      "TradeStatisticsDateRange": {
        "properties": {
          "dateString": {
            "type": "string"
          },
          "from": {
            "format": "date-time",
            "type": "string"
          },
          "to": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": ["to", "from", "dateString"],
        "type": "object"
      },
      "TradeStatisticsItem": {
        "properties": {
          "dateRange": {
            "$ref": "#/components/schemas/TradeStatisticsDateRange"
          },
          "stats": {
            "$ref": "#/components/schemas/TradeStatistics"
          }
        },
        "required": ["stats", "dateRange"],
        "type": "object"
      },
      "TradeWarning": {
        "properties": {
          "message": {
            "type": "string"
          }
        },
        "required": ["message"],
        "type": "object"
      },
      "TradingSessionLifetime": {
        "enum": ["ONE_DAY", "ONE_WEEK"],
        "type": "string"
      },
      "TrailingDistance": {
        "description": "For orderModels `trailingStopMarket` and `trailingStopLimit`: the distance between the security's quote and the\nstop value to calculate.",
        "properties": {
          "mode": {
            "enum": ["abs", "rel"],
            "type": "string"
          },
          "value": {
            "$ref": "#/components/schemas/MonetaryValue"
          }
        },
        "required": ["value", "mode"],
        "type": "object"
      },
      "ValidationDetail": {
        "properties": {
          "debugData": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": ["debugData", "message"],
        "type": "object"
      },
      "ValidationDetails": {
        "additionalProperties": {
          "$ref": "#/components/schemas/ValidationDetail"
        },
        "description": "For validation errors (error code `VALIDATION_FAILED`), a map with the affected field as key and ValidationDetail\nas value.",
        "properties": {},
        "type": "object"
      },
      "sizeUnitsByCashAccountIdMap": {
        "additionalProperties": {
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "properties": {},
        "type": "object"
      }
    },
    "securitySchemes": {
      "clientId": {
        "description": "The brokerize clientId provided to API customers. The clientId defines which origins are allowed for CORS and which URLs may be used for OAuth redirects.",
        "in": "header",
        "name": "x-brkrz-client-id",
        "type": "apiKey"
      },
      "cookieAuth": {
        "description": "Requests are authenticated by providing an HTTP-Only cookie `_id` which is a JWT token stored in the browser by calling the `/login` endpoint. This allows clients to not have to care about authentication at all - it is provided by 3rd party cookies which are not visible to the frontend at all. However, this comes with limitations (e.g. some browsers do not send those cookies if they are under a 3rd party domain).",
        "in": "cookie",
        "name": "_id",
        "type": "apiKey"
      },
      "idToken": {
        "description": "Requests are authenticated by providing either a header `Authorization: Bearer <TOKEN>` or a header `x-access-token: <TOKEN>` where <TOKEN> is a token retrieved either from the `CreateGuestUser` endpoint or retrieved for a user from the amazon cognito pool, or a Personal Access Token created in the brokerize admin interface.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "contact": {},
    "description": "# brokerize API\n\nThe brokerize API allows clients to implement multi-brokerage with a unified interface. While our partner brokers have different feature sets and legal constraints, our abstractions make it easy to build a consistent trading experience for your users. We provide an accessible demo broker for development and quality assurance purposes that allows you to test the different behaviours without the need to log in to the actual brokers.\n\n# user accounts & temporary guest sessions\n\nEvery API request is executed on behalf of an end user interacting with your application.\nWe recommend calling the API **directly from the frontend**. This approach ensures that your backend never handles user access tokens or sensitive user data and your systems are not involved in sending orders to brokers.\nFor web applications, this typically requires a CORS configuration, which can be easily attached to your client configuration.\n\nIf you think that you need to call the API from your backend, please contact our support to discuss your use case and available options.\n\n## Guest user model\n\nAll end users access the API as **anonymous guest users**. A new guest user can be created using the `CreateGuestUser` endpoint.\n\nGuest users are temporary by default. Their expiration depends on the client configuration and is typically **around one day**. However:\n\n- Guest lifetimes can be automatically renewed while the user remains active.\n- Inactivity timeouts and maximum lifetimes are configurable.\n- Optimal settings depend on the client technology and application use case.\n\nThese parameters can be adjusted in collaboration with brokerize support.\n\n### Long-term guest user access\n\nRandomly generated `RecoveryPhrases` allow guest users to keep their data in the brokerize backend long-term without revealing their identity. Users can access their account anytime by entering their RecoveryPhrase.\n\n## Registered users\n\nRegistered user accounts (email-based) are supported **only** for certain administrative endpoints, such as client management or downloading order reports.\n\nThis functionality is out of scope for this documentation and is not required for most client applications.\n\n## UserAccessTokens\n\nWhile `RecoveryPhrases` are used to log in to an account on a new device or browser, `UserAccessTokens` provide fine-grained permissions (e.g. for automated tasks).\n\nThese tokens can be generated with specific permission sets and are ideal for scripts that:\n\n- Download reports automatically\n- Access portfolio data\n- Perform other automated user actions\n\n# connecting brokers and synchronizing data to brokerize\n\nUsers connect their brokerage accounts from either the official brokerize UI or from an app's interface using their broker credentials. To find out which brokers can be used for logging in, the [GetBrokers](#operation/GetBrokers) endpoint must be used. An end user can add a login by calling [AddSession](#operation/AddSession). Note that brokerize _never_ saves the login credentials, but only tokens / session ids that are issued by the brokers. Those are discarded as soon as the user logs out from the broker using [LogoutSession](#operation/LogoutSession).\n\nAs soon as users have connected one or more broker sessions, those sessions are synced into their user account. This means that the list of portfolios, positions and orders are stored in the brokerize database. All synchronized portfolios and their contents are accessible using the portfolio operations (e.g. [GetPortfolios](#operation/GetPortfolios), [GetPortfolioOrders](#operation/GetPortfolioOrders) etc.). Even after the user disconnects a session (or it times out at the broker etc.), the data remains available until actively deleted by the user ([DeletePortfolio](#operation/DeletePortfolio)). This means that users can easily look at the last known state of each portfolio without needing to log in. As soon as they log in again via [AddSession](#operation/AddSession), the data is updated again (i.e. the synchronized portfolio gets connected to an \"online session\" again).\n\nData is automatically synchronized in the background, but clients can also request a sync using [TriggerSessionSync](#operation/TriggerSessionSync).\n\n![](/docs/diagrams/session-lifecycle.svg)\n\n# performing actions in portfolios\n\nSee [GetAuthInfo](#operation/GetAuthInfo) to get an overview on the available operations like creation, change and cancellation of orders.\nFor an overview how the flow of the creation of a trade from start to finish looks, see the next section\n\n# trade flow\n\nThe following diagram tries to assist in unterstanding the flow that occurs, when a trade is performed. It shows an example of a trade flow. Details may vary depending the broker and connected requirements. For more in-depth information please have a look a look at the [GetAuthInfo](#operation/GetAuthInfo) section.\n\n![](/docs/diagrams-drawio/trade-flow.svg)\n\n# rate limits\n\nCurrently a rate limit of 100 requests per 10 seconds per client/userId combination is implemented for all endpoints. The `CreateGuestUser` endpoint is accessible without a token, so _for that endpoint_ an IP-based limiting (1 guest user creation per 10 seconds) is implemented. These rate limits are subject to change and will be refined in the future.\n\nClients should implement ways to deal with the http `429` status code and can inspect the `Retry-After` header to implement appropriate waiting behavior.\n\n# privileged clients with client secrets\n\nOur API is designed to be publicly accessible in order to be used directly from browsers and apps. However this comes with relatively strict rate limiting (for example) for the guest user creation.\n\nIf a client only calls the API from a secured backend, the limit may be increased.\n\nIn order to authenticate as a priviliged client, the header `x-brkrz-client-secret` must be added to requests (a client secret is provided manually in that case).\n\n# request ids\n\nThe brokerize backend assigns a requestId to each request and returns it in the `x-request-id` header. The ID can be used to research error details, so it may be displayed to the user in the case of unexpected errors. In the case of internal server errors, the id will also be part of the JSON body; for example:\n\n```\n{\n    \"message\": \"An internal server error occured.\",\n    \"requestId\": \"9KzqMpRvVrQHDkFo\"\n}\n```\n\n# tradable securities\n\nIn this API, all tradable securities are identified by their ISIN. However, some securities do not have an ISIN. In these cases, we however still use the ISIN field for some special values. Currently frontends should manually map the securities to their security database if suitable.\n\nThe following special values for ISIN are currently supported (of course, the actual availability depends on the specific broker implementations):\n\n| `ISIN`  | Description |\n| ------- | ----------- |\n| `BTC` | BTC/EUR |\n| `ETH` | ETH/EUR |\n| `LTC` | LTC/EUR |\n| `XRP` | XRP/EUR |\n| `BCH` | BCH/EUR |\n| `EOS` | EOS/EUR |\n| `LINK` | LINK/EUR |\n| `XLM` | XLM/EUR |\n| `DOT` | DOT/EUR |\n| `UNI` | UNI/EUR |\n| `DOGE` | DOGE/EUR |\n| `ETC` | ETC/EUR |\n| `ADA` | ADA/EUR |\n| `SOL` | SOL/EUR |\n| `AAVE` | AAVE/EUR |\n| `ALGO` | ALGO/EUR |\n| `CRV` | CRV/EUR |\n| `LUNA` | LUNA/EUR |\n| `MANA` | MANA/EUR |\n| `POL` | POL/EUR |\n| `XTZ` | XTZ/EUR |\n| `AVAX` | AVAX/EUR |\n| `ENJ` | ENJ/EUR |\n| `FTM` | FTM/EUR |\n| `LRC` | LRC/EUR |\n| `MKR` | MKR/EUR |\n| `NEAR` | NEAR/EUR |\n| `QNT` | QNT/EUR |\n| `GRT` | GRT/EUR |\n| `HBAR` | HBAR/EUR |\n| `BAT` | BAT/EUR |\n| `GNO` | GNO/EUR |\n| `S` | S/EUR |\n| `1INCH` | 1INCH/EUR |\n| `ANKR` | ANKR/EUR |\n| `APE` | APE/EUR |\n| `ARB` | ARB/EUR |\n| `ATOM` | ATOM/EUR |\n| `AXS` | AXS/EUR |\n| `BNB` | BNB/EUR |\n| `BNT` | BNT/EUR |\n| `CAKE` | CAKE/EUR |\n| `CHZ` | CHZ/EUR |\n| `COMP` | COMP/EUR |\n| `CRO` | CRO/EUR |\n| `CVC` | CVC/EUR |\n| `CVX` | CVX/EUR |\n| `GALA` | GALA/EUR |\n| `HNT` | HNT/EUR |\n| `IMX` | IMX/EUR |\n| `INJ` | INJ/EUR |\n| `KSM` | KSM/EUR |\n| `LDO` | LDO/EUR |\n| `NMR` | NMR/EUR |\n| `ONDO` | ONDO/EUR |\n| `OP` | OP/EUR |\n| `POWR` | POWR/EUR |\n| `PYTH` | PYTH/EUR |\n| `REQ` | REQ/EUR |\n| `RUNE` | RUNE/EUR |\n| `SAND` | SAND/EUR |\n| `SNX` | SNX/EUR |\n| `STORJ` | STORJ/EUR |\n| `SUI` | SUI/EUR |\n| `SUSHI` | SUSHI/EUR |\n| `TON` | TON/EUR |\n| `TRX` | TRX/EUR |\n| `WOO` | WOO/EUR |\n| `YFI` | YFI/EUR |\n| `ZRX` | ZRX/EUR |\n",
    "title": "brokerize",
    "version": "1.8.0"
  },
  "openapi": "3.0.0",
  "paths": {
    "/admin/client": {
      "post": {
        "description": "Create an API client.",
        "operationId": "CreateClient",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": ["name", "id"],
                  "type": "object"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/client/{clientId}": {
      "delete": {
        "description": "Delete the given client permanently.",
        "operationId": "DeleteClient",
        "parameters": [
          {
            "in": "path",
            "name": "clientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/clients": {
      "get": {
        "description": "List all clients that the current user may administrate.",
        "operationId": "GetMyClients",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientsResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/clients/{clientId}/config": {
      "post": {
        "description": "Replace the client configuration. Keys that are not provided will not be changed.",
        "operationId": "SetClientConfig",
        "parameters": [
          {
            "in": "path",
            "name": "clientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "config": {
                    "$ref": "#/components/schemas/ClientConfigUpdate"
                  }
                },
                "required": ["config"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/clients/{clientId}/oauthReturnTo": {
      "post": {
        "description": "Add an OAuth return to URL to the client config.",
        "operationId": "AddOAuthReturnToUrl",
        "parameters": [
          {
            "in": "path",
            "name": "clientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "url": {
                    "type": "string"
                  }
                },
                "required": ["url"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/clients/{clientId}/origin": {
      "post": {
        "description": "Add an allowed CORS origin to the client config.",
        "operationId": "AddOrigin",
        "parameters": [
          {
            "in": "path",
            "name": "clientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "origin": {
                    "type": "string"
                  }
                },
                "required": ["origin"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/clients/{clientId}/removeOAuthReturnTo": {
      "post": {
        "description": "Remove an OAuth return to URL from the client config.",
        "operationId": "RemoveOAuthReturnToUrl",
        "parameters": [
          {
            "in": "path",
            "name": "clientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "url": {
                    "type": "string"
                  }
                },
                "required": ["url"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/clients/{clientId}/removeOrigin": {
      "post": {
        "description": "Remove an allowed CORS origin from the client config.",
        "operationId": "RemoveOrigin",
        "parameters": [
          {
            "in": "path",
            "name": "clientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "origin": {
                    "type": "string"
                  }
                },
                "required": ["origin"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/admin/orderReport": {
      "get": {
        "description": "Get an order report for a client.",
        "operationId": "GetOrderReport",
        "parameters": [
          {
            "description": "Date filter: if `onlyExecutedOrders` is true, this refers to the date of execution. Otherwise the date of order creation.",
            "in": "query",
            "name": "from",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Date filter: if `onlyExecutedOrders` is true, this refers to the date of execution. Otherwise the date of order creation.",
            "in": "query",
            "name": "to",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated list of client ids to include in the report. Defaults to all clients that the user has management access to.",
            "in": "query",
            "name": "clientIds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "File format of the report. Defaults to be figured out from the \"Accept\" request header. If no supported format can be detected, `'csv'` is the default.\n*Attention*: the `json` format is *currently in beta*. We may change the output format in the future.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "enum": ["csv", "xlsx", "json"],
              "type": "string"
            }
          },
          {
            "description": "If this is true, the report will only contain executed orders.",
            "in": "query",
            "name": "onlyExecutedOrders",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "If this is true, the report will *NOT* be rendered with file download headers. This may be useful when working with the reports in scripts.",
            "in": "query",
            "name": "noDownload",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "format": "byte",
                  "type": "string"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["admin"]
      }
    },
    "/brokers": {
      "get": {
        "description": "List all brokers that users can log in to. Describes *how* to login by specifying either a `loginForm` or some other means\nof login (e.g. the brokers' OAuth process in the future). The `loginForm` field is only available for a small combination\nof brokers and clients and is not guaranteed to be present.",
        "operationId": "GetBrokers",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "brokers": [
                        {
                          "brokerName": "demo",
                          "displayName": "Demobroker",
                          "envLabel": "Environment",
                          "envs": [
                            {
                              "id": "test",
                              "isTestingEnvironment": true,
                              "label": "A test environment"
                            }
                          ],
                          "features": {
                            "supportedOrderStatuses": [
                              "open",
                              "open_executed",
                              "executed",
                              "canceled",
                              "canceled_executed"
                            ]
                          },
                          "images": {
                            "dark": "https://example.com/dark.svg",
                            "darkSquare": "https://example.com/dark_square.png",
                            "light": "https://example.com/light.svg",
                            "lightSquare": "https://example.com/light_square.png"
                          },
                          "loginForm": {
                            "passwordField": {
                              "label": "Password",
                              "type": "password"
                            },
                            "usernameField": {
                              "label": "Account name",
                              "type": "string"
                            }
                          },
                          "supportsOAuthLogin": true
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/GetBrokersResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": []
          }
        ],
        "tags": ["meta"]
      }
    },
    "/decoupledOperations/{decoupledOperationId}": {
      "delete": {
        "operationId": "CancelDecoupledOperation",
        "parameters": [
          {
            "in": "path",
            "name": "decoupledOperationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Bad Request."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Session not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Session not found."
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["decoupledOperations"]
      },
      "get": {
        "operationId": "GetDecoupledOperationStatus",
        "parameters": [
          {
            "in": "path",
            "name": "decoupledOperationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecoupledOperationStatus"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "getDecoupledOperation called with wrong parameters"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["decoupledOperations"]
      }
    },
    "/demo/accounts": {
      "get": {
        "description": "List all demo accounts that the user has in her account. The account name can be used as the login username in the\ndemo broker login process.",
        "operationId": "GetDemoAccounts",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DemoAccountsResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["demobroker"]
      },
      "post": {
        "description": "Create an account at the demo broker for the logged-in user. The account will have a default\nset of two empty portfolios by default. If the setting `isSinglePortfolio` is set, only one portfolio\nis created.\n\nThe account as well as the two portfolios have a randomly generated name.\n\nTo log into an account, use the account's generated name as username (Account name) in `AddSession`.\n- with the password `42`, the login will succeed immediately\n- with the password `1337`, a challenge with type text will be returned which must be completed by using `addSessionCompleteChallenge` (with a challengeResponse `42`)\n- with the password `7`, a challenge with type base64png will be returned which must be completed by using `addSessionCompleteChallenge` (with a challengeResponse `42`)\n- other passwords will not allow to log in\n\nThe demo broker implements the following pre-defined trade behaviors, so that different flows can be tested:\n- ISIN US0378331005 (Apple):\n  - market buy order is executed after 10 seconds by the backend at a random quote\n  - stop buy or stop loss order stays open forever (can be used for testing cancellation)\n  - cost estimations contain a `costDetailsLink` and a `costAcceptancePrompt`\n  - securityDetailedInfo is set, so a \"KID\" link should be displayed and linked to the corresponding table\n  - the preparedTrade's `costEstimationMustBeShown` is true, so that the correct behavior (users cannot skip cost estimation in that case) can be tested.\n- ISIN LU0378438732 (a DAX ETF)\n  - preparedTrade has `costEstimationIsOnlyDetailedTable` set to true, so that deviating order form behaviors can be tested\n  - orders are rejected with code `ORDER_REJECTED` immediately\n- ISIN LU2611732046 (a DAX ETF)\n  - preparedTrade has `costEstimationIsOnlyDetailedTable` set to true, so that deviating order form behaviors can be tested\n  - two exchanges are available (\"xetra\" and \"quoteExchange\")\n  - xetra allows market and limit orders for buying and has defaultValidityByOrderModel set to GFD for market and GTD 2030-01-01 for limit\n  - orders are rejected with code `ORDER_REJECTED` immediately\n- ISIN DE000MD96WE8 (a knock out with DAX as underlying)\n  - prepareTrade is rejected with a message that the user may not trade risky derivatives.\n- ISIN DE000DTR0CK8 (Daimler Truck Holding)\n  - prepareTrade is rejected with a message that the user may not trade risky derivatives.\n- ISIN US4180561072 (Hasbro)\n  - only quote orders on one exchange are supported\n  - the quotes are valid for 45 seconds\n  - quote value is always `42`\n  - the order gets executed immediately\n- ISIN DE0005557508 (Deutsche Telekom)\n  - only quote orders on two different exchanges are supported\n  - the quotes do *NOT* have an expiration\n  - quote value is always `42`\n  - quote comes together with a costEstimation. Subsequent getCostEstimation calls are not allowed.\n  - `noExchangeDefault` is true, so that exchange must be selected by the user\n  - order will be canceled after 3 seconds\n- ISIN US98980L1017 (Zoom)\n  - only market orders (both buy and sell) are suppored on one exchange\n  - orders are executed immediately at a random quote\n  - order creation requires the user to accept a hint (i.e. first try will result in a `MUST_ACCEPT_HINT` error)\n  - default validity is set to `GTD` with a date of `2030-01-01`\n- ISIN US29786A1060 (Etsy)\n  - the prepareTrade request takes 5 seconds\n  - create challenge takes 5 seconds. for authMethod photoTAN, the challenge will return with an error after that period of time\n  - only quote and market orders allowed\n  - at exchange \"Slow exchange\" it takes 7 seconds to get a quote as well as 7 seconds to retrieve order costs\n  - at exchange \"Exchange with quote and cost errors\" the quote request as well as cost estimation will end with an error after 3 seconds\n  - the preparedTrade's `costEstimationMustBeShown` is true, so that the correct behavior (users cannot skip cost estimation in that case) can be tested.\n- ISIN XS2149280948 (bond from Bertelsmann)\n  - quote, limit and market orders (both buy and sell) are supported on one exchange\n  - limit orders are executed at exactly the limit price\n  - market orders are executed at a random quote between 90 and 150 percent\n  - for market orders, there is a legal message to confirm set (`legalMessagesToConfirmByOrderModel`)\n- ISIN US64110L1061 (Netflix Inc.)\n  - one exchange with only quote order\n  - creating the quote order will return an error (quote expired)\n - ISIN US67066G1040 (NVIDIA)\n   - one exchange with only quote order, allowsQuoteModeLimit=true\n   - quote orders are executed immediately.\n     - if a quoteLimit is provided, execution happen at quoteLimit value\n     - otherwise, a random execution quote will be used\n- ISIN DE000BAY0017 (Bayer AG)\n  - one exchange with only market order\n  - `costEstimationIsNotAvailable` is true, so no cost estimations should be linked/shown\n  - orders will be canceled after 3 seconds\n- ISIN DE000PAH0038 (Porsche)\n  - one exchange with only market order\n  - all orders will be canceled\n  - `GetCostEstimation` contains (only) a link to a PDF document. This can be used to test whether linking to a PDF works.\n  - the instrument has both a `riskClassInfo.legalHint` as well as a `strikingHint`. Both should be visible in the order form.\n- ISIN DE0008404005 (Allianz) and some other hidden ISINs (can be requested from brokerize support)\n  - one exchange with all available orderModels\n  - orders are executed immediately\n  - limit orders are executed at exactly the provided limit price\n- ISIN DE0008430026 (Munich Re)\n  - one exchange (L&S) with all available orderModels\n  - orders are executed immediately\n- ISIN FR0000120321 (L'Oréal)\n  - one exchange with all available orderModels\n  - the exchange has a `securityQuotesToken` set\n  - orders stay open\n  - changesHaveCostEstimations is `true` for orders with this ISIN\n- ISIN US5949181045 (Microsoft)\n  - one exchange with all available orderModels\n  - if size is even, a partial execution with size 1 is executed, the remaining part stays open\n  - if size is odd, a partial execution with size 1 is executed, the remaining part is canceled\n- ISIN US30303M1027 (Meta)\n  - one exchange with all available orderModels\n  - for each piece of the order size, there will be one execution with size 1 (so e.g. 10 executions for size 10)\n  - sizes > 30 are not accepted\n- ISIN US2546871060 (Disney)\n  - one exchange with all available orderModels\n  - all orders are canceled after 3s\n  - `costEstimationMustBeShown` is false and `costEstimationIsOnlyDetailedTable` is true (frontends must only show a link to the cost estimation table)\n- ISIN XX1234567890 (example of an ISIN that can never be mapped by frontends)\n  - one exchange with all available orderModels\n  - the instrument has two sellPositions to choose from (\"Sell Position A\" and \"Sell Position B\"). If no correct sell position is provided, trades will be rejected.\n  - orders are executed immediately\n- ISIN DE0007100000 (Mercedes-Benz)\n  - one exchange with all available orderModels\n  - the instrument has two sellPositions to choose from (\"Sell Position A\" and \"Sell Position B\"). If no correct sell position is provided, trades will be rejected.\n  - orders are executed immediately\n- ISIN DE0007472060 (Wirecard)\n  - test instrument for `empty orderModelsBuy` / `onlySellAllowed`\n- ISIN BTC (Bitcoin/Euro)\n  - has one exchange with support for quote, market and limit orders\n  - orders will be executed right away (with the exception of limit orders with the limit 42. Those stay open!)\n  - can be used to test frontend mapping of cryptos\n  - when you prepare a trade in the *second* portfolio (which has two cash accounts), `sizeUnitsByCashAccountId` will be set, so that the frontend can let the user select a combination of `cashAccount` and `sizeUnit`.\n  - positions of BTC/EUR will always have sizeDecimals=8\n- ISIN DE0006231004 (Infineon Technologies AG)\n  - one exchange with `orderModelsSell=['market']` and `orderModelsBuy=[]`\n- ISIN DE0005552004 (Deutsche Post AG)\n  - one exchange with `orderModelsSell=[]` and `orderModelsBuy=['market']`\n  - market buy orders are executed immediately\n  - positions of DE0005552004 will always have sizeDecimals=undefined\n- ISIN US8740541094 (Take Two)\n  - three exchanges are available. all have `market` and `limit` available\n  - configuration for `takeProfitStopLoss` is different for the three exchanges. This can be used to test the implementation of takeProfit/stopLoss creation.\n    - exchange_with_exclusive_tp_sl: `takeProfitStopLoss.exclusive` is `true`, so that only one of the two can be set. Also, both fields are limited to market buy orders\n    - exchange_with_unlimited_tp_sl: `takeProfitStopLoss.exclusive` is `false`, so that both tp and sl may be set, for both sell and buy orders and both support orderModels\n    - exchange_without_tp_sl: `takeProfitStopLoss` is not set, so that no tp/sl can be set\n  - orders stay open forever\n  - the order size can be changed (`allowsChangeSize=true`)\n- ISIN US5529531015 (MGM Resorts International)\n  - one exchange with market and limit orders\n  - orders are executed immediately\n  - short selling is allowed, so `availableOrderIntents` as well as `availableOrderIntentsToken` is set. \"sell to open\" and \"buy to close\" can be tested here.\n- ISIN XAU (Gold)\n  - only quote trading is allowed\n  - depending on the selected portfolio, it is possible to select a cash account (e.g. EUR or USD) to trade with\n  - users can chose between specifying the order size in the cash currency or in grams\n  - quotes have the `totalAmount` field set\n- ISIN US88160R1014 (Tesla)\n  - market, limit, stop buy trading is allowed\n  - `GetCostEstimation` returns order fees\n  - orders will be executed\n  - order fees are saved for the order and returned in the order receipt\n- `CryptoPair` ADA-USD (Cardano - US Dollar)\n  - `quote`, `market`, `limit` order models are available\n  - One of the created demobroker portfolios does not have an USD cash account. For this portfolio an error will appear upon opening the order form\n  - users can chose between specifying the order size in the cash currency (USD) or in ADA\n  - validity types for limit orders are [`IOC`, `GTDT`]. With `GTDT` the user can specify a date AND time at which his order should be executed\n  - the size input decimal places are limited per sizeUnit. For USD it's 2 and for ADA it is 4 decimal places\n  - the orders will be executed after 10 seconds\n- ISIN US23804L1035 (Datadog Inc.)\n  - only  quote orders are available\n  - in 80% of `CreateTrade` calls, a 400 error with the code `QUOTE_REJECTED_RETRYABLE` is returned. This can be used to test UIs which automatically retry `GetQuote` in this case.\n- ISIN DE0006969603 (Puma SE)\n  - one exchange with all orderModels\n  - orders stay open forever\n  - `allowsChangeValidityTypes` is empty, so it is not possible to change the order validity\n  - `changesHaveCostEstimations=false`, so it is not possible to receive cost estimations for order changes)\n- all other orders will be canceled after 3 seconds\n\nWhen orders are created using a `decoupled` method, the order id is only returned if the order size is greater than `5`. This can\nbe used to test if the order receipt is skipped correctly in UIs.\n\nCost estimations for `buy` and `sell` return a different set of fields. This can be used to test proper UI behavior when fields\nare set or unavailable.\n\nBehavior of `PortfolioQuotes` in the demo broker:\n- portfolio 1 starts with 100.000€ cash. portfolio 2 has two cash accounts, one starts with 100.000€, one with 100.000$.\n- when cash account values are summed up, we just assume an exchange rate of 1:1\n- each open buy order reserves 10€ cash from the availableCash\n- profit loss of the portfolio is the sum of the position's profit loss\n- if a EUR cashAccount has the value 0,00€, its `hideInOverviews` property is set to true. This can be used to test the frontend's behavior when a cash account is hidden.",
        "operationId": "CreateDemoAccount",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DemoAccountSettings"
              }
            }
          },
          "required": false
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "id": 42
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/CreatedResponseBody"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["demobroker"]
      }
    },
    "/demo/accounts/{accountId}": {
      "delete": {
        "description": "Delete the given demo account and all data (demo portfolios and the related orders) *permanently*.",
        "operationId": "DeleteDemoAccount",
        "parameters": [
          {
            "in": "path",
            "name": "accountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "msg": "ok"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/OkResponseBody"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["demobroker"]
      }
    },
    "/exchanges": {
      "get": {
        "description": "List all exchanges mapped in brokerize.\n\nBrokers provide their own list of exchanges with any order preparation request, so there\nmay be cases where a broker exchange is not mapped to this brokerize exchange list. This is\ntotally valid: this list serves as a known subset of exchanges to facilitate switching between\nbrokers or mapping to your own exchange database.",
        "operationId": "GetExchanges",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "exchanges": [
                        {
                          "id": 1,
                          "name": "München"
                        },
                        {
                          "id": 2,
                          "name": "XETRA"
                        },
                        {
                          "id": 3,
                          "name": "NYSE"
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ExchangesResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": []
          }
        ],
        "tags": ["meta"]
      }
    },
    "/export/renderGenericTable": {
      "post": {
        "description": "Render a `GenericTable`, as retrievable from other endpoints.\nBy default, this will return a PDF download. If the header `Accept` is set to `text/html`, output will\nbe an HTML document.",
        "operationId": "RenderGenericTable",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderGenericTableParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/pdf": {
                "schema": {
                  "format": "byte",
                  "type": "string"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["export"]
      }
    },
    "/legalTerms": {
      "get": {
        "description": "Get the legal terms that the user has to accept before logging in to any broker.",
        "operationId": "GetLegalTerms",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "checkboxesHtml": [
                        "Checkbox 1: Some HTML (possibly with <a href=\"https://brokerize.com\">links</a>) that the user",
                        "Checkbox 2: Another box to check for the user"
                      ],
                      "confirmItems": [
                        {
                          "html": "Checkbox 1: Some HTML (possibly with <a href=\"https://brokerize.com\">links</a>) that the user",
                          "id": "agb"
                        },
                        {
                          "html": "Checkbox 2: Another box to check for the user",
                          "id": "europeanUnion"
                        }
                      ],
                      "disclaimerHtml": "A possibly long disclaimer text that explains the legal terms of<br/><br/> trading with brokerize. It may contain some HTML markup (<br> tags, <a> tags)"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/LegalTermsResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["meta"]
      }
    },
    "/order/{id}": {
      "get": {
        "operationId": "GetOrder",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetOrderResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["order"]
      }
    },
    "/order/{id}/cancel": {
      "post": {
        "description": "Cancel the given order (or in the case of decoupled authMethods: send the order cancellation to the user for\nconfirmation. In this case, a decoupledOperationId is returned).",
        "operationId": "CancelOrder",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancelOrderParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelOrderResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "no logged in session available for portfolio"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for order portfolio"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["order"]
      }
    },
    "/order/{id}/cancelChallenge": {
      "post": {
        "description": "If the user chose an auth method from `GetAuthInfo` with the flow `CHALLENGE_RESPONSE`, before\ncancelling an order, a challenge must be requested first. If any other flow is used, a challenge\n*must not* be requested and `CancelOrder` is used right away.",
        "operationId": "CreateCancelOrderChallenge",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancelOrderChallengeParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "challengeExplanation": "We send SMS messages with codes as a second authentication factor.",
                      "challengeId": "ttG0q1dLlzxAFqxO",
                      "challengePrompt": "Please enter the code we just sent you.",
                      "challengePromptType": "text"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Challenge"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "no logged in session available for portfolio"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for order portfolio"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["order"]
      }
    },
    "/order/{id}/change": {
      "post": {
        "description": "Perform an order change.",
        "operationId": "ChangeOrder",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeOrderParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeOrderResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "no logged in session available for portfolio"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for order portfolio"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["order"]
      }
    },
    "/order/{id}/changeChallenge": {
      "post": {
        "description": "If the user chose an auth method from `GetAuthInfo` with the flow `CHALLENGE_RESPONSE`, before\nchanging an order, a challenge must be requested first. If any other flow is used, a challenge\n*must not* be requested and `ChangeOrder` is used right away.",
        "operationId": "CreateChangeOrderChallenge",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeOrderChallengeParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Challenge"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "no logged in session available for portfolio"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for order portfolio"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["order"]
      }
    },
    "/order/{id}/changeCostEstimation": {
      "post": {
        "description": "Get an order cost estimation for an order change.",
        "operationId": "GetChangeOrderCostEstimation",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateChangeOrderCostsParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCostEstimation"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "no logged in session available for portfolio"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for order portfolio"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["order"]
      }
    },
    "/pages": {
      "get": {
        "description": "Get the matching brokerize pages configuration.\n\nThe endpoint will try to find a matching configuration in this order:\n- if parameter `clientId` is given: load the pages configuration for the given client id\n- if parameter `clientName` is given: load the pages configuration for the given client name\n- if neither parameter is provided, the requests `origin` will be used to find the configuration.",
        "operationId": "GetPagesConfiguration",
        "parameters": [
          {
            "in": "query",
            "name": "clientId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "clientName",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "clientId": "abcdefghijkl",
                      "page": {
                        "banner": {
                          "logoDark": "https://example.com/logo_dark.svg",
                          "logoLight": "https://example.com/logo_light.svg",
                          "text": "The stock millionaire"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/PagesConfigurationResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [],
        "tags": ["meta"]
      }
    },
    "/portfolios": {
      "get": {
        "operationId": "GetPortfolios",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortfoliosResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}": {
      "delete": {
        "operationId": "DeletePortfolio",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponseBody"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/authinfo": {
      "get": {
        "description": "Get the AuthInfo for the given portfolio.\n\nIf the portfolio does not have an online session, this will return a 400 status code.\n\nIf it does, the response describes whether session TAN is available or active and which auth methods are available for the given portfolio\n(this information depends on the broker and the user's account settings).\n\nThe response determines which of the following operations can be used and which are required to successfully perform an\noperation in a portfolio:\n\n-   Session TAN handling (for performing other actions in portfolios without further per-case authorization)\n    -   [CreateSessionTanChallenge](#operation/CreateSessionTanChallenge) to request a challenge for s TAN activation.\n    -   [EnableSessionTan](#operation/EnableSessionTan) to enable the session TAN.\n    -   [EndSessionTan](#operation/EndSessionTan) to end the session TAN.\n-   Create a trade\n    -   [PrepareTrade](#operation/PrepareTrade) to figure out how a given security can be traded in a portfolio.\n    -   [CreateTradeChallenge](#operation/CreateTradeChallenge) to (for example) request a TAN for a trade.\n    -   [CreateTrade](#operation/CreateTrade) to perform the trade.\n-   Edit an order\n    -   [CreateChangeOrderChallenge](#operation/CreateChangeOrderChallenge) to request a challenge for an order change.\n    -   [ChangeOrder](#operation/ChangeOrder) to change an order.\n-   Cancel an order\n    -   [CreateCancelOrderChallenge](#operation/CreateCancelOrderChallenge) to request a Challenge for an order cancellation.\n    -   [CancelOrder](#operation/CancelOrder) to cancel an order.\n\nThe list of available AuthMethods should only be presented to the user if session TAN is not active (yet). The list and names are defined by our partner brokers.\nAll auth methods are generally categorized using the `flow` attribute:\n\n| `flow`               | requires challenge? | Description                                                                                                                                                                                                          |\n| -------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `TAN`                | no                  | the simplest flow: no challenge is required to perform the operation. the TAN is simply sent as parameter `tan`                                                                              |\n| `CHALLENGE_RESPONSE` | yes                 | a challenge must be created using the `createXYZChallenge` operations and the challenge must be presented to the user. The user can then execute the action using the `challengeId` and `challengeResponse` parameters. If the auth method has `challengeResponseIsOnlyConfirmation=true`, that challengeResponse is always an empty string and users do not enter a TAN. Otherwise, a text field labelled with `tanFieldLabel` must be displayed where the user enteirs their challengeResponse. |\n| `DECOUPLED`          | no                  | the operation is executed without any TAN, but returns a `decoupledOperationId` which can be used to read the action's status. Users will authorize the action in another frontend (usually in their broker's app). Note that currently `DECOUPLED` auth methods only work for enabling session TAN.   |\n\n- If `sessionTanActive` is `true`: Session TAN has been enabled for the session that\ncurrently backs the portfolio. In this case, all operations like `CreateTrade` can be executed right away\nwithout an `authMethod`. The UI should *not* show a dropdown with the auth methods in this case.\n- If `sessionTanActive` is `false` but `sessionTanSupported` is `true`: the user can enable session TAN\nusing `CreateSessionTanChallenge` / `EnableSessionTan`.\n- If `allOperationsRequireSessionTan` is `true`, the auth methods can *ONLY* be used for enabling session TAN.\n- Otherwise, the `authMethods` can be used to perform individual operations.\n\n| sessionTanActive | sessionTanSupported | allOperationsRequireSessionTan | Description                                                                                                                                                                                                                                                 |\n| ---------------- | ------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `true`           | `true`              | -                              | Session TAN has been enabled for the session that currently backs the portfolio. In this case, all operations like `CreateTrade`, `ChangeOrder`, `CancelOrder` can be executed right away without an `authMethod`. The UI should _not_ show a dropdown with the auth methods in this case. |\n| `false`          | `true`              | `true`                         | the user can enable session TAN using the provided auth methods via `CreateSessionTanChallenge` / `EnableSessionTan`. All other operations can only take place after session TAN has been enabled.                                                          |\n| `false`          | `true`              | `false`                        | the user can enable any operation (enable session tan, create trade, cancel order, change order) using the provided auth methods                                                                                                                            |\n\nNote that it is possible that brokers only reveal all details about the available auth methods *TOGETHER* with the first `GetChallenge` request. This special behavior\ncan be simulated with our demo broker when the flag `lazyAuthMethods=true` is specified upon creation of a demo account. In those accounts, the\n`GetAuthInfo` endpoint will initially return a single \"placeholder\" method with `{flow: \"CHALLENGE_RESPONSE\", isDefaultMethod: true, ...}`.\n\nIn the situation where there is *exactly one* auth method like this, frontends may immediately request the challenge for the desired operation\nwithout waiting for the user to click the get challenge button (for Session TAN, this means that as soon as the user opens the dialog for enabling session\nTAN, `CreateSessionTanChallenge` can be called). In the case described here, `AuthInfo` will be populated with the actual list of auth methods when\nthe create challenge request returns (also, the corresponding WebSocket event is published to notify about this change). `GetAuthInfo` must be called again\nin this case and repopulate the corresponding frontend (e.g. the name of the auth method will become available etc.). So what is done in this case is:\nrequest a challenge for the *unknown* default method in order to get both a challenge and an update of the auth methods.\n\nNote that usually challenges have effects like an SMS or some broker app notification for the\nend user, so it is important to keep the requested challenge info, *even when auth info is refreshed*. For example, if there is a select box with\nthe auth method list, that box must keep its selected `id` while updating the now-available `label`. This way, the user can use the first requested challenge,\nas the frontend will still be in the right state.",
        "operationId": "GetAuthInfo",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetAuthInfoResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/calendar": {
      "get": {
        "description": "Retrieve \"by-day\" aggregated values for the selected date ranges.",
        "operationId": "GetPortfolioCalendar",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated date ranges to summarize. A trade is considered to be in a date range by its closing date.\nOne range is denoted in the form `YYYY-MM-DD-YYYY-MM-DD`.",
            "in": "query",
            "name": "dateRanges",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPortfolioCalendarResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/orders": {
      "get": {
        "operationId": "GetPortfolioOrders",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "for pagination: how many items per page (maximum allowed values is 100)",
            "in": "query",
            "name": "take",
            "required": false,
            "schema": {
              "default": 10,
              "format": "int32",
              "type": "integer"
            }
          },
          {
            "description": "for pagination: how many items to skip (0 for first page)",
            "in": "query",
            "name": "skip",
            "required": false,
            "schema": {
              "default": 0,
              "format": "int32",
              "type": "integer"
            }
          },
          {
            "description": "fulltext search query. This usually searches for ISIN and security name or other symbols, depending on the broker.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "filter by statuses (comma-separated)",
            "in": "query",
            "name": "statuses",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "order by `<field>:<asc|desc>`, where `field` may be one of `createdAt`, `executedAt`",
            "in": "query",
            "name": "orderBy",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "filter by isin",
            "in": "query",
            "name": "isin",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "wkn",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "sinoTicker",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "usTicker",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "cryptoCode",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPortfolioOrdersResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/positions": {
      "get": {
        "operationId": "GetPortfolioPositions",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPortfolioPositionsResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/quotes": {
      "get": {
        "operationId": "GetPortfolioQuotes",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPortfolioQuotesResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/rename": {
      "post": {
        "description": "This endpoint can be used to rename the display name of a specified portfolio.\nTo restore the original portfolio name, send a rename request with an empty string as the new name.\n**Note**: This does not change the original portfolio name at your broker.",
        "operationId": "RenamePortfolio",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "newPortfolioName": {
                    "type": "string"
                  }
                },
                "required": ["newPortfolioName"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/trades": {
      "get": {
        "description": "Load a list of completed trades in a portfolio. A completed trade corresponds to *one* closing of a position.\nTechnically each closing of a position corresponds to one execution of an order with `intent=close` (usually those\nare sell orders, but in the case of short selling, opening a position is a sell order with intent=open).\n\nThe analysis follows the FIFO (First In, First Out) principle to accurately summarize trades. Each time a position is closed\n(note that partial executions are possible. In this case, each individual execution is regarded as a transaction),\nthe system identifies the earliest corresponding \"open position execution\" that contributed to that closing. The result includes\na single entry for each closing transaction, detailing key metrics such as profit/loss and holding period, based on the matched opening transactions.\n\nThis could be a real world example:\n- 2020-01-01: buy 5 stock1 for 100 USD each\n- 2021-06-01: buy 3 stock1 for 200 USD each\n- 2021-06-06: sell 6 stock1 for 300 USD each\n\nIn this case, the result would be one completed trade (corresponding to the last sell) with a profit of `(300*6)-(100*5+1*200)=1800-700=1100 USD`.\nThere is an open position remaining (2 units of stock1, which correspond to the second buy transaction).\n\nWhen we add this sell:\n- 2021-06-07: sell 2 stock1 for 400 USD each\n\nIt would add a second complete trade with a profit of `(400*2)-(200*2)=800-400=400 USD`.\n\nFor some brokers, the order history may be incomplete (e.g. only reveals the latest 90 days), so that we do not know if there could be older transactions.\nThus, our implementation might detect (given the current set of open positions together with the list of order executions) that we cannot figure out\nthe corresponding opening transactions for a closing transaction. Affected trades will be ignored for this analysis and might appear as warning items in the\n`/warnings` endpoint. Frontends should show those warnings so that users can understand why the analysis is incomplete.",
        "operationId": "GetPortfolioTrades",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "fulltext search query. This usually searches for ISIN and security name or other symbols, depending on the broker.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "for pagination: how many items per page. Maximum allowed value is 100.",
            "in": "query",
            "name": "take",
            "required": false,
            "schema": {
              "default": 10,
              "format": "int32",
              "type": "integer"
            }
          },
          {
            "description": "for pagination: how many items to skip (0 for first page)",
            "in": "query",
            "name": "skip",
            "required": false,
            "schema": {
              "default": 0,
              "format": "int32",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPortfolioTradesResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/trades/statistics": {
      "get": {
        "description": "Load statistics based on the trade list for selected date ranges. The statistics (such as `longestWinningStreak` or `tradeCount`) are\ncomputed for each of the requested date ranges.",
        "operationId": "GetPortfolioTradeStatistics",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated date ranges to summarize. A trade is considered to be in a date range by its closing date.\nOne range is denoted in the form `YYYY-MM-DD-YYYY-MM-DD`.",
            "in": "query",
            "name": "dateRanges",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPortfolioTradeStatisticsResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/portfolios/{portfolioId}/trades/warnings": {
      "get": {
        "operationId": "GetPortfolioTradeWarnings",
        "parameters": [
          {
            "in": "path",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/TradeWarning"
                  },
                  "type": "array"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "PORTFOLIO_NOT_FOUND",
                      "msg": "Portfolio not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Portfolio not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["portfolio"]
      }
    },
    "/securities/quotes/{securityQuotesToken}": {
      "get": {
        "description": "Load the current quotes for the given `securityQuotesToken` (provided by `PreparedTrade`).\nCurrently, polling this endpoint is the only way to get the current quotes. A polling interval of 2500 milliseconds\nis recommended and it counts towards the general rate limit.",
        "operationId": "GetSecurityQuotes",
        "parameters": [
          {
            "in": "path",
            "name": "securityQuotesToken",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "quotes": {
                        "ask": {
                          "value": 101
                        },
                        "bid": {
                          "timestamp": 1708961975019,
                          "value": 100
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/SecurityQuotesResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NOT_FOUND",
                      "msg": "Security quote was not found"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["securities"]
      }
    },
    "/securities/quotes/{securityQuotesToken}/meta": {
      "get": {
        "description": "Load metadata about the given securityQuotesToken. This includes the currency, decimals and the quote source name.",
        "operationId": "GetSecurityQuotesMeta",
        "parameters": [
          {
            "in": "path",
            "name": "securityQuotesToken",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "currency": "EUR",
                      "decimals": 3,
                      "quoteSourceName": "Best of all exchanges"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/SecurityQuotesMeta"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NOT_FOUND",
                      "msg": "Security quote was not found"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["securities"]
      }
    },
    "/sessions": {
      "get": {
        "description": "Get the currently active broker sessions of the user's account.",
        "operationId": "GetSessions",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      },
      "post": {
        "operationId": "AddSession",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddSessionParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "complete login": {
                    "value": {
                      "sessionId": "gxN0gSA0h0jTZ6Yy",
                      "state": "ready"
                    }
                  },
                  "incomplete login": {
                    "value": {
                      "challenge": {
                        "challengeExplanation": "We send SMS messages with codes as a second authentication factor.",
                        "challengeId": "ttG0q1dLlzxAFqxO",
                        "challengePrompt": "Please enter the code we just sent you.",
                        "challengePromptType": "text"
                      },
                      "state": "challenge"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/LoginResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "OAuth Ticket does not have a valid state."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Wrong credentials"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Wrong credentials"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/completeLogin": {
      "post": {
        "description": "If login returns the state `challenge`, the login must be completed by providing a challenge response first.",
        "operationId": "AddSessionCompleteChallenge",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddSessionCompleteChallengeParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResponseReady"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Broker does not support OAuth"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Challenge not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Challenge not found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/confirmOAuth": {
      "post": {
        "description": "For brokers with OAuth login processes, this adds the session to the user's account after redirects happen. Only the user that is redirected from\nthe broker login in the browser will receive the `code`. This step ensures that the logged-in user at brokerize is actually the one that\nhas gone through the broker OAuth steps.",
        "operationId": "ConfirmOAuth",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmOAuthParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "sessionId": "Aqh3ecket4ae6NiV"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ConfirmOAuthResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "OAuth Ticket does not have a valid state."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/prepareOAuthRedirect": {
      "post": {
        "description": "For brokers with `isOAuth`, sessions can not be created using `AddSession`. This is how a session\ncan be added for an OAuth-based login process:\n\n1. use `prepareOAuthRedirect` to obtain a URL to redirect to. You can provide a `returnTo` URL which will be redirected to later. Note that a list of allowed URLs has to be configured for the client.\n2. redirect the user's browser to the `redirectTo` URL\n3. after the user has logged in at the broker's interface, a redirect to `returnTo` with the URL query parameters `verifysession=1`, `code` and `ticketId` will happen\n4. the `returnTo` page must call `confirmOAuth` with the given `ticketId` and `code` to finally add the session to the user's account",
        "operationId": "PrepareOAuthRedirect",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrepareOAuthRedirectParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrepareOAuthRedirectResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "OAuth not available for the broker."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/{sessionId}": {
      "delete": {
        "description": "Log out from the given broker session.",
        "operationId": "LogoutSession",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoutOkResponseBody"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Session not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Session not found."
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/{sessionId}/decoupledOperation/{decoupledOperationId}": {
      "delete": {
        "deprecated": true,
        "description": "Cancel a decoupled operation.\n\nThis is deprecated, use the new `CancelDecoupledOperation` instead (which does not require the sessionId anymore).",
        "operationId": "CancelDecoupledOperationLegacy",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "decoupledOperationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Bad Request."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Session not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Session not found."
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      },
      "get": {
        "deprecated": true,
        "description": "Get the status of a decoupled operation.\n\nThis is deprecated, use the new `GetDecoupledOperation` instead, which does not require the `sessionId` any more.",
        "operationId": "GetDecoupledOperationStatusLegacy",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "decoupledOperationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecoupledOperationStatus"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "getDecoupledOperation called with wrong parameters"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/{sessionId}/sessiontan": {
      "delete": {
        "description": "End Session TAN for the given broker session.\n\nIf applicable, the broker may return a message with a confirmation code which can be looked up in the initial activation SMS.\nIf message is present in the response, it should be displayed to the user.",
        "operationId": "EndSessionTan",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndSessionTanResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Bad Request."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Session not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Session not found."
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      },
      "post": {
        "operationId": "EnableSessionTan",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnableSessionTanParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnableSessionTanResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Wrong TAN"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/{sessionId}/sessiontanchallenge": {
      "post": {
        "description": "If the user chose an auth method from `GetAuthInfo` with the flow `CHALLENGE_RESPONSE`, before\nenabling session TAN, a challenge must be requested first.",
        "operationId": "CreateSessionTanChallenge",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTanChallengeParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "challengeExplanation": "We send SMS messages with codes as a second authentication factor.",
                      "challengeId": "ttG0q1dLlzxAFqxO",
                      "challengePrompt": "Please enter the code we just sent you.",
                      "challengePromptType": "text"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/Challenge"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "The selected auth method is not available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/{sessionId}/sync": {
      "post": {
        "description": "Trigger a background sync process for the given broker session. This means that a sync will be\nscheduled as soon as possible. All data related to the portfolio (e.g. positions and orders) will\nbe loaded into the brokerize database.",
        "operationId": "TriggerSessionSync",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponseBody"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Session not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Session not found."
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["session"]
      }
    },
    "/sessions/{sessionId}/triggerSyncError": {
      "post": {
        "description": "Only for demo broker portfolios: set a sync error for a session. This can be used for testing.",
        "operationId": "TriggerDemoSessionSyncError",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponseBody"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "TRADING_ERROR",
                      "msg": "Session not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Session not found."
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["demobroker"]
      }
    },
    "/trade/availableOrderIntents": {
      "get": {
        "description": "If `PreparedTrade` contains an `availableOrderIntentsToken`, this endpoint can be used to update the\navailable order intents.\n\nIt is recommended to poll this (e.g. at a rate of one request per 5s). In a future version updates will\nbe provided over WebSockets.",
        "operationId": "GetAvailableOrderIntents",
        "parameters": [
          {
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderIntentAvailability"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for given portfolio available"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "SECURITY_NOT_FOUND",
                      "msg": "Security was not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Security could not be found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/trade/challenge": {
      "post": {
        "description": "If the user chose an auth method from `GetAuthInfo` with the flow `CHALLENGE_RESPONSE`, before\ncreating a trade, a challenge must be requested first. If any other flow is used, a challenge\n*must not* be requested.",
        "operationId": "CreateTradeChallenge",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderChallengeParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Challenge"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for given portfolio available"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "SECURITY_NOT_FOUND",
                      "msg": "Security was not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Security could not be found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/trade/costEstimation": {
      "post": {
        "operationId": "GetCostEstimation",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetCostEstimationParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCostEstimation"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for given portfolio available"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/trade/create": {
      "post": {
        "description": "Create a trade.\n\nIt is possible that the broker rejects the order because of some extra hints that the user must accept (which can not be figured\nout in `prepareTrade`, e.g. because the order volume has to be determined first). In this case, the `MUST_ACCEPT_HINT` error\ncode is returned. The user can choose to accept that hint. If that is the case, the request can be\nretried with the `acceptHintId` parameter.",
        "operationId": "CreateTrade",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateTradeResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  },
                  "Example 2": {
                    "value": {
                      "code": "MUST_ACCEPT_HINT",
                      "hint": {
                        "id": "fees_for_low_order_volume",
                        "text": "The order volume for this order is very low and will result in extra fees. Those fees have to be accepted first."
                      },
                      "msg": "Please accept the hint first."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Hint must be accepted by the user first."
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/trade/prepare": {
      "get": {
        "description": "Prepare a trade of the security in the given portfolio `portfolioId`. You can provide `isin`, `usTicker`, `cryptoCode`, `cryptoPair` to select\na security. The actual broker implementation then automatically uses the appropriate identifier.\n\nIf you already have a `brokerSecurityId` for the given broker, you can also pass that.\n\nNote that for backwards-compatibility reasons `isin` is required. However, if the isin is not applicable, an empty string can be passed.\n\nThe response describes what kind of orders are supported by the broker for the security.\n\nIt requires the portfolio to have at least one active broker session.",
        "operationId": "PrepareTrade",
        "parameters": [
          {
            "in": "query",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ISIN of the security to trade. Note that this is only required for backwards compatibility reasons.\nIf the instrument doest not have an ISIN (or one of our magic ISIN values),\nprovide an empty string and at least one of the other identifiers to find the security at the broker.",
            "in": "query",
            "name": "isin",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The US ticker of the security to trade. Depending on the broker, this might be the preferred identifier.",
            "in": "query",
            "name": "usTicker",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The cryptoCode of the crypto security to trade e.g. 'BTC'. Either this or \"cryptoPair\" should be defined for\ntrades of this kind.",
            "in": "query",
            "name": "cryptoCode",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The crypto pair of the crypto security to trade e.g. 'BTC-EUR'. Either this or \"cryptoCode\" should be defined for\ntrades of this kind.",
            "in": "query",
            "name": "cryptoPair",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The brokerSecurityId of the given broker. Usually this is unknown initially (but will be included in the response of this call).\nIf you know the brokerSecurityId (e.g. because it is provided in an existing position or order), it will be preferred over\nthe other provided identifiers.",
            "in": "query",
            "name": "brokerSecurityId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrepareTradeResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for given portfolio available"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "SECURITY_NOT_FOUND",
                      "msg": "Security was not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Security could not be found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/trade/quote": {
      "post": {
        "description": "Get a quote to use with `orderModel=quote`. The actual quote trade is then performed using `createTradeChallenge` / `createTrade` as\nfor other orderModels.",
        "operationId": "GetQuote",
        "parameters": [
          {
            "in": "query",
            "name": "portfolioId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetQuoteParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetQuoteResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for given portfolio available"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "SECURITY_NOT_FOUND",
                      "msg": "Security was not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Security could not be found"
          },
          "422": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "VALIDATION_FAILED",
                      "msg": "Validation failed",
                      "validationDetails": {
                        "requestBody.order.size": {
                          "debugData": "{\"value\":\"ABC\"}",
                          "message": "invalid float number"
                        }
                      }
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Validation error"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/trade/securityDetails": {
      "get": {
        "description": "Loads more detailed information about a security specified by the given token.\nThe token is extracted from the securityDetailedInfo object in the prepareTrade response",
        "operationId": "GetSecurityDetailedInfo",
        "parameters": [
          {
            "description": "token from the prepareTrade response \"response.securityDetailedInfo.token\"",
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenericTable"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "NO_SESSION_AVAILABLE_FOR_PORTFOLIO",
                      "msg": "No online session for given portfolio available"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No online session for given portfolio available"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["trade"]
      }
    },
    "/tradeDrafts": {
      "get": {
        "description": "Returns active trade draft for a specific user in the specified pagination",
        "operationId": "GetTradeDrafts",
        "parameters": [
          {
            "in": "query",
            "name": "take",
            "required": false,
            "schema": {
              "default": 10,
              "format": "double",
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "skip",
            "required": false,
            "schema": {
              "default": 0,
              "format": "double",
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetActiveTradeDraftsResponse"
                }
              }
            },
            "description": "Ok"
          },
          "400": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "",
                      "msg": "pagination params are invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["tradeDraft"]
      },
      "post": {
        "description": "Create a new trade draft",
        "operationId": "CreateTradeDrafts",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TradeDraftCreateParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "id": {
                      "type": "string"
                    }
                  },
                  "required": ["id"],
                  "type": "object"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["tradeDraft"]
      }
    },
    "/tradeDrafts/{id}": {
      "delete": {
        "description": "Delete a trade draft from the database",
        "operationId": "DeleteTradeDraft",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["tradeDraft"]
      },
      "put": {
        "description": "Update a trade draft",
        "operationId": "UpdateTradeDraft",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TradeDraftUpdateParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["tradeDraft"]
      }
    },
    "/tradeDrafts/{id}/deactivate": {
      "post": {
        "description": "Set a trade draft inactive, but NOT deleted. Inactive trade drafts will not be shown to the user anymore.",
        "operationId": "DeactivateTradeDraft",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "404": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "ORDER_NOT_FOUND",
                      "msg": "Order not found."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Order not found"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["tradeDraft"]
      }
    },
    "/user": {
      "delete": {
        "description": "Delete the current user (only allowed if it is a guest account). Also logs out all active broker\nsessions attached to the user.",
        "operationId": "DeleteGuestUser",
        "parameters": [],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "CAN_ONLY_DELETE_GUEST_USERS",
                      "msg": "Only guest users can be deleted using this endpoint."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Can only delete guest users"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["user"]
      },
      "get": {
        "description": "Checks the provided authentication and returns the logged-in user.",
        "operationId": "GetUser",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetUserResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/accessTokenAvailablePermissions": {
      "get": {
        "description": "Figure out which permissions are available to select from for a new access token.",
        "operationId": "GetAcessTokenAvailablePermissions",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "availablePermissions": {
                      "items": {
                        "$ref": "#/components/schemas/AvailablePermissionsNode"
                      },
                      "type": "array"
                    }
                  },
                  "required": ["availablePermissions"],
                  "type": "object"
                }
              }
            },
            "description": "Ok"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/accessTokens": {
      "get": {
        "operationId": "GetAccessTokens",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetAccessTokensResponse"
                }
              }
            },
            "description": "Ok"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["user"]
      },
      "post": {
        "description": "Create a token for the current user. The token can be used to access resources on behalf of the user.",
        "operationId": "CreateAccessToken",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccessTokenParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenResult"
                }
              }
            },
            "description": "Ok"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/accessTokens/{accessTokenId}": {
      "delete": {
        "operationId": "RevokeAccessToken",
        "parameters": [
          {
            "in": "path",
            "name": "accessTokenId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "idToken": []
          },
          {
            "clientId": [],
            "cookieAuth": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/guest": {
      "post": {
        "description": "Create a guest user and return a token which can be used to access resources.\n\nThe lifetime of the generated temporary user as well as the returned `access_token` depend on the client configuration.\nIt is usually around 24 hours. For some clients, tokens can be expired earlier based on inactivity.\n\nIf the client has configured a longer lifetime for their guest users, a `refresh_token`  is included in the\nresponse. This token can be used to renew the `access_token` after it has expired.\n\nThe `refresh_token` can be used to obtain a new `access_token` after the original token has expired using the `/user/token` endpoint.",
        "operationId": "CreateGuestUser",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateGuestUserResponse"
                }
              }
            },
            "description": "Ok"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/recoveryPhrases": {
      "get": {
        "description": "Lists all the recoveryPhrases metadata the user has in their account.",
        "operationId": "GetRecoveryPhrases",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetRecoveryPhrasesResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "User may not manage recovery phrases"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "cookieAuth": []
          },
          {
            "clientId": [],
            "idToken": []
          }
        ],
        "tags": ["user"]
      },
      "post": {
        "description": "Create a RecoveryPhrase for the current guest user.\n\nThe brokerize backend uses RecoveryPhrases instead of email + password registration or similar approaches, which can never be\nguaranteed to be anonymous.\n\nUsers can simply generate a RecoveryPhrase and save it in a password manager, memorize it or write it down in a safe location.\n\nThe BIP39 word list known from Bitcoins is used to encode a cryptographically safe random token and allows\naccess to the account later (see endpoint `ObtainTokenFromRecoveryPhrase`).",
        "operationId": "CreateRecoveryPhrase",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRecoveryPhraseParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateRecoveryPhraseResult"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "User may not manage recovery phrases"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "cookieAuth": []
          },
          {
            "clientId": [],
            "idToken": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/recoveryPhrases/check": {
      "post": {
        "description": "Check if the RecoveryPhrase is still valid without obtaining a new token set. This can be used in frontends\nwhen users are asked if they still have their RecoveryPhrase.",
        "operationId": "CheckRecoveryPhrase",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ObtainTokenByRecoveryPhraseParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "expiresAt": {
                      "format": "date-time",
                      "type": "string"
                    }
                  },
                  "required": ["expiresAt"],
                  "type": "object"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/recoveryPhrases/token": {
      "post": {
        "description": "Obtain a new access and refresh token set by a RecoveryPhrase. The new set also contains a refresh_token etc, so it can then be used\njust like the tokens obtained from the `ObtainToken` endpoint.\n\nThis also creates a new `trading_session`, as RecoveryPhrases never allow access to an existing trading_session.",
        "operationId": "ObtainTokenByRecoveryPhrase",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ObtainTokenByRecoveryPhraseParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/recoveryPhrases/{recoveryPhraseId}": {
      "delete": {
        "description": "Delete the RecoveryPhrase from the account.",
        "operationId": "DeleteRecoveryPhrase",
        "parameters": [
          {
            "in": "path",
            "name": "recoveryPhraseId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "User may not manage recovery phrases"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "403": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": [],
            "cookieAuth": []
          },
          {
            "clientId": [],
            "idToken": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/user/token": {
      "post": {
        "description": "Obtain a new access token using a refresh token as specified in https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4.\nIf `CreateGuestUser` has provided a `refresh_token`, this endpoint may be used to obtain a new `access_token` after the original token has expired.",
        "operationId": "ObtainToken",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/TokenParams"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            },
            "description": "Ok"
          },
          "401": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "AUTH",
                      "msg": "Authentication is not present or invalid"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not logged in"
          },
          "429": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "RATE_LIMITED",
                      "msg": "Rate limit exceeded."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Rate-limit exceeded"
          },
          "503": {
            "content": {
              "application/json": {
                "examples": {
                  "Example 1": {
                    "value": {
                      "code": "MAINTENANCE",
                      "msg": "API is in maintenance mode. Please try again after 11:30."
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Maintenance active"
          }
        },
        "security": [
          {
            "clientId": []
          }
        ],
        "tags": ["user"]
      }
    },
    "/websocket": {
      "get": {
        "description": "Most operations at brokerize have asynchronous effects.\n\nFor example, consider the flow of an order: when the user creates an order, it will not immediately appear in order list endpoints, because usually brokers take a few seconds until they are retrievable in those lists. Also, after a while, the order may be executed or cancelled asynchronously by the stock exchange.\n\nA common solution for frontends would be to reload the order list regularly. However data is then either delayed or there will be many more requests than needed.\n\nThe brokerize websocket endpoint allows getting updates via web sockets. Generally speaking, clients can subscribe by assigning a subscription id and will then receive updates on that subscription.\n\nIn this documentation, ⬆️ denotes messages from the client to the server, whereas messages from server to client are marked with ⬇️.\n\n## authentication\n\nWhen using cookies for authorization, the WebSocket connection is authenticated with the HTTP upgrade request.\n\nIf token headers are used, the _first_ message from client to server must be:\n\n```\n⬆️ {\n    \"cmd\": \"authorize\",\n    \"idToken\": <string>\n}\n```\n\nIn all cases, clients must wait for the welcome message before sending other messages:\n\n```\n⬇️ { \"cmd\": \"authenticated\" }\n```\n\n## ping\n\nAfter 1 minute of inactivity of a client, the WebSocket connection will be considered stale and will automatically terminated. To prevent this, a ping message can be sent:\n\n```\n ⬆️ {\"cmd\": \"ping\"}\n```\n\nThe server also sends this message regularly. If no message has been received on a WebSocket connection for more than 1 minute, it should be terminated by the client.\n\n```\n ⬇️ {\"cmd\": \"ping\"}\n```\n\n## subscriptions\n\nSubscriptions can be used to get invalidate events or updates for selected resources.\n\n### invalidate subscriptions\n\nInvalidation events can be used for the frontend to know when reload requests via the HTTP endpoints are appropriate. Currently only invalidate events can be subscribed, the actual data must then be reloaded using the HTTP endpoints.\n\nTo set up a subscription for an invalidate event, use:\n\n```\n⬆️ {\n    \"cmd\": \"subscribe\",\n    \"type\": \"invalidate\",\n    \"subscriptionId\": 1,\n    \"entity: \"brokersessions\" /* \"positions\" | \"orders\" */,\n    \"portfolioId\": 42 /* required for \"positions\" or \"orders\" */\n}\n```\n\nIf the subscription failed to be set up on the server, an error will be sent for the subscription. This also automatically ends the subscription on the server side:\n\n```\n⬇️ {\n    \"subscriptionId\": 1,\n    \"error\": {\n        \"message\": \"Could not set up invalidation event due to...\"\n    }\n}\n```\n\nIf an invalid `subscriptionId` is provided (or the subscription id is already in use by the connection), an error like this will be sent:\n\n```\n⬇️ {\n    \"error\": {\n        \"message\": \"Could not add subscription due to invalid subscriptionId\"\n    }\n}\n```\n\n⚠️ _the connection will then be terminated immediately_.\n\nIf the subscription is sucessfuly set up, whenever an invalidation happens, the server will send a message like this:\n\n```\n⬇️ {\n    \"cmd\": \"invalidate\",\n    \"subscriptionId\": 1\n}\n```\n\nWhen that invalidation event is received, the client should reload the data using the corresponding endpoints.\n\nClients can end their subscription with the `unsubscribe` command:\n\n```\n⬆️ {\n    \"cmd\": \"unsubscribe\",\n    \"subscriptionId\": 1\n}\n```\n\n### subscribe to the state of a decoupled operation\n\nFor decoupled operations (e.g. authorizing a session TAN using a second factor device), the state of the operation can be subscribed:\n\n```\n⬆️ {\n    \"cmd\": \"subscribe\",\n    \"type\": \"decoupledOperationStatus\",\n    \"subscriptionId\": 1,\n    \"sessionId\": string,\n    \"decoupledOperationId\": string\n}\n```\n\nError handling as well as unsubscribing works as described for invalidate subscriptions. Example message from the server for updating the state:\n\n```\n⬇️ {\n    \"cmd\": \"updateDecoupledOperationStatus\",\n    \"subscriptionId\": number,\n    \"state\": <DecoupledOperationStatus>\n}\n```\n",
        "operationId": "Websocket",
        "responses": {
          "101": {
            "description": "Upgrading to WebSocket"
          }
        },
        "tags": ["websocket"]
      }
    }
  },
  "servers": [
    {
      "description": "Preview environment",
      "url": "https://api-preview.brokerize.com"
    },
    {
      "description": "This API instance",
      "url": "https://api.brokerize.com"
    }
  ],
  "tags": [
    {
      "description": "For every brokerize user, demo accounts at the demo broker can be created. Those accounts can be used to test client implementations for correct handling of the API, while *NOT* simulating real trading. In a demobroker portfolio, orders are always handled the way described below. This can be used to test applications both manually and automatically, because the behavior is reproducible (which is obviously not the case in a real trading account).",
      "name": "demobroker"
    },
    {
      "description": "Meta-data about available brokers and exchanges",
      "name": "meta"
    },
    {
      "description": "Requests that relate to placed orders",
      "name": "order"
    },
    {
      "description": "Requests that relate to creating a new order / trade",
      "name": "trade"
    },
    {
      "description": "Requests that relate to sessions or session TANs. Logging in, creating a new session, deleting a session",
      "name": "session"
    },
    {
      "description": "Requests that relate to portfolios",
      "name": "portfolio"
    },
    {
      "description": "Requests for managing brokerize API clients",
      "name": "admin"
    },
    {
      "description": "Requests that relate to securities and their data (like quotes)",
      "name": "securities"
    },
    {
      "description": "BETA FEATURE: requests for managing TradeDrafts. TradeDrafts can be generated by bots / trading scripts and are manually reviewed by the user before they are executed. This allows for a more secure trading experience, because the user can review the trades before they are executed.",
      "name": "tradeDraft"
    },
    {
      "description": "Requests that relate to users",
      "name": "user"
    }
  ]
}
