All websocket channels may return an error frame instead of the expected response. Error frames share a single, consistent schema.

Error Envelope

{
  "type": "error",
  "error_code": "RateLimited",
  "message": "You have exceeded the allowed message rate.",
  "incoming_message": {
    "type": "add_order",
    "params": {
      "symbol": "AAPL",
      "side": "BUY",
      "order_type": "LIMIT",
      "order_time_in_force": "GTC",
      "quantity": 10.0,
      "price": 200.0,
      "client_order_id": "my-order-001",
      "take_profit": null,
      "stop_loss": null
    }
  }
}

Fields

FieldTypeRequiredDescription
typestringYesAlways "error" for error frames.
error_codestringYesMachine-readable error code (see list below). Matches server enum variant exactly.
messagestring/nullNoHuman-readable context. May be null.
incoming_messageobject/nullNoEcho of the request that caused the error (your original message), when available.
Note: incoming_message uses the same tagged format as requests ({ "type": "<snake_case>", "params": { ... } }).

Error Codes

These values map 1:1 to the server enum:
CodeWhen it happensSuggested Client Action
RateLimitedYou’ve exceeded the allowed message rate (weighted per message type).Backoff and retry later. Consider batching and respecting published limits.
InvalidJSONFormatMessage is not valid JSON or doesn’t match the expected schema.Validate JSON and schema before sending. Include required fields and correct types/enum values.
AlreadyAuthenticatedYou attempted to authenticate again after a successful auth on the same connection.Do not re-auth on an already authenticated socket.
InvalidParameterOne or more parameters are out of range, missing, or invalid for the specified message.Correct the parameter(s) and retry.
PermissionDeniedThe API key or user lacks permission for the requested action.Check key scopes/roles; contact support if needed.
ServerErrorUnexpected internal error.Safe to retry after a short delay; if persistent, contact support with timestamp and incoming_message.

Rate limiting notes

The server computes message weight by the message "type" (e.g., "add_order", "cancel_order") and applies limits over a sliding window. Some messages are heavier than others. If you see RateLimited, delay and reduce frequency; prefer fewer, larger requests when possible.

Examples

1) Invalid JSON

{
  "type": "error",
  "error_code": "InvalidJSONFormat",
  "message": "Expected field `symbol` (string).",
  "incoming_message": {
    "type": "add_order",
    "params": {
      "side": "BUY",
      "order_type": "LIMIT",
      "order_time_in_force": "GTC",
      "quantity": 10.0,
      "price": 200.0
    }
  }
}

2) Already authenticated

{
  "type": "error",
  "error_code": "AlreadyAuthenticated",
  "message": "Connection is already authenticated.",
  "incoming_message": { "type": "auth", "params": { "api_key": "****" } }
}

3) Invalid parameter

{
  "type": "error",
  "error_code": "InvalidParameter",
  "message": "price must be >= min_tick and within price bands.",
  "incoming_message": {
    "type": "modify_order",
    "params": {
      "symbol": "AAPL",
      "order_id": "cd1a2b0c-...-f3",
      "quantity": 10.0,
      "price": 0.0001,
      "take_profit": 0.0,
      "stop_loss": 0.0,
      "side": "BUY"
    }
  }
}

4) Permission denied

{
  "type": "error",
  "error_code": "PermissionDenied",
  "message": "API key does not allow trading on this account.",
  "incoming_message": {
    "type": "transfer_balance",
    "params": { "amount": 100.0, "to_api_key": "****" }
  }
}

5) Rate limited

{
  "type": "error",
  "error_code": "RateLimited",
  "message": "Too many requests. Please retry after 200ms.",
  "incoming_message": { "type": "cancel_all_orders", "params": {} }
}

6) Server error

{
  "type": "error",
  "error_code": "ServerError",
  "message": "Unexpected error processing request.",
  "incoming_message": { "type": "get_user_trades", "params": { "limit": 50 } }
}

Client Handling Patterns

Authentication & Errors

  • trade.qfex.com requires authentication within 1 minute of connecting.
  • Attempting to re-authenticate an already authenticated connection yields AlreadyAuthenticated.

Troubleshooting Checklist

  1. Validate JSON (types/enums/required fields).
  2. Respect rate limits (reduce burstiness; batch where possible).
  3. Ensure your API key has the right permissions.
  4. Log incoming_message from error frames to quickly reproduce issues.
  5. For persistent ServerError, contact support@qfex.com with timestamp and offending incoming_message.