Authentication
After establishing a WebSocket trade push connection, you must send an authentication frame first. No trade events will be pushed until authentication succeeds. If authentication fails, the connection is closed, or no authentication result is returned within the timeout, close the current connection, correct your credentials, and reconnect.
INFO
This page describes the authentication frame format supported by the current WebSocket gateway. The backend trade push service does not validate public-network credentials directly — it receives the session context established by the gateway after authentication. Developers only need to handle the first-frame authentication, the authentication result, and subsequent event reception. Internal session fields should not be included.
Prerequisites
Before you begin, confirm the following:
- You have obtained valid access credentials following the Getting Started guide.
- You have connected to the WebSocket Trade endpoint:
wss://webapi-trade.moomoo.com- The current account has the required trading permissions. Permissions affect the range of events you will receive.
Authentication Methods
WebSocket trade push supports two authentication methods:
| Method | Recommended | Use Case | Description |
|---|---|---|---|
| OAuth 2.1 + PKCE | Recommended | Third-party apps, desktop apps, mobile apps, web apps requiring user authorization | Use access_token as a Bearer Token to authenticate the WebSocket connection. |
| API Key | Compatible | Server-side systems, backend jobs, internal tools where the developer controls the key | Use AppKey, timestamp, nonce, and signature to authenticate the WebSocket connection. |
Use OAuth When Possible
OAuth eliminates the need to store a private API key on the client and removes the overhead of manually managing signature materials for each connection. Unless you already have a server-side API Key integration or have an explicit compatibility requirement, OAuth 2.1 + PKCE is recommended.
Authentication Frame Format
After the connection is established, the client should send the authentication frame as the first business message:
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Must be auth. |
data.auth_type | string | Yes | Authentication type. Use oauth2 for OAuth; appkey for API Key. |
data.authorization | string | Yes | For OAuth, pass Bearer {access_token}; for API Key, pass the signature result. |
OAuth Authentication Example
First obtain an access_token following Getting Started: OAuth 2.1 + PKCE, then send the following JSON after the WebSocket connection opens:
{
"action": "auth",
"data": {
"auth_type": "oauth2",
"authorization": "Bearer {access_token}"
}
}Notes:
authorizationmust include theBearerprefix.- If
access_tokenis expired or invalid, authentication will fail. Refresh usingrefresh_token, then re-establish the WebSocket connection and re-authenticate. - Ensure the user's authorization scope covers trade event read access; insufficient permissions may result in no events being received.
Token Security
Do not embed access_token or refresh_token in publicly accessible static configs, logs, or error reports. Server-side applications should use secure storage; desktop or mobile applications should use system keychains or encrypted storage.
API Key Authentication Example
API Key is suitable when the private key is held server-side. First follow Getting Started: Traditional API Key to create an AppKey, upload the public key, and securely store the private key.
The high-level structure of the WebSocket authentication frame:
{
"action": "auth",
"data": {
"auth_type": "appkey",
"credential_id": "{app_key}",
"authorization": "{signature_base64}",
"timestamp_ms": 1782357937000,
"nonce": "{nonce}"
}
}Field descriptions:
| Field | Type | Required | Description |
|---|---|---|---|
credential_id | string | Yes | AppKey ID. |
authorization | string | Yes | Signature generated using the AppKey private key, typically Base64-encoded. |
timestamp_ms | int64 | Yes | Client-side current Unix timestamp in milliseconds. |
nonce | string | Yes | Client-generated random string for replay protection. |
API Key Signing Rules
WebSocket API Key authentication uses the same AppKey / public key / private key identity as REST API Key calls, but the signing payload for WebSocket authentication may include WebSocket-specific method and path components. Follow the official WebSocket signing rules provided in the platform documentation — do not reuse a REST request's signing payload directly.
Private Key Security
The API Key private key must only be stored in a secure server-side environment or a controlled runtime. Do not distribute it to browsers, mobile app packages, client-side config files, or code repositories.
Handling the Authentication Result
After sending the authentication frame, the client should wait for the server's response before expecting any trade event push.
Recommended handling:
| Scenario | Recommended Action |
|---|---|
| Authentication succeeded | Record the connection as authenticated and wait for the server to push trade events. |
| Error returned | Check your Token, AppKey, signature, timestamp, and permissions based on the error message. |
| Server closes the connection | Treat the current connection as unavailable. Correct credentials or apply a backoff delay before reconnecting and re-authenticating. |
| Timeout waiting for response | Close the connection and retry. Avoid waiting for events in an unknown authentication state. |
Authentication Success Response
On success, the server returns the following JSON:
{
"id": "req-001",
"session_id": "123456789",
"server_time": 1782357937000000
}| Field | Type | Description |
|---|---|---|
id | string | Echoed request ID; omitted if not provided in the request. |
session_id | string | Session ID assigned by the server. |
server_time | int64 | Server time as a microsecond-precision Unix timestamp. |
After successful authentication, the gateway establishes the session context required for subsequent event push. Clients do not need to parse or forward internal routing fields such as uid, session_id, or conn_id — these are handled internally by the gateway and backend services.
Channel Refresh
After authentication succeeds, you can send a refresh frame on the established connection to renew the session token. Trade event push continues uninterrupted after a successful refresh.
Refresh Frequency Requirement
Clients must send a refresh frame at least once every 10 minutes. If no refresh is sent for more than 10 minutes, the server will actively close the connection. It is recommended to send refresh frames on a 5-minute interval to allow room for retries.
OAuth Refresh
After exchanging a new access_token in the background using refresh_token, send the following refresh frame:
{
"action": "refresh",
"data": {
"authorization": "Bearer {new_access_token}"
}
}Notes:
- Refresh proactively before the token expires to avoid session interruption due to token expiry.
authorizationmust include theBearerprefix.
API Key Refresh
{
"action": "refresh",
"data": {
"credential_id": "{app_key}",
"authorization": "{new_signature_base64}",
"timestamp_ms": 1782357938000,
"nonce": "{new_nonce}"
}
}Notes:
timestamp_msandnoncemust be new values different from those used in the previous authentication — they cannot be reused.- The signing payload format is the same as for initial authentication; do not reuse previous signing material.
Refresh Success Response
On success, the server returns the same format as the initial authentication response:
{
"id": "req-002",
"session_id": "123456789",
"server_time": 1782357938000000
}session_id remains unchanged; server_time is updated to the current server time.
If a refresh fails, verify that the new credentials are valid. If refreshes fail repeatedly, close the connection and re-establish it with new credentials.
Connection Lifecycle Recommendations
- Authenticate before expecting events: Every time a new WebSocket connection is established, send an authentication frame first and wait for success before expecting event push.
- Re-authenticate after reconnection: Do not assume the authentication state of the previous connection is still valid. Reconnect and re-authenticate.
- Send refresh frames on schedule: After authentication succeeds, clients must send a refresh frame at least once every 10 minutes; a 5-minute interval is recommended. The server will actively close the connection if no refresh is received within 10 minutes. For OAuth, also refresh the token before it expires; API Key sessions likewise require periodic refresh to maintain the session. See Channel Refresh.
- Do not reuse internal session fields: Session identifiers that appear in server responses or logs are for internal gateway routing only and should not be persisted or reused as public parameters.
- Apply backoff on repeated failures: If authentication fails repeatedly, verify credential configuration and use exponential backoff to avoid high-frequency reconnection.
FAQ
Can I re-send an authentication frame on the same connection to switch users?
Not recommended. A single WebSocket connection should correspond to one authentication context. To switch users, accounts, or credentials, close the current connection and reconnect with the new credentials.
Can OAuth and API Key be used together?
Choose one method per connection. OAuth uses auth_type=oauth2 and a Bearer Token; API Key uses auth_type=appkey and signature materials. Do not include both sets of credentials in the same authentication frame.
Why am I not receiving any events after authentication succeeds?
Authentication success only means the connection is valid — it does not mean the account has pending events. Trade event push is passive: the server only pushes when events occur. If no messages are received for an extended period, check whether the connection is still healthy using Keep Alive.
Next Steps
- Trade Event Push Overview — Learn about WebSocket trade push capabilities and the integration flow.
- Subscription — Learn about the event push coverage and behavior after authentication.
- Keep Alive — Handle ping/pong, timeouts, and reconnection.
- Data Format — View push message structure and field reference.
- Error Codes — Troubleshoot authentication and connection errors.