# Websocket API

To establish websocket connection use the endpoint wss\://trade.finerymarkets.com/ws (or wss\://test.finerymarkets.com/ws for test environment)

* WS allows binding to incremental data feed
* WS allows to execute any REST method with a `request` message
* Connection idle timeout is 80 sec.
* Maximum 100 connections per IP are allowed.

### Connect Websocket

Generate API keys to authenticate websocket connections. To connect a websocket additional headers are required:

`EFX-Key`: your public key

`EFX-Sign`: content signature. Sign the payload string with your private key using HMAC SHA384.

`EFX-Content`: JSON string that contains nonce and timestamp.

Generate a signature to authenticate the websocket connection. Send headers `EFX-Key`, `EFX-Sign`, and `EFX-Content` when connecting websocket (*nodejs with CryptoJS lib*):

```javascript
// Put your API keys there
const key = "RlZ4sKsHSr5zmYKIzbtf772J9y9gx8nekd8COrawI5V"
const secret = "cZpZ1vwzOaXuiONfIQVg8h6za97FoHhrwwgoSCNwDAR"

let content = JSON.stringify({
    "nonce": 12345,
    "timestamp": new Date().valueOf()
})

let signature = CryptoJS.HmacSHA384(content, secret).toString(CryptoJS.enc.Base64)

this.client = new WebSocketClient(this.host, null, null, {
    'EFX-Key': key,
    'EFX-Sign': signature,
    'EFX-Content': content
})
```

If handshake error occurs when connecting a websocket, check what has been sent in response body. It could be authentication error. See the following pages to handle most common authentication errors:

{% content-ref url="troubleshooting-errors/error-6" %}
[error-6](https://faq.finerymarkets.com/api-reference/troubleshooting-errors/error-6)
{% endcontent-ref %}

{% content-ref url="troubleshooting-errors/error-7" %}
[error-7](https://faq.finerymarkets.com/api-reference/troubleshooting-errors/error-7)
{% endcontent-ref %}

**Connection status**

After connection you will receive either...

```javascript
['X', 0, 'Z', 0] - which means that WS backend's connection to Finery Markets is established
```

Or...

```javascript
['X', 0, 'Z', <non-zero error code>] - which means that WS backend's connection to Finery Markets is not established
```

While connected you may receive...

```javascript
['X', 0, 'Z', 0] - after WS backend connects to Finery Markets

['X', 0, 'Z', <non-zero error code>] - after WS backend disconnects from Finery Markets
```

**Cancel-on-Disconnect**

CoD functionality means that all active orders will be cancelled by the Platform if the connection is lost. If multiple connections are used, only those orders will be cancelled, which are placed via the lost connection.

**Errors**

WS feed updates indicate a failure when a third element of an array is `Z` (i.e., failed to subscribe). WS commands `bind` and `unbind` indicate a failure when a third element of an array is `Z` (i.e., failed to subscribe and failed to unsubscribe respectively).&#x20;

### Feeds

To receive market data and other live updates you have to subscribe feeds. There are general steps to work with any feed:

* *Subscription*. To receive data from a channel you have to send a `bind` message first
* *Snapshot*. Upon subscribing to a channel an initial snapshot is sent
* *Update*. After receiving the snapshot, you will receive updates upon any change
* *Unsubscription*. To stop receiving data from a channel you have to send a `unbind` message

Subscribe feed example:

```javascript
data = {
        "event": "bind",
        "feed": "B",
        "feedId": 42,
    }
const payload = JSON.stringify(data)
ws_client.send(payload)
```

Unsubscribe feed example:

```javascript
data = {
        event: "unbind",
        feed: "B",
        feedId: 42,
}
const payload = JSON.stringify(data)
ws_client.send(payload)
```

### Requests

It is possible to send the same requests as with the REST API. Use `"event": "request"`, add `"method"` and `"content"` filed as in the example below:

```javascript
data = {
        event: "request",
        reqId: 1234,
        method: "add",
        content: {
            instrument: "BTC-EUR",
            clientOrderId: 1,
            size: 100000,
            side: side,
            type: "marketIOC",
            cod: False
        }
}
        
const payload = JSON.stringify(data)
ws_client.send(payload)
```

{% hint style="danger" %}
Use empty JSON if the are no parameters in the request.\
Example: `content : {}`
{% endhint %}
