Skip to content

Add websockets stream api docs #1074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
82d333a
Add skeleton for new websockets stream api docs
illia-malachyn Jan 7, 2025
935825a
change structure of pages
illia-malachyn Jan 14, 2025
28c11d5
add some up-to-date info
illia-malachyn Jan 21, 2025
3bb8e24
improve some explanations
k1nder10 Jan 22, 2025
16c701b
Added suported topics. Minor fixes
Guitarheroua Feb 19, 2025
29b4230
fixed typos
Guitarheroua Feb 24, 2025
eea4d2f
Apply suggestions from code review
Guitarheroua Feb 27, 2025
b8cd59d
added supported values for block_status
Guitarheroua Feb 27, 2025
de5b5a2
Merge branch 'main' of github.com:The-K-R-O-K/docs into illia-malachy…
Guitarheroua Mar 4, 2025
66e4f76
Moved to correct chapter. Restructure files
Guitarheroua Mar 4, 2025
6c05b39
Merge branch 'onflow:main' into illia-malachyn/6644-new-websockets-st…
Guitarheroua Mar 11, 2025
a9c1115
Restructured supported topics. Added cross linking.
Guitarheroua Mar 11, 2025
d58780c
Improved examples for all bloks and events
Guitarheroua Mar 11, 2025
dee8107
improved account statuses topic documentation
Guitarheroua Mar 11, 2025
ab2a79f
improved ts statuses documentation topic documentation
Guitarheroua Mar 11, 2025
b3b9c8d
Added cross referance for topics
Guitarheroua Mar 11, 2025
21c4bb7
added postman example
Guitarheroua Mar 13, 2025
9c890cd
remove unnecessary files
Guitarheroua Mar 13, 2025
0fe73ad
added common errors page
Guitarheroua Mar 13, 2025
38df4b3
changed uuid to custom id
Guitarheroua Mar 13, 2025
05a8f9b
Apply suggestions from code review
Guitarheroua Mar 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
label: Websockets Stream API
196 changes: 196 additions & 0 deletions docs/networks/access-onchain-data/websockets-stream-api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
---
title: Overview
sidebar_label: Overview
sidebar_position: 1
---

# Websockets Stream API

## Overview

The Stream API allows clients to receive real-time updates from the Flow blockchain via WebSocket connections. It
supports subscribing to various topics, such as blocks, events, and transactions, enabling low-latency access to live
data.

### Important Information

- **Endpoint**: The WebSocket server is available at:
- Mainnet: `wss://rest-mainnet.onflow.org/v1/ws`
- Testnet: `wss://rest-testnet.onflow.org/v1/ws`
- **Limits**:
- Each connection supports up to 20 concurrent subscriptions. Exceeding this limit will result in an error.
- Each subscription may provide up to 20 responses per second.
- After 1 minute of inactivity (no data sent or received) the connection is closed.

- **Supported Topics**:
- `block_digests`
- `block_headers`
- `blocks`
- `events`
- `account_statuses`
- `transaction_statuses`
- `send_and_get_transaction_statuses`

- **Notes**: Always handle errors gracefully and close unused subscriptions to maintain efficient connections.

---

## Setting Up a WebSocket Connection

Use any WebSocket client library to connect to the endpoint. Below is an example using JavaScript:

```javascript
const ws = new WebSocket('wss://rest-mainnet.onflow.org/ws');

ws.onopen = () => {
console.log('Connected to WebSocket server');
};

ws.onclose = () => {
console.log('Disconnected from WebSocket server');
};

ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
```

---

## Subscribing to Topics

To receive data from a specific topic, send a subscription request in JSON format over the WebSocket connection.

### Request Format

```json
{
"subscription_id": "some-id-42",
"action": "subscribe",
"topic": "blocks",
"arguments": {
"block_status": "sealed",
"start_block_height": "123456789"
}
}
```

- **`subscription_id`**(optional): A unique identifier for the subscription (a string with maximum length constraint of 20 characters). If omitted, the server generates one.
- **`action`**: The action to perform. Supported actions include: `subscribe`, `unsubscribe`, `list_subscriptions`.
- **`topic`**: The topic to subscribe to. See the supported topics in the Overview.
- **`arguments`**: Additional topic specific arguments for subscriptions, such as `start_block_height`, `start_block_id`, and others.

### Successful Response Format

```json
{
"subscription_id": "some-id-42",
"action": "subscribe"
}
```

---

## Unsubscribing from Topics

To stop receiving data from a specific topic, send an unsubscribe request.

### Request Format

```json
{
"subscription_id": "some-id-42",
"action": "unsubscribe"
}
```

