WebSocket API

order.batchCancel

Cancel multiple orders in a single message (Batch Order). Each order in params.orders has the same structure and rules as order.cancel (the order is identified by orderId OR clientRequestId).

The same general rules and the same fast PD acknowledgment as order.batchNew apply (up to 50 orders, all-or-nothing validation, 30-second replay window, idempotency by batchRequestId, signature over the entire params). The real outcome of each cancel request arrives afterward through the order.{accountNo} notification channel.

Required scope: tradingws:order:delete.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

bodyobjectrequired
idstringrequired
methodstringrequired
paramsobjectrequired
batchRequestIdstringrequired

Batch identifier created by the client. Must be unique per API Key and per action (place/cancel) within a day. Used as the idempotency key.

batchRequestTimeintegerrequired

The time the client created the batch, in epoch milliseconds (UTC). Must be within 30 seconds of server time.

ordersarrayrequired

List of orders to cancel, up to 50. Each element has the same structure as the `params` of `order.cancel`.

orders[]objectrequired

Exactly one of `orderId`/`clientRequestId` must be supplied to identify the order to cancel.

clientCancelIdstring | nulloptional

Client-generated cancel identifier. Auto-generated by the system when omitted.

clientRequestIdstring | nulloptional

The original order's client-generated identifier from when it was placed. Used XOR with `orderId`.

orderIdstring | nulloptional

The original order's identifier generated by the SSI system. Used XOR with `clientRequestId`.

accountNostringrequired

Trading account number.

deviceIdstringrequired

Identifier of the device submitting the cancel request.

userAgentstring | nulloptional

Information about the browser/application sending the request.

signaturestringrequired

RSA+SHA256 signature (base64) over the entire `params` content. Required.

timestampintegerrequired

Response Body

application/json

application/json

Sample Request

wscat -c wss://api.ssi.com.vn/ws/v3/trading -x '{
  "id": "req-0011",
  "method": "order.batchCancel",
  "params": {
    "batchRequestId": "batch-20261014-0002",
    "batchRequestTime": 1755000020000,
    "orders": [
      {
        "orderId": "ORD123456",
        "accountNo": "0901351",
        "deviceId": "MAC-AABBCCDDEEFF"
      },
      {
        "clientRequestId": "o-0002",
        "accountNo": "0901351",
        "deviceId": "MAC-AABBCCDDEEFF"
      }
    ]
  },
  "signature": "base64(RSA-SHA256(...))",
  "timestamp": 1755000020000
}'

Sample Response

{
  "id": "req-0011",
  "method": "order.batchCancel",
  "status": 200,
  "result": {
    "batchRequestId": "batch-20261014-0002",
    "results": [
      {
        "clientRequestId": "o-0001",
        "clientCancelId": "c-0001",
        "orderId": "ORD123456",
        "orderStatus": "PD",
        "success": true
      },
      {
        "clientRequestId": "o-0002",
        "clientCancelId": "c-0002",
        "orderStatus": "PD",
        "success": true
      }
    ]
  },
  "rateLimit": {
    "limit": 50,
    "remaining": 45,
    "resetMs": 850
  }
}

order.batchNewWS

Place multiple new orders in a single message (Batch Order). Each order in `params.orders` has the same structure and rules as `order.place`. **General rules** - Up to **50 orders** per batch. Orders may belong to different accounts, but every account must be in the list of accounts granted to the API Key. - Validation is **all-or-nothing**: if any order is invalid, the entire batch is rejected and no order is sent. - **Replay protection**: `batchRequestTime` (epoch milliseconds, UTC) must be within **30 seconds** of server time. - **Idempotency**: `batchRequestId` must be unique per API Key and per action (place/cancel) within a day; resending the same `batchRequestId` is rejected as a duplicate request. - The `signature` (RSA+SHA256) is computed over the **entire `params`**, i.e. `batchRequestId`, `batchRequestTime` and `orders`. **Response:** the system returns **a single ack** for the whole batch, in which every order has `orderStatus: "PD"` — this is not the match result yet. The real outcome of each order (filled/rejected/cancelled) is delivered separately through the `order.{accountNo}` notification channel (see "Place/amend/cancel orders: fast acknowledgment, result arrives later" at the top of this document), so clients **must subscribe** for the accounts involved. Unlike REST, the WebSocket ack does not contain `orderId` and does not indicate whether an individual order is later rejected during business processing. Required scope: `tradingws:order:post`.

fco.placeWS

Place a conditional order — the response returns the order-creation result right away, unlike `order.*` which acks first and delivers the result later. If rejected, the response carries an error with `error.code: "FCO_ERROR"`. Requires a `signature`. See also the [Conditional Order Reference](/en/docs/api-reference/appendix/fco-reference) appendix. Required scope: `tradingws:fco:post`.