Order Status Event Push (V2)
Connection Information
Connection Endpoint: wss://{host}/ws/v2/stream
Description: Provides real-time order status change push notifications for Makers. After establishing the connection, the client must send a subscribe message to start receiving order status change events.
Authentication: Institution credentials (API Key + Signature), passed via api_key, timestamp, and signature fields in the subscribe message body. See WebSocket Authentication
Connection Mechanism
After the WebSocket connection is established, the server does not automatically push any data. The client must send a subscribe message to begin receiving events.
Initial Handshake Timeout (5-Second Rule)
After the connection is established, the client must send at least one valid message within 5 seconds, otherwise the server will actively close the connection (CloseStatus: PolicyViolation, description: No message received within timeout).
Once the first message is received, subsequent idle periods will not trigger this mechanism. This rule only filters zombie connections that send no messages after connecting.
Subscribe / Unsubscribe
Subscribe Request
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"method": "order_status_change",
"action": "subscribe",
"api_key": "<your-api-key>",
"timestamp": "1703123456789",
"signature": "<computed-signature>"
}| Field | Type | Required | Description |
|---|---|---|---|
id | UUID | Yes | Client-generated request ID, returned in the response for correlation |
method | string | Yes | Fixed value: "order_status_change" |
action | string | Yes | "subscribe" or "unsubscribe", case-insensitive |
api_key | string | Yes | Institution API key |
timestamp | string | Yes | Unix timestamp in milliseconds |
signature | string | Yes | Request signature. Set as empty string placeholder during signature calculation |
token | string | No | Deprecated. Legacy Maker JWT, kept for backward compatibility only. Use api_key + signature instead |
Note: Each message (both
subscribeandunsubscribe) must carryapi_key,timestamp, andsignaturefor authentication. For signature calculation details, see WebSocket Authentication.
Unsubscribe Request
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"method": "order_status_change",
"action": "unsubscribe",
"api_key": "<your-api-key>",
"timestamp": "1703123456789",
"signature": "<computed-signature>"
}Server Response
Each client request receives a corresponding response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"success": true
}{
"id": "550e8400-e29b-41d4-a716-446655440000",
"success": false,
"message": "Invalid or missing authentication header(s)"
}| Field | Type | Description |
|---|---|---|
id | UUID | null | Corresponding request ID, may be null if parsing failed |
success | boolean | Whether the operation succeeded |
message | string | absent | Error description on failure, absent on success |
Order Status Change Notification
After a successful subscription, when order status changes, you will receive messages in the following format:
{
"type": "order_status_change",
"timestamp": "2026-04-23T03:12:07.119578059Z",
"data": {
"order_hash": "0xb452a5d566ae0ee5ae41ba4b99bbf10b74c4ac6f3a1b3fb92cd6b54d9887bda1",
"maker": "0xC6f20F09C919316518a4EAcE1cB8258bccEa1E3E",
"taker": "0x5fc23eB93208F58e29A1AC493dc15FD0b0Cb5C92",
"from_status": "pending",
"to_status": "locked",
"metadata": {
"blockchain_tx_hash": "0xcf16f0dec7a9ac63bb69c706aca33d32f0631296cc920089ce758f14a4ab0ad9",
"expires_at": "2026-05-23T03:06:57Z",
"lock_id": "636320be-891b-4051-a6a9-0d5b1d11ded2",
"reference_id": "Taker-moawo74x3nw5j2",
"taker_address": "0x5fc23eB93208F58e29A1AC493dc15FD0b0Cb5C92"
}
}
}Message Field Description
| Field | Type | Description |
|---|---|---|
| type | string | Message type: "order_status_change" |
| timestamp | string | Server push time (ISO 8601) |
| data | object | Order status change data |
| data.order_hash | string | Order hash |
| data.maker | string | Maker wallet address |
| data.taker | string | Taker wallet address, may be null |
| data.from_status | string | Previous status, may be null (on order creation) |
| data.to_status | string | New status |
| data.metadata | object | Additional information, may be null |
| data.metadata.blockchain_tx_hash | string | Blockchain transaction hash |
| data.metadata.expires_at | string | Order expiry time |
| data.metadata.lock_id | string | Lock ID |
| data.metadata.reference_id | string | Reference ID |
| data.metadata.taker_address | string | Taker address |
Status Change Trigger Scenarios
1. Order Creation
null→pending: Order created successfullynull→rejected: Order validation failed
2. Taker Operations
pending→locked: Taker locks orderlocked→pending: Taker unlocks orderlocked→rejected: Taker rejects orderpending/locked→partially_filled: Order partially filledpartially_filled→filled: Order fully filled
3. Maker Operations
pending→cancelled: Maker cancels order
4. System Operations
pending→expired: Order automatically expires- Any status →
suspended: System exception, requires manual intervention
Connection Throttling
The server limits concurrent connections per UserId for the order_status_change method. When the limit is exceeded, the server returns:
{
"id": "...",
"success": false,
"message": "Subscription limit reached"
}Throttling thresholds are managed via server-side configuration and are not disclosed in this document.
Server Heartbeat
The server sends heartbeat messages every 30 seconds (configurable) to all active connections. The client does not need to respond:
{
"type": "heartbeat",
"timestamp": 1703123456789
}| Field | Type | Description |
|---|---|---|
type | string | Fixed value: "heartbeat" |
timestamp | number | Server Unix timestamp in milliseconds |
Heartbeat messages keep connections alive and prevent intermediate proxies (e.g., ALB with a 60-second default timeout) from dropping idle connections.
Error Handling
| Error Message | Cause |
|---|---|
Invalid JSON format | Message is not valid JSON |
Invalid request | JSON parsed to null |
Request method can not be empty | method field is empty |
Unknown method: order_status_change | method has no corresponding handler |
Invalid or missing authentication header(s) | Institution credential authentication failed (invalid api_key, expired timestamp, or signature mismatch) |
Subscription limit reached | Throttling limit triggered |