diff --git a/docs/networks/access-onchain-data/websockets-stream-api/_category_.yml b/docs/networks/access-onchain-data/websockets-stream-api/_category_.yml new file mode 100644 index 0000000000..9173e0239d --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/_category_.yml @@ -0,0 +1,2 @@ +label: "WebSockets Stream API" +position: 3 diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_1.png b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_1.png new file mode 100644 index 0000000000..2055821642 Binary files /dev/null and b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_1.png differ diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_2.png b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_2.png new file mode 100644 index 0000000000..73730ff888 Binary files /dev/null and b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_2.png differ diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_3.png b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_3.png new file mode 100644 index 0000000000..4e5ed46cc6 Binary files /dev/null and b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_3.png differ diff --git a/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_4.png b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_4.png new file mode 100644 index 0000000000..46a3531123 Binary files /dev/null and b/docs/networks/access-onchain-data/websockets-stream-api/assets/pe_4.png differ diff --git a/docs/networks/access-onchain-data/websockets-stream-api/common-errors.md b/docs/networks/access-onchain-data/websockets-stream-api/common-errors.md new file mode 100644 index 0000000000..125289510b --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/common-errors.md @@ -0,0 +1,85 @@ +--- +title: Common errors +sidebar_label: Common errors +sidebar_position: 7 +--- + +This document outlines the possible errors returned from the WebSocket API. Understanding these errors will help properly handle error cases in client implementation. + +## Error Structure + +All errors returned by the WebSocket API follow this structure: + +```json +{ + "subscriptionID": "string", + "error": { + "code": number, + "message": "string" + }, + "action": "string" +} +``` + +Where: +- `subscriptionID`: The ID of the subscription related to the error (if applicable) +- `error.code`: HTTP status code indicating the error type +- `error.message`: Human-readable description of the error +- `action`: The action that was being performed when the error occurred (`subscribe`, `unsubscribe`, or `list_subscription`) + + +### Message Format Errors + +**Status Code:** 400 Bad Request + +These errors occur when the server cannot parse or validate your incoming message. + +| Error Message | Description | When to Expect | +|---------------|-------------|---------------| +| *"error reading message: ..."* | The raw message could not be read from the WebSocket connection | When sending malformed JSON or when the connection is disrupted | +| *"error parsing message: ..."* | The message was read but could not be processed | When the message structure doesn't match the expected format | +| *"error unmarshalling base message: ..."* | The message JSON could not be processed into the expected format | When required fields are missing or of incorrect type | +| *"error unmarshalling subscribe message: ..."* | The message JSON could not be processed into a subscribe request | When sending a malformed subscribe request | +| *"error unmarshalling unsubscribe message: ..."* | The message JSON could not be processed into an unsubscribe request | When sending a malformed unsubscribe request | +| *"error unmarshalling list subscriptions message: ..."* | The message JSON could not be processed into a list subscriptions request | When sending a malformed list subscriptions request | +| *"unknown action type: ..."* | The action specified in the message is not recognized | When specifying an action other than `subscribe`, `unsubscribe`, or `list_subscription` | + +## Subscription-Related Errors + +### Subscribe Action Errors + +**Action:** `subscribe` + +| Error Message | Status Code | Description | When to Expect | +|---------------|-------------|-------------|---------------| +| *"error creating new subscription: maximum number of subscriptions reached"* | 429 Too Many Requests | The maximum number of active subscriptions per connection has been reached | When trying to create more subscriptions than allowed by the server | +| *"error parsing subscription id: ..."* | 400 Bad Request | The provided subscription ID is invalid | When providing a malformed subscription ID | +| *"subscription ID is already in use: ..."* | 400 Bad Request | The provided subscription ID is already being used | When trying to reuse an existing subscription ID | +| *"error creating data provider: ..."* | 400 Bad Request | The subscription could not be created | When providing an invalid topic or arguments for your subscription | + +### Unsubscribe Action Errors + +**Action:** "unsubscribe" + +| Error Message | Status Code | Description | When to Expect | +|---------------|-------------|-------------|---------------| +| *"error parsing subscription id: ..."* | 400 Bad Request | The provided subscription ID is invalid | When providing a malformed subscription ID | +| *"subscription not found"* | 404 Not Found | The specified subscription does not exist | When trying to unsubscribe from a non-existent subscription | + +### Subscription Runtime Errors + +**Action:** "subscribe" + +| Error Message | Status Code | Description | When to Expect | +|---------------|-------------|-------------|---------------| +| *"internal error: ..."* | 500 Internal Server Error | An error occurred while processing your subscription | When there's an issue with the subscription after it was successfully created | + +## Error Handling Best Practices + +1. **Always check for errors in responses**: Every response from the WebSocket API should be checked for the presence of an error object. + +2. **Handle subscription limits**: Be prepared to handle the case where the maximum number of subscriptions has been reached. + +3. **Log detailed error information**: Log the complete error object for debugging purposes. + +4. **Validate messages before sending**: Ensure your messages conform to the expected format to avoid parsing errors. \ No newline at end of file diff --git a/docs/networks/access-onchain-data/websockets-stream-api/index.md b/docs/networks/access-onchain-data/websockets-stream-api/index.md new file mode 100644 index 0000000000..a6f61765c6 --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/index.md @@ -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**: See more details on [Supported Topics](supported-topics/index.md) page. + - [`block_digests`](supported-topics/block_digests_topic.md) + - [`block_headers`](supported-topics/block_headers_topic.md) + - [`blocks`](supported-topics/blocks_topic.md) + - [`events`](supported-topics/events_topic.md) + - [`account_statuses`](supported-topics/account_statuses_topic.md) + - [`transaction_statuses`](supported-topics/transaction_statuses_topic.md) + - [`send_and_get_transaction_statuses`](supported-topics/send_and_get_transaction_statuses_topic.md) + +- **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. See more details about arguments for each topic on [Supported Topics](supported-topics/index.md) page. + +### 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. \ No newline at end of file diff --git a/docs/networks/access-onchain-data/websockets-stream-api/list-subscriptions-message.md b/docs/networks/access-onchain-data/websockets-stream-api/list-subscriptions-message.md new file mode 100644 index 0000000000..8426c3232b --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/list-subscriptions-message.md @@ -0,0 +1,49 @@ +--- +title: List subscriptions request message format +sidebar_label: Listing subscriptions +sidebar_position: 5 +--- + +# 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" +} +``` + +### Example of response + +```json +{ + "subscriptions": [ + { + "subscription_id": "some-id-1", + "topic": "blocks", + "arguments": { + "block_status": "finalized", + "start_block_height": "123456789" + } + }, + { + "subscription_id": "some-id-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 | diff --git a/docs/networks/access-onchain-data/websockets-stream-api/postman-example.md b/docs/networks/access-onchain-data/websockets-stream-api/postman-example.md new file mode 100644 index 0000000000..d9bf7cb91a --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/postman-example.md @@ -0,0 +1,51 @@ +--- +title: Connecting to WebSockets via Postman UI +sidebar_label: Connecting to WebSockets via Postman UI +sidebar_position: 6 +--- + +This tutorial will guide you through connecting to a WebSocket using Postman and sending a subscription message. + +## Step 1: Open Postman + +Ensure you have Postman installed and opened on your system. If you don’t have it yet, download it from [Postman’s official website](https://www.postman.com/downloads/). + +## Step 2: Create a New WebSocket Request + +1. In Postman, click on **File** > **New...** > **WebSocket**. +![pe_1]() +2. Enter the WebSocket URL in **Enter URL** field : `wss://rest-mainnet.onflow.org/v1/ws` or `wss://rest-testnet.onflow.org/v1/ws` +3. Click **Connect** button to establish the WebSocket connection. +![pe_2]() + +## Step 3: Send a Subscription Message + +1. Once connected, go to the **Messages** tab. +2. Enter the JSON message into the text box. In this example the [digests block subscription](./supported-topics/block_digests_topic.md) will be established. For other available topics check [Supported topics page](./supported-topics/index.md). +3. Click **Send** to subscribe to the WebSocket topic. +![pe_3]() + +## Step 4: View Responses + +- After sending the message, you should start receiving responses in the **Response** bottom tab. +- Each message received from the server will be displayed in real-time. + +![pe_4]() + +## Step 5: Disconnect + +- When you are done, click **Disconnect** to close the WebSocket connection. + +## Troubleshooting + +- Ensure WebSocket URL is correct and active. +- In case of an error validate your JSON message for any syntax errors before sending and check correctness of all arguments on [Supported topics page](./supported-topics/index.md). + +Congratulations! You have successfully connected to a WebSocket server using Postman and sent a subscription message. + + + + + + + diff --git a/docs/networks/access-onchain-data/websockets-stream-api/subscribe-message.md b/docs/networks/access-onchain-data/websockets-stream-api/subscribe-message.md new file mode 100644 index 0000000000..255438de75 --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/subscribe-message.md @@ -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": "99416580" + } +} +``` + +### 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. See more details on [Supported Topics](supported-topics/index.md) page. | +| `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. diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml new file mode 100644 index 0000000000..72660ebdb1 --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/_category_.yml @@ -0,0 +1,2 @@ +label: "Supported topics" +position: 4 diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md new file mode 100644 index 0000000000..9645c64a3d --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/account_statuses_topic.md @@ -0,0 +1,106 @@ +--- +title: Account statuses +sidebar_label: Account statuses +sidebar_position: 6 +--- + +Provides accounts statuses updates. The response can be configured using additional arguments to filter and retrieve only filtered account statuses instead of all core account events. + +## Example Request + +Started from latest block for event types `flow.AccountKeyAdded` and `flow.AccountKeyRemoved`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "account_statuses", + "arguments": { + "event_types": [ + "flow.AccountKeyAdded", + "flow.AccountKeyRemoved" + ] + } +} +``` + +Started from block height `106219488` for all accounts events with heartbeat interval equal 10 blocks: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "account_statuses", + "arguments": { + "start_block_height": "106219488", + "heartbeat_interval": "10" + } +} +``` + +Started from block id `f1ba2fb02daf02c7a213b6b0f75774aaf54180ae67fb62bdf22ae37295fe1120` for account addresses `0xe544175ee0461c4b` and `2d4c3caffbeab845` with heartbeat interval equal 5 blocks: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "account_statuses", + "arguments": { + "start_block_id": "f1ba2fb02daf02c7a213b6b0f75774aaf54180ae67fb62bdf22ae37295fe1120", + "heartbeat_interval": "5", + "account_addresses": [ + "0xe544175ee0461c4b", + "2d4c3caffbeab845" + ] + } +} +``` + +### Request Arguments + +| Name | Type | Required | Description | +| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `start_block_id` | STRING | NO | The ID of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_height`. | | +| `start_block_height` | STRING | NO | The height of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_id` | +| `heartbeat_interval` | STRING | NO | Maximum number of blocks between messages after which a response with no events is returned. This helps the client track progress for sparse event filters. | +| `event_types` | LIST | NO | A comma-separated list of event types to include. See the list of possible event types value [below](#the-list-of-possible-core-event-types). | +| `account_addresses` | LIST | NO | A comma-separated list of addresses who's events should be included. The format could be `"0xe544175ee0461c4b"` or `"e544175ee0461c4b"`. | + +If neither `start_block_id` nor `start_block_height` is set, the subscription will start from the latest block based on its status. + +#### The list of possible core event types + +- `flow.AccountCreated` emitted when a new account gets created. +- `flow.AccountKeyAdded` emitted when a key gets added to an account. +- `flow.AccountKeyRemoved` emitted when a key gets removed from an account. +- `flow.AccountContractAdded` emitted when a contract gets deployed to an account. +- `flow.AccountContractUpdated` emitted when a contract gets updated on an account. +- `flow.AccountContractRemoved` emitted when a contract gets removed from an account. +- `flow.InboxValuePublished` emitted when a Capability is published from an account. +- `flow.InboxValueUnpublished` emitted when a Capability is unpublished from an account. +- `flow.InboxValueClaimed` emitted when a Capability is claimed by an account. + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "account_statuses", + "payload": { + "block_id": "ab20d1a3574177e69636eea73e7db4e74cffb2754cb14ca0bf18c2b96e8b68b9", + "height": "106219247", + "account_events": { + "0x37d2b958f6970c48": [ + { + "type": "flow.AccountKeyAdded", + "transaction_id": "19af79cf2fe081491f1e7b0bf490869c8baece742c6606b4a51383515131b5f0", + "transaction_index": "1", + "event_index": "14", + "payload": "2IGChNigg0BpUHVibGljS2V5goJpcHVibGljS2V52IvYiQyCcnNpZ25hdHVyZUFsZ29yaXRobdiIQQLYpINBAW1IYXNoQWxnb3JpdGhtgYJocmF3VmFsdWXYiQzYpINBAnJTaWduYXR1cmVBbGdvcml0aG2BgmhyYXdWYWx1ZdiJDNiig0EDdGZsb3cuQWNjb3VudEtleUFkZGVkhYJnYWRkcmVzc9iJA4JpcHVibGljS2V52IhAgmZ3ZWlnaHTYiReCbWhhc2hBbGdvcml0aG3YiEEBgmhrZXlJbmRleNiJBILYiEEDhUg30rlY9pcMSIKYQBjBGFoYKhg8GLoAGEIHGHAYYREYoBirGKsYiRhrGDAY3xiTGLkUGJYYdRixGOwYjxjNGCkAExhRGCoY/xgfEBh/GJ0YtxjBGH8YLxiqGD4JGKIY6xgmDhiUGDEYqRhvGCYY8hitGMEWGKwY6RiEGF4YQRhBGKGBAhsAAAAXSHboAIEBwkA=" + } + ] + }, + "message_index": 4 + } +} +``` diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md new file mode 100644 index 0000000000..f7163d183c --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_digests_topic.md @@ -0,0 +1,74 @@ +--- +title: Block digests +sidebar_label: Block digests +sidebar_position: 2 +--- + +Provides a summarized version of block information, including only the block ID, height, and timestamp, each time a new block appears on the blockchain. + +## Example Request + +Started from latest block: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "block_digests", + "arguments": { + "block_status": "sealed" + } +} +``` + +Started from block height `106192109`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "block_digests", + "arguments": { + "block_status": "sealed", + "start_block_height": "106192109" + } +} +``` + +Started from block id `37193c008576c5f9e3fb9738d4cc53c9ca021ca593e437eb79107c13ec5a1758`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "block_digests", + "arguments": { + "block_status": "sealed", + "start_block_id": "37193c008576c5f9e3fb9738d4cc53c9ca021ca593e437eb79107c13ec5a1758" + } +} +``` + +### Request Arguments + +| Name | Type | Required | Description | +| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `block_status` | STRING | YES | The status of blocks to subscribe to. Supported values are: `sealed`, `finalized`. | +| `start_block_id` | STRING | NO | The ID of the block from which the subscription starts. If this argument is set, `start_block_height` MUST be empty. | | +| `start_block_height` | STRING | NO | The height of the block from which the subscription starts. If this argument is set, `start_block_id` MUST be empty. | + +If neither `start_block_id` nor `start_block_height` is set, the subscription will start from the latest block based on its status. + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "block_digests", + "payload": { + "block_id": "311ca4b8530fad041356ace3ba27cd6ca8bed53d166b4cefdde4c3ae414940d5", + "height": "106190012", + "timestamp": "2025-03-11T11:08:58.504803374Z" + } +} +``` \ No newline at end of file diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md new file mode 100644 index 0000000000..0f1a027486 --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/block_headers_topic.md @@ -0,0 +1,76 @@ +--- +title: Block headers +sidebar_label: Block headers +sidebar_position: 3 +--- + +Provides block headers without the payload, each time a new block appears on the blockchain. + +## Example Request + +Started from latest block: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "block_headers", + "arguments": { + "block_status": "finalized" + } +} +``` + +Started from block height `106195326`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "block_headers", + "arguments": { + "block_status": "finalized", + "start_block_height": "106195326" + } +} +``` + +Started from block id `cb27b014fa105a1e0e64d56cfbe2d7e140f4adf32938e38c3459592d01a72e91`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "block_headers", + "arguments": { + "block_status": "finalized", + "start_block_id": "cb27b014fa105a1e0e64d56cfbe2d7e140f4adf32938e38c3459592d01a72e91" + } +} +``` + +### Request Arguments + +| Name | Type | Required | Description | +| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `block_status` | STRING | YES | The status of blocks to subscribe to. Supported values are: `sealed`, `finalized`. | +| `start_block_id` | STRING | NO | The ID of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_height`. | | +| `start_block_height` | STRING | NO | The height of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_id` | + +If neither `start_block_id` nor `start_block_height` is set, the subscription will start from the latest block based on its status. + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "block_headers", + "payload": { + "id": "5cd0b1d0a0f0017c25647a6e2454a59aafa90682f2329449a610e19673ba07de", + "parent_id": "72ecd7cf6b18488b3597e677c5fa620d2dfad981fdd81b5cdb1851490b0cff56", + "height": "106195236", + "timestamp": "2025-03-11T12:18:39.702990376Z", + "parent_voter_signature": "+GyIAAAAAAAAAACwsabEiORFcP/ru95TABxwxXsxnUtJNoUbGB1xKKNtpR/LNUqDL5TyIQjL3xBl5KtKgLCFde8F5DHtUSGYSQUzaGhv+IoQgh1wgbXlY/soY5T30/HwmrucwD925EKOJAQUj7s=" + } +} +``` diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md new file mode 100644 index 0000000000..d16dee305a --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/blocks_topic.md @@ -0,0 +1,169 @@ +--- +title: Blocks +sidebar_label: Blocks +sidebar_position: 4 +--- + +Provides full block information each time a new block appears on the blockchain. + +## Example Request + +Started from latest block: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "blocks", + "arguments": { + "block_status": "sealed" + } +} +``` + +Started from block height `106192109`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "blocks", + "arguments": { + "block_status": "sealed", + "start_block_height": "106192109" + } +} +``` + +Started from block id `83a8229cbe552f9b10160163394986dc7d99790ad3fedf7db4153d7d7863a3fa`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "blocks", + "arguments": { + "block_status": "sealed", + "start_block_id": "83a8229cbe552f9b10160163394986dc7d99790ad3fedf7db4153d7d7863a3fa" + } +} +``` + +### Request Arguments + +| Name | Type | Required | Description | +| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `block_status` | STRING | YES | The status of blocks to subscribe to. Supported values are: `sealed`, `finalized`. | +| `start_block_id` | STRING | NO | The ID of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_height`. | | +| `start_block_height` | STRING | NO | The height of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_id` | + +If neither `start_block_id` nor `start_block_height` is set, the subscription will start from the latest block based on its status. + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "blocks", + "payload": { + "header": { + "id": "7a7bc4dc574f67f0dc01a6c96cfbabe73ead23f76ac8130e620996779a500925", + "parent_id": "70b7f0a8c14e9f374eaf2f37da4dee7815c8639b3f9e67c301e84cf7fb51070c", + "height": "106195712", + "timestamp": "2025-03-11T12:25:00.450424315Z", + "parent_voter_signature": "+GyIAAAAAAAAAACwobZq2GxrWxPUuNJwo5T1pFWvwcAF4/ue8e7j7eFTcRhtReHV+dWnneyGtJdpuaIagLCEfjHvfItzt3J/kXsbdEFeycVBeznP4LIHs0XWWkeRn+yds4NAM8jltmGGBnvgJ68=" + }, + "payload": { + "collection_guarantees": [ + { + "collection_id": "74d146368179f95a49531072cda799d1c0905523fd5a35c224eefbd92fab6a90", + "signer_indices": "71d9de679d7ff457a0", + "signature": "" + }, + { + "collection_id": "b4b40fa4bd5a98cc5f61924aa63a98c588f56447cec5bcdad538e0a855f1a0f3", + "signer_indices": "710746ee7fd5f7a540", + "signature": "" + } + ], + "block_seals": [ + { + "block_id": "71418383aefda2df4da5fabb03d5ff0e8778f83783c5566c1110ba4a4d6e8de3", + "result_id": "35f480934324280f6eebd6016b143bc28cecb8f71fcd8262153320ad93b16c61", + "final_state": "\"0cc68829215fb9d69641537a317787b4ff805fe07d2f9ce12534b87d7d0f1335\"", + "aggregated_approval_signatures": [ + { + "verifier_signatures": [ + "rF6XjkIxY8lYD1vZvUycBtT+9DNY4d0U+p1q6WxiA8siYuFawrThkEIkLA3lYPjz" + ], + "signer_ids": [ + "80a0eaa9eb5fd541b2abbd1b5ffa79f0ae9a36973322556ebd4bdd3e1d9fe4cd" + ] + }, + { + "verifier_signatures": [ + "j2Y94dVrZZT1qNuK1ZbTOxj5HfNZxmV5zVBA3uwTKrQ4FFQ6gN0na1nXhZDJN1po" + ], + "signer_ids": [ + "e7e46cd698170b1f86bc9116dded0ac7df6ea0d86c41788c599fa77072059ea1" + ] + }, + { + "verifier_signatures": [ + "jp1/x2dr+LVS6Wl3ScaabsxD8745sb1kec3FUrj0SVXGEFnS7AUvG5RTKfsdF6m3" + ], + "signer_ids": [ + "49c9f946170d5fb40c2af953b1534fae771905865b142ab6ac9685b8ba5b51c1" + ] + }, + { + "verifier_signatures": [ + "rogMdMXwEKJvMUxdHcFqseW9VGVmNzya51kI8yoc8M0kPfuRfENqfgY1NuQBVn3N" + ], + "signer_ids": [ + "a1e6a5d9385d549f546803566747463e616e1d02ade2fcadba1b49c492ec8f29" + ] + }, + { + "verifier_signatures": [ + "seNSZjDBI7P4730jLcMWp1cq5XjSoSao9KLmrevSz2voQ+92Fcf7HqcSIpiF5CLi" + ], + "signer_ids": [ + "8f8d77ba98d1606b19fce8f6d35908bfc29ea171c02879162f6755c05e0ca1ee" + ] + } + ] + }, + { + "block_id": "9735518c51b170372fc3d04a6e360fef8b7f987fdb5f1e0f84d9a065d21a550c", + "result_id": "328efa584043b0042b32b5e53c4d3c56988387440d94e9507d0a8d24a0f31e82", + "final_state": "\"e1fb1b23de61b1cd83f22ffbcdd14a1844332d2e730e01df519c43ea3565bc3a\"", + "aggregated_approval_signatures": [ + { + "verifier_signatures": [ + "tchbJMwDd92Ui2UXnGPL20rEsTrkHQIYsYPZDAgR7O/9lRZh/u/5Y/7JN9+AiMwP" + ], + "signer_ids": [ + "0a29d8eb288d9bb0a0a4f2f9ff180ec83617659998ce363814048ec1683083e0" + ] + }, + { + "verifier_signatures": [ + "q07CVWjMP1ocBmShFFZ9K5SYIwBitF8g5gajVkOJ0t+O8twzbtW7SjWPY8NIWKyp" + ], + "signer_ids": [ + "446ae6d5ebdf6bc45aee29ed3b8da8dcf155afff87296401a3c0a28206121bcc" + ] + } + ] + } + ] + }, + "_expandable": {}, + "_links": { + "_self": "/v1/blocks/7a7bc4dc574f67f0dc01a6c96cfbabe73ead23f76ac8130e620996779a500925" + }, + "block_status": "BLOCK_SEALED" + } +} +``` diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md new file mode 100644 index 0000000000..3a2cdbc604 --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/events_topic.md @@ -0,0 +1,112 @@ +--- +title: Events +sidebar_label: Events +sidebar_position: 5 +--- + +Provides blockchain events. The response can be configured using additional arguments to filter and retrieve only filtered events instead of all events. + +## Example Request + +Started from latest block for event types `flow.AccountKeyAdded` and `flow.AccountKeyRemoved`: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "events", + "arguments": { + "event_types": [ + "flow.AccountKeyAdded", + "flow.AccountKeyRemoved" + ] + } +} +``` + +Started from block height `106197172` for contracts `A.f919ee77447b7497.FlowFees` and `A.1654653399040a61.FlowToken` with heartbeat interval equal 10 blocks: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "events", + "arguments": { + "start_block_height": "106197172", + "heartbeat_interval": "10", + "contracts": [ + "A.f919ee77447b7497.FlowFees", + "A.1654653399040a61.FlowToken" + ] + } +} +``` + +Started from block id `44774d980c75d9380caaf4c65a2ee6c4bde9a1e6da6aa858fe2dc5e4a7aff773` for account addresses `0xe544175ee0461c4b` and `2d4c3caffbeab845` with heartbeat interval equal 5 blocks: + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "events", + "arguments": { + "start_block_id": "44774d980c75d9380caaf4c65a2ee6c4bde9a1e6da6aa858fe2dc5e4a7aff773", + "heartbeat_interval": "5", + "addresses": [ + "0xe544175ee0461c4b", + "2d4c3caffbeab845" + ] + } +} +``` + +### Request Arguments + +| Name | Type | Required | Description | +| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| `start_block_id` | STRING | NO | The ID of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_height`. | | +| `start_block_height` | STRING | NO | The height of the block from which the subscription starts. If this argument is set, it is **not** possible to set `start_block_id` | +| `heartbeat_interval` | STRING | NO | Maximum number of blocks between messages after which a response with no events is returned. This helps the client track progress for sparse event filters. | +| `event_types` | LIST | NO | A comma-separated list of event types to include. | +| `addresses` | LIST | NO | A comma-separated list of addresses who's events should be included. The format could be `"0xe544175ee0461c4b"` or `"e544175ee0461c4b"`. | +| `contracts` | LIST | NO | A comma-separated list of contracts who's events should be included. The format is `"A.f919ee77447b7497.FlowFees"` | + +If neither `start_block_id` nor `start_block_height` is set, the subscription will start from the latest block based on its status. + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "events", + "payload": { + "block_id": "660ce05ff19193a08c24730cdc0d747da76dfcc39fbab523d970270f2d5c9a3c", + "block_height": "106197288", + "block_timestamp": "2025-03-11T12:46:03.588742664Z", + "events": [ + { + "type": "flow.AccountKeyAdded", + "transaction_id": "7d9290e54437b4b9a5de416c04af6d597fcf5bf1cefcf618232ad86e5f71322b", + "transaction_index": "1", + "event_index": "14", + "payload": "2IGChNigg0BpUHVibGljS2V5goJpcHVibGljS2V52IvYiQyCcnNpZ25hdHVyZUFsZ29yaXRobdiIQQLYpINBAW1IYXNoQWxnb3JpdGhtgYJocmF3VmFsdWXYiQzYpINBAnJTaWduYXR1cmVBbGdvcml0aG2BgmhyYXdWYWx1ZdiJDNiig0EDdGZsb3cuQWNjb3VudEtleUFkZGVkhYJnYWRkcmVzc9iJA4JpcHVibGljS2V52IhAgmZ3ZWlnaHTYiReCbWhhc2hBbGdvcml0aG3YiEEBgmhrZXlJbmRleNiJBILYiEEDhUhbvtriVP1Dy4KYQBUYNhhKGHoYZhicGHwYwxgYGKcYqxhqGIcYZxiCGKMXGDgYRRjnGGQYjBieGIIYxhiUGIgY+BjjGM0YlxhBGL0Y2hiyGHUY8hjoGBwYMhiUGC4YIxjtGNkYJhgoGPMYNxgmGF0YqhgjGP0YlRh2GMoYTxihGOIYsBizGEsYVIECGwAAABdCgQcAgQPCQA==" + }, + { + "type": "flow.AccountKeyAdded", + "transaction_id": "7d9290e54437b4b9a5de416c04af6d597fcf5bf1cefcf618232ad86e5f71322b", + "transaction_index": "1", + "event_index": "15", + "payload": "2IGChNigg0BpUHVibGljS2V5goJpcHVibGljS2V52IvYiQyCcnNpZ25hdHVyZUFsZ29yaXRobdiIQQLYpINBAW1IYXNoQWxnb3JpdGhtgYJocmF3VmFsdWXYiQzYpINBAnJTaWduYXR1cmVBbGdvcml0aG2BgmhyYXdWYWx1ZdiJDNiig0EDdGZsb3cuQWNjb3VudEtleUFkZGVkhYJnYWRkcmVzc9iJA4JpcHVibGljS2V52IhAgmZ3ZWlnaHTYiReCbWhhc2hBbGdvcml0aG3YiEEBgmhrZXlJbmRleNiJBILYiEEDhUhbvtriVP1Dy4KYQBg2GMoY4QYYUhiTGNkYjBinGFsYuhiPGEQYcBjrGKoYdRhsGCkYVRivGMIYRxj6GCUYpRj1GJ4YeRipDgoYPBiLGKAYdgkY8RhVGC4YKxhHGDYYVRiqGOcIGGsYOhhwGIgEGKwYyhj4AxgxGLwYpxhuGMQYtxjsGKeBAhsAAAAXSHboAIEDwkEB" + }, + { + "type": "flow.AccountKeyAdded", + "transaction_id": "7d9290e54437b4b9a5de416c04af6d597fcf5bf1cefcf618232ad86e5f71322b", + "transaction_index": "1", + "event_index": "16", + "payload": "2IGChNigg0BpUHVibGljS2V5goJpcHVibGljS2V52IvYiQyCcnNpZ25hdHVyZUFsZ29yaXRobdiIQQLYpINBAW1IYXNoQWxnb3JpdGhtgYJocmF3VmFsdWXYiQzYpINBAnJTaWduYXR1cmVBbGdvcml0aG2BgmhyYXdWYWx1ZdiJDNiig0EDdGZsb3cuQWNjb3VudEtleUFkZGVkhYJnYWRkcmVzc9iJA4JpcHVibGljS2V52IhAgmZ3ZWlnaHTYiReCbWhhc2hBbGdvcml0aG3YiEEBgmhrZXlJbmRleNiJBILYiEEDhUhbvtriVP1Dy4KYQBjTABhfGC8YmBiZGLoYwBjEGI0YwBjJGJwYVRhxGJ0YxRjKCRj6AxhaEBiEGI0YfBj3GM0YPhiDGFIYrBg/GMgYnBh0GFQYNBhAGFEYZxi/GNMIGB8YeRhEGKQYbRhHGHAYShjyGEYYnhjrGCEYZBjBGLYYYxg5GBwYkoECGgX14QCBA8JBAg==" + } + ], + "message_index": 11 + } +} +``` diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/index.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/index.md new file mode 100644 index 0000000000..b35746597d --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/index.md @@ -0,0 +1,13 @@ +--- +title: Supported topics +sidebar_label: Supported topics +sidebar_position: 1 +--- + +# Supported Topics + +In this section, there is a list of topics that client can subscribe to in order to receive updates on different states of the Flow blockchain. + +It is possible to subscribe to each topic multiple times with different configurations based on input arguments. + +The responses for all topics are aligned with the [Flow REST API](/http-api) responses. \ No newline at end of file diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md new file mode 100644 index 0000000000..2ef831329b --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/send_and_get_transaction_statuses_topic.md @@ -0,0 +1,74 @@ +--- +title: Send and get transaction statuses +sidebar_label: Send and get transaction statuses +sidebar_position: 8 +--- + +Sends a transaction and provides updates on its status changes. + +## Example Request + +```json +{ + "subscription_id": "some-id-7", + "action": "subscribe", + "topic": "send_and_get_transaction_statuses" + "arguments": { + "arguments": [], + "authorizers": ["dba05362251g43g4"], + "envelope_signatures": [ + { + "address": "dba05362251g43g4", + "key_index": "0", + "signature": "PJPVEOCtPKubTEpPqd4zrrSXo1RhpABAMDuzIchgBje8gyh04XuWY4f/tu+c0llDhOU/5sQBokeOTdygaS6eTQ==" + } + ], + "gas_limit": "1000", + "payer": "dba05362251g43g4", + "proposal_key": { + "address": "dba05362251g43g4", + "key_index": "0", + "sequence_number": "0" + }, + "reference_block_id": "817d7c1d2c13a4bd37c182747a4116b45cd175c0ba4878071c33f0f278b37dd7", + "script": "CgkJCXRyYW5zYWN0aW9uIHsKCQkJCXByZXBhcmUoYWNjOiAmQWNjb3VudCkge30KCQkJCWV4ZWN1dGUgewoJCQkJCWxvZygidGVzdCIpCgkJCQl9CgkJCX0KCQk=" + } +} +``` + +| Name | Type | REQUIRED | Description | +| --------------------- | ------ | -------- | ------------------------------------------------------------------------- | +| `script` | STRING | YES | Base64-encoded content of the Cadence script. | +| `arguments` | LIST | YES | A list of arguments, each encoded as Base64. | +| `reference_block_id` | STRING | YES | BlockID for the transaction's reference block | +| `gas_limit` | STRING | YES | The limit on the amount of computation a transaction can perform. | +| `payer` | STRING | YES | The 8-byte address of an account. | +| `proposal_key` | OBJECT | YES | A required object representing the proposal key. | +| `authorizers` | LIST | YES | A list of authorizers, each represented as a hexadecimal-encoded address. | +| `payload_signatures` | LIST | NO | A list of Base64-encoded signatures. | +| `envelope_signatures` | LIST | YES | A list of Base64-encoded signatures. | + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "send_and_get_transaction_statuses", + "payload": { + "transaction_result": { + "block_id": "7ad167602487665db095f7cb0b95139e5dcaf3ad2479ee4d14cade35b7d4bbdc", + "collection_id": "d0855ed45c16be2831ab9892ec8a9ddfd10a0e01e683466971cfd87c759bf7d1", + "execution": "Failure", + "status": "Sealed", + "status_code": 1, + "error_message": "[Error Code: 1009] error caused by: 1 error occurred:\n\t* transaction verification failed: [Error Code: 1006] invalid proposal key: public key 0 on account dba05362251g43g4 does not have a valid signature: [Error Code: 1009] invalid envelope key: public key 0 on account dba05362251g43g4 does not have a valid signature: signature is not valid\n\n", + "computation_used": "0", + "events": [], + "_links": { + "_self": "/v1/transaction_results/92014de98466a6304ecd821c95ee2612e248c22419d243e6e3ff4d138dffde04" + } + }, + "message_index": 3 + } +} +``` \ No newline at end of file diff --git a/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md new file mode 100644 index 0000000000..4580e9a3e8 --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/supported-topics/transaction_statuses_topic.md @@ -0,0 +1,69 @@ +--- +title: Transaction statuses +sidebar_label: Transaction statuses +sidebar_position: 7 +--- + +Provides updates on transaction status changes for already sent transactions. + +## Example Request + +```json +{ + "subscription_id": "some-id", + "action": "subscribe", + "topic": "transaction_statuses", + "arguments": { + "tx_id": "fe3784095bc194dca02e4b14e7e6a1e0519d10b7bc907453e5b5dc276259a106" + } +} +``` + +### Request Arguments + +| Name | Type | Required | Description | +| ------- | ------ | -------- | -------------------------------------------------------- | +| `tx_id` | STRING | YES | The ID of the transaction to monitor for status changes. | + + +## Example Response + +```json +{ + "subscription_id": "some-id", + "topic": "transaction_statuses", + "payload": { + "transaction_result": { + "block_id": "b668e472c404e471cba8bab5246ca98f90d8492e80c81aae4cccbfae6e734aad", + "collection_id": "efdcbf3b2b02b20cdfa7f2669034da05e44232ea68e41d3ed14756472081f9b9", + "execution": "Success", + "status": "Sealed", + "status_code": 0, + "error_message": "", + "computation_used": "0", + "events": [ + { + "type": "A.0b2a3299cc857e29.TopShot.Withdraw", + "transaction_id": "fe3784095bc194dca02e4b14e7e6a1e0519d10b7bc907453e5b5dc276259a106", + "transaction_index": "4", + "event_index": "0", + "payload": "eyJ2YWx1ZSI6eyJpZCI6IkEuMGIyYTMyOTljYzg1N2UyOS5Ub3BTaG90LldpdGhkcmF3IiwiZmllbGRzIjpbeyJ2YWx1ZSI6eyJ2YWx1ZSI6IjQwOTQ3MzE4IiwidHlwZSI6IlVJbnQ2NCJ9LCJuYW1lIjoiaWQifSx7InZhbHVlIjp7InZhbHVlIjp7InZhbHVlIjoiMHg2N2Q5OTk5MWMxMzRlODQ4IiwidHlwZSI6IkFkZHJlc3MifSwidHlwZSI6Ik9wdGlvbmFsIn0sIm5hbWUiOiJmcm9tIn1dfSwidHlwZSI6IkV2ZW50In0K" + }, + // Full response is cut down due to its large size; see `_links` for the full response. ... + { + "type": "A.f919ee77447b7497.FlowFees.FeesDeducted", + "transaction_id": "fe3784095bc194dca02e4b14e7e6a1e0519d10b7bc907453e5b5dc276259a106", + "transaction_index": "4", + "event_index": "22", + "payload": "eyJ2YWx1ZSI6eyJpZCI6IkEuZjkxOWVlNzc0NDdiNzQ5Ny5GbG93RmVlcy5GZWVzRGVkdWN0ZWQiLCJmaWVsZHMiOlt7InZhbHVlIjp7InZhbHVlIjoiMC4wMDAwNDc5OCIsInR5cGUiOiJVRml4NjQifSwibmFtZSI6ImFtb3VudCJ9LHsidmFsdWUiOnsidmFsdWUiOiIxLjAwMDAwMDAwIiwidHlwZSI6IlVGaXg2NCJ9LCJuYW1lIjoiaW5jbHVzaW9uRWZmb3J0In0seyJ2YWx1ZSI6eyJ2YWx1ZSI6IjAuMDAwMDAxODgiLCJ0eXBlIjoiVUZpeDY0In0sIm5hbWUiOiJleGVjdXRpb25FZmZvcnQifV19LCJ0eXBlIjoiRXZlbnQifQo=" + } + ], + "_links": { + "_self": "/v1/transaction_results/fe3784095bc194dca02e4b14e7e6a1e0519d10b7bc907453e5b5dc276259a106" + } + }, + "message_index": 3 + } +} +``` + diff --git a/docs/networks/access-onchain-data/websockets-stream-api/unsubscribe-message.md b/docs/networks/access-onchain-data/websockets-stream-api/unsubscribe-message.md new file mode 100644 index 0000000000..069e0b0e4a --- /dev/null +++ b/docs/networks/access-onchain-data/websockets-stream-api/unsubscribe-message.md @@ -0,0 +1,45 @@ +--- +title: Unsubscribe request message format +sidebar_label: Unsubscribing from topic +sidebar_position: 3 +--- + +# Unsubscribe message format + +Unsubscribe requests must be sent as JSON in text frames, one request per frame. + +### Example of unsubscribe request + +```json +{ + "subscription_id": "some-id-1", + "action": "unsubscribe" +} +``` + +### Example of successful response + +```json +{ + "subscription_id": "some-id-1", + "action": "unsubscribe" +} +``` + +### Example of error response + +```json +{ + "error": { + "code": 404, + "message": "subscription not found" + } +} +``` + +### Request fields + +| Name | Type | Required | Description | +|-------------------|--------|----------|-----------------------------------------------------------------------| +| `subscription_id` | STRING | YES | Unique identifier of the subscription | +| `action` | STRING | YES | Action to perform. Must be `unsubscribe` to initiate a unsubscription |