Skip to content

Cancel All Orders (WebSocket)

Cancel all open orders for specific market(s), or all markets with the wildcard symbol, through the WebSocket connection.

Action Result Notifications

This method executes cancellations immediately. Cancellation events are automatically sent via SubAccount Updates Subscription if subscribed.

Endpoint

ws.send() wss://api.synthetix.io/v1/ws/trade

Request

Request Format

{
  "id": "cancelall-1",
  "method": "post",
  "params": {
    "action": "cancelAllOrders",
    "subAccountId": "1867542890123456789",
    "symbols": ["BTC-USDT", "ETH-USDT"],
    "source": "direct",
    "nonce": 1704067200000,
    "expiresAfter": 1704067300,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Parameters

Request Parameters

ParameterTypeRequiredDescription
idstringYesClient-generated unique request identifier
methodstringYesMust be "post"
paramsobjectYesContains all parameters for the request

Params Object

ParameterTypeRequiredDescription
actionstringYesMust be "cancelAllOrders"
subAccountIdstringYesSubAccount ID to cancel orders for
symbolsarrayYesArray of symbols to cancel. Use ["*"] to cancel across all markets. [] is rejected. ["*", "ETH-USDT"] is rejected
sourcestringNoRequest source identifier for tracking and rebates (max 100 characters). Use "direct" for generic integrations
nonceintegerYesPositive integer, incrementing nonce
expiresAfterintegerNoOptional expiration Unix timestamp in seconds (0 = no expiration)
signatureobjectYesEIP-712 signature with v, r, s components

EIP-712 Signature

const domain = {
  name: "Synthetix",
  version: "1",
  chainId: 1,
  verifyingContract: "0x0000000000000000000000000000000000000000"
};
 
const types = {
  CancelAllOrders: [
    { name: "subAccountId", type: "uint256" },
    { name: "symbols", type: "string[]" },
    { name: "nonce", type: "uint256" },
    { name: "expiresAfter", type: "uint256" }
  ]
};
 
const message = {
  subAccountId: "1867542890123456789",
  symbols: ["BTC-USDT", "ETH-USDT"],
  nonce: Date.now(),
  expiresAfter: 0
};
 
const signature = await signer._signTypedData(domain, types, message);

Wildcard Rules for symbols

  • ["*"]: Cancel all open orders across all markets
  • ["BTC-USDT", "ETH-USDT"]: Cancel only those markets
  • []: Rejected
  • ["*", "ETH-USDT"]: Rejected (wildcard must be used alone)

Response Format

Success Response

{
  "id": "cancelall-1",
  "status": 200,
  "result": {
    "status": "success",
    "response": [
      {
        "order": {
          "venueId": "1958787130134106112",
          "clientId": "cli-1958787130134106112"
        },
        "orderId": "1958787130134106112",
        "message": "",
        "symbol": "BTC-USDT"
      },
      {
        "order": {
          "venueId": "1958787130134106113",
          "clientId": "cli-1958787130134106113"
        },
        "orderId": "1958787130134106113",
        "message": "",
        "symbol": "ETH-USDT"
      }
    ]
  }
}

Empty Result (No Orders to Cancel)

{
  "id": "cancelall-1",
  "status": 200,
  "result": {
    "status": "success",
    "response": []
  }
}

Error Response

{
  "id": "cancelall-1",
  "status": 400,
  "result": null,
  "error": {
    "code": 400,
    "message": "Invalid request parameters"
  }
}

Code Examples

Migration Note: Use order.venueId as canonical in cancellation responses. orderId is deprecated compatibility output.

The message field contains an error description when cancellation fails for a specific order, and is empty on success. Do not treat a non-empty message as a success confirmation.

Cancel Orders for Specific Markets

{
  "id": "cancelall-markets",
  "method": "post",
  "params": {
    "action": "cancelAllOrders",
    "subAccountId": "1867542890123456789",
    "symbols": ["BTC-USDT", "ETH-USDT"],
    "nonce": 1704067200000,
    "expiresAfter": 1704067300,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Cancel Orders for All Markets

{
  "id": "cancelall-all",
  "method": "post",
  "params": {
    "action": "cancelAllOrders",
    "subAccountId": "1867542890123456789",
    "symbols": ["*"],
    "nonce": 1704067200000,
    "expiresAfter": 1704067300,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Cancel Orders for Single Market

{
  "id": "cancelall-btc",
  "method": "post",
  "params": {
    "action": "cancelAllOrders",
    "subAccountId": "1867542890123456789",
    "symbols": ["BTC-USDT"],
    "nonce": 1704067200000,
    "expiresAfter": 1704067300,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Implementation Example

class OrderCancellation {
  constructor(ws, signer) {
    this.ws = ws;
    this.signer = signer;
    this.pendingRequests = new Map();
  }
 
  async cancelAllOrders(subAccountId, symbols) {
    if (!symbols || symbols.length === 0) {
      throw new Error('symbols array must contain at least one market symbol');
    }
    if (symbols.includes('*') && symbols.length > 1) {
      throw new Error('wildcard "*" must be used alone as ["*"]');
    }
 
    const nonce = Date.now();
    const expiresAfter = Math.floor(Date.now() / 1000) + 30; // 30 seconds from now (Unix seconds)
 
    // Create EIP-712 signature
    const signature = await this.signCancelAllOrders({
      subAccountId,
      symbols,
      nonce,
      expiresAfter
    });
 
    const request = {
      id: `cancelall-${Date.now()}`,
      method: "post",
      params: {
        action: "cancelAllOrders",
        subAccountId,
        symbols,
        nonce,
        expiresAfter,
        signature
      }
    };
 
    return this.sendRequest(request);
  }
 
  async signCancelAllOrders({ subAccountId, symbols, nonce, expiresAfter }) {
    const domain = {
      name: "Synthetix",
      version: "1",
      chainId: 1,
      verifyingContract: "0x0000000000000000000000000000000000000000"
    };
 
    const types = {
      CancelAllOrders: [
        { name: "subAccountId", type: "uint256" },
        { name: "symbols", type: "string[]" },
        { name: "nonce", type: "uint256" },
        { name: "expiresAfter", type: "uint256" }
      ]
    };
 
    const message = {
      subAccountId,
      symbols,
      nonce,
      expiresAfter
    };
 
    const signature = await this.signer._signTypedData(domain, types, message);
    const { v, r, s } = ethers.utils.splitSignature(signature);
    return { v, r, s };
  }
 
  sendRequest(request) {
    return new Promise((resolve, reject) => {
      this.pendingRequests.set(request.id, { resolve, reject });
      this.ws.send(JSON.stringify(request));
 
      setTimeout(() => {
        if (this.pendingRequests.has(request.id)) {
          this.pendingRequests.delete(request.id);
          reject(new Error('Request timeout'));
        }
      }, 10000);
    });
  }
 
  handleResponse(response) {
    const pending = this.pendingRequests.get(response.id);
    if (pending) {
      this.pendingRequests.delete(response.id);
      if (response.error) {
        pending.reject(new Error(response.error.message));
      } else {
        pending.resolve(response.result);
      }
    }
  }
}
 
// Usage Examples
 
// Cancel all orders for specific markets
async function cancelByMarkets(cancellation, subAccountId, symbols) {
  try {
    const result = await cancellation.cancelAllOrders(subAccountId, symbols);
    console.log(`Cancelled ${result.response.length} orders in ${symbols.join(', ')}`);
    return result;
  } catch (error) {
    console.error('Cancel by markets failed:', error);
    throw error;
  }
}
 
// Cancel all BTC orders
async function cancelAllBtcOrders(cancellation, subAccountId) {
  return cancelByMarkets(cancellation, subAccountId, ['BTC-USDT']);
}

Cancel Behavior

  • Immediate Effect: Orders are cancelled immediately upon validation
  • Margin Release: Freed margin becomes available instantly
  • Partial Fills: Partially filled orders are cancelled for remaining quantity
  • All Order Types: Cancels limit, market, and trigger orders
  • Atomic Operation: All specified orders are cancelled together

Implementation Details

The API performs the following steps:

  1. Validates that the symbols array contains at least one market
  2. Validates wildcard usage (* may only appear as ["*"])
  3. Retrieves all open orders for the authenticated subaccount
  4. Filters orders by the specified symbols (or all when ["*"] is used)
  5. Iterates through each order and attempts to cancel it
  6. Returns an array of cancellation statuses for each processed order

Implementation Notes

  • symbols array must contain at least one valid market symbol
  • symbols: ["*"] cancels all markets and wildcard cannot be mixed with other symbols
  • Market symbols must be valid trading pairs (e.g., "BTC-USDT")
  • Authentication timestamps must be strictly increasing per subaccount
  • EIP-712 domain separator must use "Synthetix" for WebSocket endpoints
  • expiresAfter uses Unix seconds (not milliseconds)

Validation Rules

  • nonce must be a positive integer, incrementing and unique per request
  • symbols array must contain at least one valid market symbol
  • ["*"] cancels all markets and cannot be combined with other symbols
  • [] is invalid
  • Must be signed by account owner or authorized delegate
  • Subaccount ID must be valid and accessible

Signing

All trading methods are signed using EIP-712. Each successful trading request will contain:

  • A piece of structured data that includes the sender address
  • A signature of the hash of that structured data, signed by the sender

For detailed information on EIP-712 signing, see EIP-712 Signing.

Nonce Management

The nonce system prevents replay attacks and ensures order uniqueness:

  • Use any positive integer as nonce
  • Each nonce must be greater than the previous one (incrementing)
  • Date.now() is a convenient option, not a requirement
  • If nonce conflicts occur, increment by 1 and retry

:::note SubAccountAction Exception SubAccountAction endpoints (getPositions, getOpenOrders, getOrdersHistory, getTrades, getFundingPayments, getSubAccount, getSubAccounts, getDelegatedSigners, getBalanceUpdates) do not require a nonce. Only the signature and optional expiresAfter parameters are needed. :::

Error CodeDescriptionRetryable
UNAUTHORIZEDEIP-712 signature validation failedNo
VALIDATION_ERRORRequest validation failedNo
MISSING_REQUIRED_FIELDRequired field is missingNo
INVALID_FORMATField format is invalidNo
INVALID_VALUEInvalid parameter valueNo
RATE_LIMIT_EXCEEDEDToo many requests in time windowYes
INSUFFICIENT_MARGINNot enough margin for tradeNo
ORDER_NOT_FOUNDOrder does not existNo
OPERATION_TIMEOUTOperation timed outYes
ErrorDescription
Symbols must be non-emptysymbols array cannot be empty
Invalid wildcard usage* must be used alone as ["*"]
Invalid market symbolMarket symbol not recognized
No orders foundNo open orders to cancel
Request expiredexpiresAfter timestamp has passed

Next Steps