Skip to content

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:

  1. You have obtained valid access credentials following the Getting Started guide.
  2. You have connected to the WebSocket Trade endpoint:
text
wss://webapi-trade.moomoo.com
  1. 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:

MethodRecommendedUse CaseDescription
OAuth 2.1 + PKCERecommendedThird-party apps, desktop apps, mobile apps, web apps requiring user authorizationUse access_token as a Bearer Token to authenticate the WebSocket connection.
API KeyCompatibleServer-side systems, backend jobs, internal tools where the developer controls the keyUse 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:

FieldTypeRequiredDescription
actionstringYesMust be auth.
data.auth_typestringYesAuthentication type. Use oauth2 for OAuth; appkey for API Key.
data.authorizationstringYesFor 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:

json
{
  "action": "auth",
  "data": {
    "auth_type": "oauth2",
    "authorization": "Bearer {access_token}"
  }
}

Notes:

  • authorization must include the Bearer prefix.
  • If access_token is expired or invalid, authentication will fail. Refresh using refresh_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:

json
{
  "action": "auth",
  "data": {
    "auth_type": "appkey",
    "credential_id": "{app_key}",
    "authorization": "{signature_base64}",
    "timestamp_ms": 1782357937000,
    "nonce": "{nonce}"
  }
}

Field descriptions:

FieldTypeRequiredDescription
credential_idstringYesAppKey ID.
authorizationstringYesSignature generated using the AppKey private key, typically Base64-encoded.
timestamp_msint64YesClient-side current Unix timestamp in milliseconds.
noncestringYesClient-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:

ScenarioRecommended Action
Authentication succeededRecord the connection as authenticated and wait for the server to push trade events.
Error returnedCheck your Token, AppKey, signature, timestamp, and permissions based on the error message.
Server closes the connectionTreat the current connection as unavailable. Correct credentials or apply a backoff delay before reconnecting and re-authenticating.
Timeout waiting for responseClose the connection and retry. Avoid waiting for events in an unknown authentication state.

Authentication Success Response

On success, the server returns the following JSON:

json
{
  "id": "req-001",
  "session_id": "123456789",
  "server_time": 1782357937000000
}
FieldTypeDescription
idstringEchoed request ID; omitted if not provided in the request.
session_idstringSession ID assigned by the server.
server_timeint64Server 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:

json
{
  "action": "refresh",
  "data": {
    "authorization": "Bearer {new_access_token}"
  }
}

Notes:

  • Refresh proactively before the token expires to avoid session interruption due to token expiry.
  • authorization must include the Bearer prefix.

API Key Refresh

json
{
  "action": "refresh",
  "data": {
    "credential_id": "{app_key}",
    "authorization": "{new_signature_base64}",
    "timestamp_ms": 1782357938000,
    "nonce": "{new_nonce}"
  }
}

Notes:

  • timestamp_ms and nonce must 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:

json
{
  "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.