ping_pong
Clients may send method: "ping_pong" (or "ping_only") at any time to check the connection is
alive; the server acks immediately on channel HEARTBEAT. This message requires no signature and
carries no id.
Client sends ping:
{ "method": "ping_pong" }
Server replies pong:
{ "method": "ping_pong", "channel": "HEARTBEAT", "status": "ok", "message": "pong" }
The server also periodically broadcasts a heartbeat message (every 30 seconds) to every open connection — clients aren't required to send their own ping, but doing so is still recommended to detect a half-open connection early.
Response Body
application/json
Sample Request
wscat -c wss://api.ssi.com.vn/ws/v3/trading -x '{
"method": "ping_pong"
}'Sample Response
{
"method": "ping_pong",
"channel": "HEARTBEAT",
"status": "ok",
"message": "pong"
}Connect WebSocket APIWS
Establish a WebSocket connection via an HTTP Upgrade request to `/ws/v3/trading`. The server returns `HTTP 101 Switching Protocols` when the connection succeeds. **Authentication:** pass the JWT access token one of two ways (checked in this order): - Query string: `wss://.../ws/v3/trading?token=<jwt>` - Header: `Authorization: Bearer <jwt>` The token must be valid (not expired, not revoked) and the API Key must be granted the `tradingws:*:*` scope — the `trading:*:*` scope used by the REST Trading API **does not work** for this WS connection; it must be granted separately. **Connection limits:** at most 10 concurrent connections per API Key; exceeding the limit is rejected with reason `Connection limit exceeded`. **⚠️ Client implementation note:** except when the request is not a valid WebSocket upgrade (a real HTTP `400` returned before connecting), every other rejection reason (401/403/429) happens AFTER the connection has already succeeded (HTTP 101) — the server accepts the connection first, sends a message describing the reason, then closes it. Reason: most WebSocket client libraries cannot reliably surface the HTTP status code of the connection step. Clients **should read the first message** after connecting to know whether the connection is actually ready to send commands. **Sample rejection message:** ```json { "code": 401, "msg": "Invalid or expired token" } ``` Possible rejection reasons: `401` missing/invalid/expired/revoked token, `403` missing `tradingws:*:*` scope, `429` concurrent-connection limit exceeded, `500` system error.
order.placeWS
Place a new order. The system **responds immediately** (`orderStatus: "PD"`) to confirm the order was accepted — the real fill status arrives later via the `order.{accountNo}` notification channel (see "Place/amend/cancel orders: fast acknowledgment, result arrives later" at the top of this document). Requires a `signature` (RSA+SHA256) per UBCKNN's data-integrity regulation for trading operations. Required scope: `tradingws:order:post`.