# Websocket API

This API provides websocket support for subscribing to trading data channels such as Ticker (Level 1), Orderbook (Level 2), Orders (Level 3), and Trades (User).\
21x WebSocket API allows a client to subscribe and receive events in near real-time.

### Connection life cycle

* Establish Connection: The client connects to the WebSocket endpoint. If there's a network error, retry with a jittered exponential backoff.
* Initialize: After connecting, the client sends an init message to start communication.
* Acknowledge: The client waits for an acknowledgment message that includes a timeout value for periodic keep-alive (ka) messages.
* Monitor Keep-Alive: The client tracks incoming ka messages. If none are received within the specified timeout, the client closes the connection.
* Subscribe: The client sends a subscribe message to register interest in specific events. Multiple subscriptions are supported per connection.
* Confirm Subscription: The client waits for confirmation messages indicating successful subscriptions.
* Listen for Events: The client receives and processes events as they are published.
* Unsubscribe: The client sends an unsubscribe message to stop receiving events for a subscription.
* Disconnect: Once all subscriptions are unregistered and no messages are pending, the client closes the WebSocket connection.

### WebSocket API Message

All messages are sent and published using `application/json` content type.

**Common fields in the messages**

#### `id`

* **Description**: The client-provided ID of the operation. This property is required and is used to correlate response error and success messages.
* **Requirements**: For subscriptions, this property must be unique for all subscriptions within a connection.
* **Format**: A string limited to a maximum of 128 alphanumeric + special character (\_,+,-) characters.
* **Regex**: `/^[a-zA-Z0-9-_+]{1,128}$/`

#### `type`

* **Description**: The type of operation being performed.
* **Supported Operations**: `subscribe`, `unsubscribe`, `publish`.
* **Details**: Must be one of the message types defined in the "Configuring message details" section.

#### `channel`

* **Description**: The channel to subscribe to events.
* **Format**: A string made up of one to five segments separated by a slash.
  * Each segment is limited to 50 alphanumeric + dash characters.
  * Case sensitive.
* **Examples**: `channelNamespaceName`, `channelNamespaceName/sub-segment-1/subSegment-2`
* **Regex**: `/^\/?[A-Za-z0-9](?:[A-Za-z0-9-]{0,48}[A-Za-z0-9])?(?:\/[A-Za-z0-9](?:[A-Za-z0-9-]{0,48}[A-Za-z0-9])?){0,4}\/?$/`

#### `authorization`

* **Description**: The authorization headers necessary to authorize the operation.
* **Examples**:
  * **ApiKey**: Contains both `host` and `x-api-key`.
  * **IAM**: Contains `host`, `x-amz-date`, `x-amz-security-token`, and `authorization`.

### Channels

Channels allow clients to select and filter the information of interest.\
When subscribing to a given channel wildcard suffix (`*`) can be used to subscribe to all subchannels.

**Example:**`/orders/*` will subscribe the client for notification for all active markets`/order/bytradingpair/ABCXYZ` will subscribe client only for notifications for market ABCXYZ

**Caution:**\
Subscribing for a non-existing market will not result in error. The subscription will be valid however, no data will be available.

***

### Message Details

#### Connection Init Message

* **Description**: After the client establishes the WebSocket connection, the client sends an `init` message to initiate the connection session.

```json
{
  "type": "connection_init"
}
```

#### Connection Acknowledge Message

* **Description**: AWS AppSync responds with an `ack` message containing a connection timeout value.
* **Notes**: If the client doesn’t receive a keep-alive message within the connection timeout period (5 minutes), the client should close the connection.

```json
{
  "type": "connection_ack",
  "connectionTimeoutMs": 300000
}
```

#### Keep-Alive Message

* **Description**: API periodically sends a keep-alive message to maintain the connection.
* **Interval**: 60 seconds.
* **Notes**: Clients do not need to acknowledge these messages.

```json
{
  "type": "ka"
}
```

#### Subscribe Message

* **Description**: After receiving a `connection_ack` message, the client can send a subscription registration message to listen for events on a channel.
* **Properties**:
  * `id`: The unique ID of the subscription per client connection.
  * `channel`: The channel to which the subscribed client is listening.
  * `authorization`: An object containing the fields required for authorization.

```json
{
  "type": "subscribe",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "channel": "/namespace/subB/subC",
  "authorization": {
    "x-api-key": "da2-12345678901234567890123456",
    "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com"
  }
}
```

#### Subscription Acknowledgment Message

* **Description**: Subscription operation acknowledges with a success message.
* **Properties**:
  * `id`: The ID of the corresponding subscribe operation that succeeded.

```json
{
  "type": "subscribe_success",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
}
```

#### Subscription Error Message

* **Description**: Subscription operation error message.

```json
{
  "type": "subscribe_error",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "errors": [
    {
      "errorType": "SubscriptionProcessingError",
      "message": "There was an error processing the operation"
    }
  ]
}
```

#### Data Frame Message

* **Description**: When an event is published to a channel the client is subscribed to, the event is delivered in a data message.
* **Properties**:
  * `id`: The ID of the corresponding subscription for the channel.
  * `event`: The JSON array of stringigifed JSON event objects, each object representing a separate data item

```json
{
  "type": "data",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "event": ["\"...JSON data content...\""]
}
```

* **Error Case**:

```json
{
  "type": "broadcast_error",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "errors": [
    {
      "errorType": "MessageProcessingError",
      "message": "There was an error processing the message"
    }
  ]
}
```

#### Unsubscribe Message

* **Description**: When the client wants to stop listening to a subscribed channel, the client sends an `unsubscribe` message.
* **Properties**:
  * `id`: The ID of the corresponding subscription.

```json
{
  "type": "unsubscribe",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
}
```

#### Unsubscribe Acknowledgment Message

* **Description**: Unsubscribe operation acknowledges with a success message.
* **Properties**:
  * `id`: The ID of the corresponding unsubscribe operation that succeeded.

```json
{
  "type": "unsubscribe_success",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
}
```

#### Unsubscribe Error Message

* **Description**: Unsubscribe operation error message.

```json
{
  "type": "unsubscribe_error",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "errors": [
    {
      "errorType": "UnknownOperationError",
      "message": "Unknown operation id ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
    }
  ]
}
```

#### Disconnecting the WebSocket

* **Description**: Before disconnecting the WebSocket, the client should ensure that no operations are in progress.
* **Recommendations**:
  * Unregister all subscriptions before disconnecting to avoid data loss.

***

### Error handling

**Connection lost**\
Client must detect situation that connection is lost / dropped and reconnect to the server.\
Data frame messages will not be retransmitted.
