Studio offers WebSocket APIs for receiving streaming updates. This section should help you familiarize yourself with how develop against our WebSocket APIs. Our WebSockets APIs are organized by channels, and these channels belong to a specific API group within Studio.

Servers

Our WebSocket servers works over TLS to secure communications. We provide both a Sandbox and a Production environment with the Sandbox environment providing a safe way to explore the product without submitting live orders.

URLDescription
wss://api.clearstreet.io/studio/v2/wsProduction URL
wss://sandbox-api.clearstreet.io/studio/v2/wsSandbox URL

📘

To obtain access to our Sandbox environment, please send an email to [email protected] with the request along with all IP addresses you plan to connect from.

Authentication

The authentication mechanism with WebSockets is different than the method used by our normal REST APIs. What is common, however, is the OAuth2 process of obtaining an access token.

Once you have an access token, and connect to our WebSocket server, you need to subscribe to a channel with a subscription request that has your access token. If the access token is valid for the channel you're subscribing to, then data will start flowing immediately.

Subscription Example

$ wscat -c wss://api.clearstreet.io/studio/v2/ws
Connected (press CTRL+C to quit)
> { "authorization": "<access-token>", "payload": { "type": "subscribe-activity", "account_id": "<my-account>" }}
< < {"timestamp":1711073665833,"payload":{"type":"subscribe-activity-ack","success":true,"details":"Successfully subscribed"}}

The above example uses the command-line tool wscat to connect to our WebSocket servers. After connecting, we are sending a subscription request for the "Orders channel". Critically, we include our <access-token> in the authorization field of the message. When the server receives your subscription, it will validate your access token and ensure that you are authorized to view order information on the given account.

You can send multiple channel subscription requests on the same connection.

Channels

These are the channels that are currently available. For details of the messages that flow in these channels, please check the linked API Reference guide.

Channel NameDescriptionAPI Group
ActivityProvides trading related activityExecution API

Timeouts

After establishing a connection to a WebSocket, you have 30 seconds to subscribe to a channel. After 30 seconds, the server will automatically disconnect your connection if you haven't subscribed.

Idle Timeout Example

$ wscat -c wss://api.clearstreet.io/studio/v2/ws
Connected (press CTRL+C to quit)
< {"timestamp":1711076847030,"payload":{"type":"error-notice","details":"Idled too long; please reconnect"}}
Disconnected (code: 1000, reason: "")

Once you have subscribed to your first channel, the connection will exist for the remainder of the time left on your access token. All access tokens expire after a certain period, which is currently 24 hours from time of creation. Your WebSocket connection will terminate when your token expires.

Expired Token Example

$ wscat -c wss://api.clearstreet.io/studio/v2/ws
Connected (press CTRL+C to quit)
< {"timestamp":1711076847030,"payload":{"type":"error-notice","details":"Auth expired; please reconnect"}}
Disconnected (code: 1000, reason: "")

Heartbeats

This is a common message you can receive on any channel. It's sent from the server to you to let you know that the session is still alive.

{
  "timestamp": 1711076847030,
  "payload": {
    "type": "heartbeat",
  }
}
FieldTypeRequiredDescription
timestampintYesMilliseconds since epoch timestamp of when the server sent the message.
payload.typestringYesAlways heartbeat
payload.detailsstringYesDetails of the error.

Error Notices

This is a common message you can receive on any channel. You'll receive this message when something has gone wrong. Depending on the error, your WebSocket might be disconnected by the server immediately after receipt of this message.

{
  "timestamp": 1711076847030,
  "payload": {
    "type": "error-notice",
    "details": "<details>"
  }
}
FieldTypeRequiredDescription
timestampintYesMilliseconds since epoch timestamp of when the server sent the message.
payload.typestringYesAlways error-notice
payload.detailsstringYesDetails of the error.