### Successful Response Format

```json
{
"subscription_id": "some-id-42",
"action": "unsubscribe"
}
```

---

## Listing Active Subscriptions

You can retrieve a list of all active subscriptions for the current WebSocket connection.

### Request Format

```json
{
"action": "list_subscriptions"
}
```

### Successful Response Format

```json
{
"subscriptions": [
{
"subscription_id": "some-id-1",
"topic": "blocks",
"arguments": {
"block_status": "sealed",
"start_block_height": "123456789"
}
},
{
"subscription_id": "some-id-2",
"topic": "events",
"arguments": {}
}
]
}
```

---

## Errors Example

If a request is invalid or cannot be processed, the server responds with an error message.

### OK Response

```json
{
"subscription_id": "some-id-42",
"topic": "block_digests",
"payload": {
"id": "0x1234...",
"height:": "123456789",
"timestamp": "2025-01-02T10:00:00Z"
}
}
```

### Error Response

```json
{
"subscription_id": "some-id-42",
"error": {
"code": 500,
"message": "Access Node failed"
}
}
```

### Common Error Codes

- **400**: Invalid message format or arguments
- **404**: Subscription not found
- **500**: Internal server error

### Asynchronous environments

If you're working in an asynchronous environment, the Streaming API ensures **first-in first-out** message processing,
so responses will be returned in the same order the requests were received over the connection.
You can leverage this feature to simplify your code and maintain consistency.

Additionally, you can specify a custom `subscription_id` in the subscribe request to easily identify the correct response. It must not be an empty string and must follow a maximum length constraint of 20 characters.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: List subscriptions request message format
sidebar_label: Listing subscriptions
sidebar_position: 4
---

# List subscriptions message format

List subscriptions requests must be sent as JSON in text frames, one request per frame.
This message is different from others as it doesn't require you to provide subscription ID.
Thus, the response for this message is different too.

### Example of request

```json
{
"action": "list_subscriptions"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@illia-malachyn illia-malachyn Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! Good catch!
I opened a PR onflow/flow-go#7317

}
```

### Example of response

```json
{
"subscriptions": [
{
"subscription_id": "uuid-1",
"topic": "blocks",
"arguments": {
"block_status": "finalized",
"start_block_height": "123456789"
}
},
{
"subscription_id": "uuid-2",
"topic": "events",
"arguments": {}
}
]
}
```

If there are no active subscriptions, `subscriptions` array will be empty.

### Request fields

| Name | Type | Required | Description |
|----------|--------|----------|-----------------------------------------------------------------------------------------|
| `action` | STRING | YES | Action to perform. Must be `list_subscriptions` to initiate a list subscription request |
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
title: Subscribe request message format
sidebar_label: Subscribing to topic
sidebar_position: 2
---

# Subscribe request format

Subscribe requests must be sent as JSON in text frames, one request per frame.


### Example of subscribe request

```json
{
"subscription_id": "some-id-1",
"action": "subscribe",
"topic": "block_digests",
"arguments": {
"block_status": "finalized",
"start_block_height": "99,416,580"
}
}
```

### Example of successful response

```json
{
"subscription_id": "some-id-1",
"action": "subscribe"
}
```

### Example of failed response

```json
{
"subscription_id": "some-id-1",
"error": {
"code": 400,
"message": "invalid message"
}
}
```

### Example of messages provided by subscription (if successful)

```json
{
"subscription_id": "some-id-1",
"topic": "block_digests",
"payload": {
"id": "0x1234...",
"height:": "123456789",
"timestamp": "2025-01-02T10:00:00Z"
}
}
```

### Example of messages provided by subscription (if error)

```json
{
"subscription_id": "some-id-1",
"error": {
"code": 500,
"message": "internal error"
}
}
```

### Request fields:

| Name | Type | Required | Description |
|-------------------|--------|----------|-----------------------------------------------------------------------------------------------------------------------------------|
| `subscription_id` | STRING | NO | Optional unique identifier for the subscription. Max length of ID generated by client is 20 characters. Server will generate a unique ID if omitted |
| `action` | STRING | YES | Action to perform. Must be `subscribe` to initiate a subscription |
| `topic` | STRING | YES | The topic to subscribe to, such as `blocks`, `block_digests`, etc. |
| `arguments` | STRING | NO | Additional topic specific parameters for the subscription, such as `start_block_id`, `start_block_height` or other. |

You can use `subscription_id` as a client-generated identifier to track responses asynchronously.
If you don't provide `subscription_id`, the server will generate one and include it in the response.
Loading