This section defines how clients should interpret and interact with the protocol, how to maintain compatibility across versions, and how to correctly process messages and fields.
•The protocol version is expressed as protocol_version_major.protocol_version_minor.
•Minor version increases indicate backward-compatible changes (e.g., new messages or fields added without altering existing ones). Clients written for an older minor version will continue to operate correctly.
•Major version changes indicate backward-incompatible modifications. Clients must not assume compatibility across major versions.
•Enum values in the protocol are always non-negative.
•Clients must not assume enums are contiguous or semantically ordered.
Clients must be forward-compatible with new enum entries introduced by future protocol versions.
•Clients must not fail when receiving an unknown enum value.
•Unknown values may be ignored, logged, or treated as “unrecognized”.
•If the protocol defines numeric ranges for errors (e.g., values above a specified threshold), clients may check unknown values against these ranges to determine severity.
•The protocol uses only explicit signed and unsigned integer types (e.g., uint32, uint64, sint32, sint64).
•This ensures consistent behavior across languages, particularly JavaScript.
•Clients should process integer fields according to their declared type and not assume any implicit sign behavior.
•Field numbers are not guaranteed to be contiguous or sorted.
•Clients must not infer semantics based on numeric ordering. New fields may appear near related ones even if their field numbers are not adjacent.
To provide consistent messaging semantics, the protocol uses the following suffixes:
•Result Indicates a response message type when a request has exactly one possible response.
•Status Indicates a message reporting the status of a required subscription.
•Report Indicates a message that combines both result and data for operations where a subscription is optional. This avoids the need for two separate messages when the subscription is not requested.
These conventions can assist clients in routing or organizing message handling logic.
The WebAPI server enforces self-protecting rate limits. All client actions are subject to these restrictions.
Note: Limit values may be adjusted (increased or decreased) without prior notice.
•Send an ApiLimitRequest to retrieve current values
•Available limits are defined in the ApiLimit enum
1. Rate Limits Maximum allowed actions per time period
Example: API_LIMIT_CONNECTION_RATE
2. Requests in Processing Concurrent request capacity
Example: API_LIMIT_SESSION_INFORMATION_REQUESTS_IN_PROCESSING
3. Subscription Limits Simultaneous subscription allowances
Example: API_LIMIT_SESSION_INFORMATION_SUBSCRIPTIONS
4. Other Operational Limits Miscellaneous restrictions
Example: API_LIMIT_HISTORICAL_ORDERS_DAYS
•Limit violations result in action rejection.
•Some limitations apply to returned data. For example, API_LIMIT_HISTORICAL_ORDERS_DAYS restricts historical data requests, resulting in truncated responses.
•Some violations (limits with _TO_CLOSE_CONNECTION suffix) force disconnection.
Example: API_LIMIT_SOCKET_UNREADY_PERIOD_TO_CLOSE_CONNECTION
Client Message:
Request API_LIMIT_CONNECTION_RATE (1), API_LIMIT_CONNECTIONS_PER_IP (3), API_LIMIT_API_LIMITS_SUBSCRIPTIONS_AND_REQUESTS_IN_PROCESSING (390).
{
"information_requests": [
{
"id": 1,
"api_limit_request": {
"limits": [
1,
3,
390
]
}
}
]
}
Server Response:
{
"information_reports": [
{
"id": 1,
"status_code": 0,
"api_limit_report": {
"limit_entries": [
{
"limit": 1,
"status_code": 1,
"value": 1000,
"period_sec": 100
},
{
"limit": 3,
"status_code": 1,
"value": 1000
},
{
"limit": 390,
"status_code": 1,
"value": 1
}
]
}
}
]
}
Some messages contain additional text details about the data. If a text field has the Text type, it can be localized. A full list of available messages is described in webapi_2_text.md, which is also provided along with the protocol.
Each row in webapi_2_text.md corresponds to a localized message and contains the following columns:
•Key → Text.key – Identifier of the message type. The key is guaranteed to remain unchanged. If a format update is needed, a new key will be created instead.
•Format – Format string associated with the key.
A Text object consists of the following fields:
•Text.key – Identifier of the message type. The key is guaranteed to remain unchanged. If a format update is needed, a new key will be created instead. Matches the Key column in webapi_2_text.md.
•Text.param – Collection of non-localizable values that should be applied to the format.
•Text.text – The already formatted English string, ready to be displayed.
Handling Changes in New Releases
In general, new releases may add or remove rows from the message list. You should be able to handle unknown messages gracefully. If you do not have a localized format for a key, Text.text can be used as a fallback.
UserMessage is a mechanism to deliver text messages from the server to the client. Typically used to inform about internal or account issues, and may suggest actions to perform (e.g., re-login or contact support).
Key characteristics: - User messages are not standardized (except for UserMessage.message_type) - They shouldn’t be parsed by clients - Designed to be shown to end-users - Exception: Messages with UserMessage.message_type = MESSAGE_TYPE_LOG should not be displayed
Informative message after logoff/disconnect:
{
"user_messages": [
{
"message_type": 4,
"source": "Web API
Server",
"text": "Message cannot be processed
within this user session after logoff or disconnect."
}
]
}
Client application not responding to server Ping:
{
"user_messages": [
{
"message_type": 4,
"source": "Web API Server",
"text": "No response to server ping request sent 30 seconds
ago."
}
]
}
Client approaching account limit:
{
"user_messages": [
{
"message_type": 2,
"source": "Web API Server",
"text": "Your current number of accounts is 4950. If your number
of accounts exceeds 5000, you will not be able to log in. Please remove inactive
accounts or contact customer support to increase the
limit."
}
]
}
The WebAPI server supports multiple account types, which determine how you interact with an account and the data available for it.
•Regular account
•Group account – Account.is_group_member=true
•Omnibus account – Account.is_omnibus=true
•Not cleared by statement accounts – Account.cleared_by_statements=false
A group account can be either a master account or a sub-account that shares resources with other accounts in the group.
•The purchasing power limit may be empty for group
accounts.
•Purchasing power is a real-time snapshot calculated by the server using data from all accounts in the group.
o As a result, it may not be synchronized with values reported for an individual account.
Not Cleared by Statement Accounts
For accounts that are not cleared by statements, certain subscription scopes and requests are not supported:
•SUBSCRIPTION_SCOPE_POSITIONS and SUBSCRIPTION_SCOPE_ACCOUNT_SUMMARY
in
TradeSubscription
Requests for such accounts do not fail, but no data is returned.
E.g., crypto exchange accounts, where there is no need for clearing since trade results are directly applied to the account balance.
See also Account.supports_exchange_balances_subscription and Account.supports_exchange_positions_subscription.