Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
300 changes: 300 additions & 0 deletions content/api-reference/bitcoin/utxo-websockets.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
---
title: UTXO WebSockets
description: Stream block, transaction, address, and fiat rate updates from Bitcoin over a persistent WebSocket connection.
subtitle: Real-time UTXO event streams over WebSockets
slug: docs/bitcoin/utxo-websockets
---

The UTXO WebSockets API streams real-time events from Bitcoin over a persistent connection, powered by [Trezor Blockbook](https://github.com/trezor/blockbook). Use it to push-subscribe to new blocks, new transactions, transactions affecting specific addresses, and fiat rate updates, with the same data shapes returned by the [UTXO REST API](/docs/bitcoin/utxo).

<Info>
When the chain reorganizes, the server emits new block events for the new chain. You may see multiple events at the same height; treat the latest one as canonical.
</Info>

# Supported Networks

* `bitcoin-mainnet`
* `bitcoin-testnet4`

# Connection

Open a WebSocket connection using the standard Alchemy WebSocket URL for the network:

<CodeGroup>
```shell wscat
wscat -c wss://bitcoin-mainnet.g.alchemy.com/v2/{apiKey}
```
</CodeGroup>

Replace `{apiKey}` with your Alchemy API key from the [Alchemy Dashboard](https://dashboard.alchemy.com/). The WebSocket URL for an app uses the same host as its HTTPS URL, just with the `wss://` scheme.

# Message format

Every client message uses the following envelope:

```json
{
"id": "1",
"method": "<request or subscription name>",
"params": { ... }
}
```

* `id`: a client-chosen string. The server echoes it back on every response so you can correlate.
* `method`: the request method or subscription name.
* `params`: method-specific arguments. Use `{}` when none.

A connection can hold only one active subscription per event type. Sending a second `subscribeAddresses` replaces the previous address list. To stop receiving events, close the connection.

# Subscriptions

## subscribeNewBlock

Emits an event each time a new block is added to the chain.

### Parameters

* None.

### Response

* `id`: `string` - The id you sent on the request.
* `data`:
* `height`: `number` - Block height.
* `hash`: `string` - Block hash.

### Request

<CodeGroup>
```shell wscat
// open the websocket
wscat -c wss://bitcoin-mainnet.g.alchemy.com/v2/{apiKey}

// then send the subscription
{"id":"1","method":"subscribeNewBlock","params":{}}
```
</CodeGroup>

### Result

<CodeGroup>
```json result
{"id":"1","data":{"subscribed":true}}

{
"id":"1",
"data":{
"height":860730,
"hash":"00000000000000000000effeb0c4460480e6a347deab95332c63007a68646ee5"
}
}
```
</CodeGroup>

## subscribeNewTransaction

Emits every new transaction added to the blockchain, across all addresses.

<Info>
This subscription is a high-volume firehose and requires the backend to be running with the `-enablesubnewtx` flag. It may not be enabled on all networks. If you do not receive events after subscribing, fall back to `subscribeAddresses` for targeted updates.
</Info>

### Parameters

* None.

### Response

* `id`: `string` - The id you sent on the request.
* `data`: a transaction object using the same shape as `GET /api/v2/tx/{txid}`. See the [Get transaction reference](https://github.com/trezor/blockbook/blob/master/docs/api.md#get-transaction) for the full field list.

### Request

<CodeGroup>
```shell wscat
{"id":"2","method":"subscribeNewTransaction","params":{}}
```
</CodeGroup>

### Result

<CodeGroup>
```json result
{"id":"2","data":{"subscribed":true}}

{
"id":"2",
"data":{
"txid":"8c1e3dec662d1f2a5e322ccef5eca263f98eb16723c6f990be0c88c1db113fb1",
"version":2,
"vin":[
{
"txid":"0eb7b574373de2c88d0dc1444f49947c681d0437d21361f9ebb4dd09c62f2a66",
"vout":1,
"n":0,
"addresses":["bc1qmgwnfjlda4ns3g6g3yz74w6scnn9yu2ts82yyc"],
"isAddress":true,
"value":"10106300"
}
],
"vout":[
{
"value":"175000",
"n":0,
"addresses":["1Nb1ykSD7J5k4RFjJQGsrD9gxBE6jzfNa9"],
"isAddress":true
}
],
"blockHeight":-1,
"confirmations":0,
"value":"10063100",
"valueIn":"10106300",
"fees":"43200"
}
}
```
</CodeGroup>

## subscribeAddresses

Emits an event when a new transaction touches any of the supplied addresses. Optionally also emits when those transactions confirm in a new block.

### Parameters

* `addresses`: `string[]` - One or more addresses to watch. Sending a new `subscribeAddresses` request replaces the previous list.
* `newBlockTxs`: `boolean` *(optional)* - When `true`, also emits an event when a watched transaction is included in a new block, not just when it enters the mempool. Defaults to `false`.

### Response

* `id`: `string` - The id you sent on the request.
* `data`:
* Initial: `{ "subscribed": true }`.
* On each event: `{ "address": <string>, "tx": <Tx> }` where `Tx` follows the same shape as `GET /api/v2/tx/{txid}`.

### Request

<CodeGroup>
```shell wscat
{
"id":"3",
"method":"subscribeAddresses",
"params":{
"addresses":[
"bc1qmgwnfjlda4ns3g6g3yz74w6scnn9yu2ts82yyc",
"1Nb1ykSD7J5k4RFjJQGsrD9gxBE6jzfNa9"
],
"newBlockTxs":true
}
}
```
</CodeGroup>

### Result

<CodeGroup>
```json result
{"id":"3","data":{"subscribed":true}}

{
"id":"3",
"data":{
"address":"bc1qmgwnfjlda4ns3g6g3yz74w6scnn9yu2ts82yyc",
"tx":{
"txid":"8c1e3dec662d1f2a5e322ccef5eca263f98eb16723c6f990be0c88c1db113fb1",
"vin":[
{
"n":0,
"addresses":["bc1qmgwnfjlda4ns3g6g3yz74w6scnn9yu2ts82yyc"],
"isAddress":true,
"value":"10106300"
}
],
"vout":[
{
"value":"175000",
"n":0,
"addresses":["1Nb1ykSD7J5k4RFjJQGsrD9gxBE6jzfNa9"],
"isAddress":true
}
],
"blockHeight":-1,
"confirmations":0,
"value":"10063100",
"fees":"43200"
}
}
}
```
</CodeGroup>

## subscribeFiatRates

Emits an event when the fiat rate ticker for the chain's native asset updates.

### Parameters

* `currency`: `string` *(optional)* - Filter to a single fiat currency (e.g. `"usd"`, `"eur"`). When omitted, the server emits all available currencies on each update.

### Response

* `id`: `string` - The id you sent on the request.
* `data`:
* Initial: `{ "subscribed": true }`.
* On each event: `{ "rates": { "<currency>": <number>, ... } }`.

### Request

<CodeGroup>
```shell wscat
{"id":"4","method":"subscribeFiatRates","params":{"currency":"usd"}}
```
</CodeGroup>

### Result

<CodeGroup>
```json result
{"id":"4","data":{"subscribed":true}}

{"id":"4","data":{"rates":{"usd":7914.5}}}
```
</CodeGroup>

# Request methods

In addition to subscriptions, the WebSocket connection accepts the same one-shot requests as the [UTXO REST API](/docs/chains/bitcoin/utxo-api-endpoints/utxo-api-endpoints). They are useful when you have already opened a connection for subscriptions and want to fetch ad-hoc data without a separate HTTP round-trip.

| Method | REST equivalent | Description |
| ---------------------------- | ------------------------------------------------ | ----------------------------------------------------------------- |
| `getInfo` | `GET /api/` | Backend and Blockbook status |
| `getBlockHash` | `GET /api/v2/block-index/{block_height}` | Block hash for a given height |
| `getAccountInfo` | `GET /api/v2/address/{address}`, `/xpub/{xpub}` | Balances and transactions for an address or xpub |
| `getAccountUtxo` | `GET /api/v2/utxo/{descriptor}` | UTXOs for an address or xpub |
| `getTransaction` | `GET /api/v2/tx/{txid}` | Normalized transaction data |
| `getTransactionSpecific` | `GET /api/v2/tx-specific/{txid}` | Coin-specific raw transaction |
| `getBalanceHistory` | `GET /api/v2/balancehistory/{address}` | Address balance history grouped by time |
| `estimateFee` | n/a | Fee estimate for a target confirmation depth |
| `sendTransaction` | `POST /api/v2/sendtx/` | Broadcast a signed raw transaction |
| `getCurrentFiatRates` | `GET /api/v2/tickers/` | Current fiat rates |
| `getFiatRatesTickersList` | `GET /api/v2/tickers-list/` | List of available fiat tickers for a timestamp |
| `getFiatRatesForTimestamps` | n/a | Historical fiat rates for specific timestamps |
| `getMempoolFilters` | n/a | Compact block filters for the mempool (for light clients) |
| `getBlockFilter` | n/a | Compact block filter for a given block |
| `ping` | n/a | Connection health check |

For request and response payload shapes, see the [Trezor Blockbook WebSocket API reference](https://github.com/trezor/blockbook/blob/master/docs/api.md#websocket-api). The payloads are the same as the REST API; only the connection layer differs.

# WebSocket limits

The following limits apply to Alchemy WebSocket connections:

* 100 concurrent connections per app on the FREE tier; 2,000 on all other tiers.
* 1,000 unique subscriptions per connection.

See [Best Practices for Using WebSockets](/docs/reference/best-practices-for-using-websockets-in-web3) for connection-management tips and [Compute Unit Costs](/docs/reference/compute-unit-costs) for billing details.

# See also

* [UTXO Overview](/docs/bitcoin/utxo)
* [UTXO API Endpoints](/docs/chains/bitcoin/utxo-api-endpoints/utxo-api-endpoints)
* [UTXO Migration Guide](/docs/bitcoin/utxo-migration-guide)
Loading
Loading