WebSocket Streaming

An alternative to webhooks for receiving events — you connect out to Blockdaemon instead of exposing an endpoint for Blockdaemon to call.

WebSocket is a second way to receive Event Streaming data, alongside webhooks. It supports all the same chains and rules as webhooks — the difference is entirely in how the connection is established.

When to use websocket

See the comparison on Webhook Streaming documentation.

Target lifecycle

A WebSocket target's lifecycle is different from a webhook target's. It does not move through connected or failed states.

  • On connect and disconnect: each event is recorded in the target's history log. The target's status stays active — connecting and disconnecting do not change it.
  • Going idle: if a target has no connection for longer than a configured window, it's moved to disabled. From there it follows the same archiving rules as any other disabled target.

Liveness is tracked internally using a short-TTL key that's continuously refreshed while a connection is active, rather than a client-facing heartbeat message.

Archiving follows the same logic as webhook targets, based on target state and last-updated time.

Connecting

Create a WebSocket target the same way as a webhook target, using POST /targets, with "type": "websocket" instead of "webhook":

{
  "name": "my-websocket-target",
  "type": "websocket",
  "max_buffer_count": 2000,
  "settings": { "mode": "noack" }
}

The response's id is the target ID used to open the connection:

wss://svc.blockdaemon.com/streaming/v2/targets/{target_id}/websocket

Authenticate at connection time with a standard Authorization: Bearer <API_KEY> header on the WebSocket handshake request, the same API key used for the REST API. There's no separate handshake message or query-param authentication step.

Once connected, each event arrives as a single JSON text frame, one message per event, using the same envelope and templates (ALL_DATA, UNIFIED_V1, UNIFIED_V1_RAW) as webhook delivery. Rules and variables are created the same way for a WebSocket target as for a webhook target.

Warning: You can open more than one WebSocket connection to the same target, for example to scale out processing. But this is not a broadcast. Each event goes to only one connection, not all of them.

Acknowledgment mode

The settings.mode field controls whether you must confirm receipt of each event:

  • noack: no confirmation needed. Delivery is not guaranteed.
  • ack: for each event received, send back a JSON text frame {"Id": "<message id>"}, using the event's own id. Up to 100 events can be sent without a confirmation; after that, no more are sent until you catch up. If a confirmation doesn't arrive in time, the connection is closed. At least once delivery is guaranteed.

A minimal Go client in ack mode:

package main

import (
	"encoding/json"
	"log"

	"github.com/gorilla/websocket"
)

type Event struct {
	Id string `json:"Id"`
	// other event fields are ignored in this example
}

func main() {
	url := "wss://svc.blockdaemon.com/streaming/v2/targets/{target_id}/websocket"
	headers := map[string][]string{"Authorization": {"Bearer <API_KEY>"}}

	conn, _, err := websocket.DefaultDialer.Dial(url, headers)
	if err != nil {
		log.Fatal("dial error:", err)
	}
	defer conn.Close()

	for {
		_, message, err := conn.ReadMessage()
		if err != nil {
			log.Fatal("read error:", err)
		}

		var event Event
		if err := json.Unmarshal(message, &event); err != nil {
			log.Println("unmarshal error:", err)
			continue
		}

		// Do something with the event here, then acknowledge it.
		ack, _ := json.Marshal(Event{Id: event.Id})
		if err := conn.WriteMessage(websocket.TextMessage, ack); err != nil {
			log.Fatal("write error:", err)
		}
	}
}

max_buffer_count has a minimum of 100; values below that are rejected.

Rules only match activity from the moment they're active. Connect and confirm the rules are live before triggering the activity being watched for; rules don't scan history retroactively.

No custom application-level heartbeat message is sent. The connection does use standard WebSocket protocol ping frames (per RFC 6455) for keepalive. A compliant WebSocket client handles these automatically at the protocol level without any application code needed.

Security

The WebSocket connection is secured with SSL. Authentication uses the same API key as the REST API, passed as a Bearer token on the connection request.

👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.


Did this page help you?