Skip to main content

Connect to ChainStream

ChainStream delivers real-time Solana blockchain data by aggregating streams from multiple validators using a "fastest wins" strategy. This multi-validator approach ensures you never miss events while minimizing notification latency, making it ideal for applications requiring complete blockchain visibility and high reliability.

Prerequisites

Enable ChainStream

Before connecting, enable ChainStream from your dashboard's ChainStream API page:

Enable ChainStream from the ChainStream API page
Enable ChainStream from the ChainStream API page

Once enabled, select how many concurrent streams you need. Scale Mode includes one stream, with additional streams available at $0.14/hour (up to 10 total).

Configure your ChainStream subscription count
Configure your ChainStream subscription count

ChainStream Endpoint

ChainStream uses a dedicated endpoint with your API key embedded in the URL path:

Mainnet:

wss://solana-mainnet.chainstream.syndica.io/api-key/YOUR_API_KEY

Devnet:

wss://solana-devnet.chainstream.syndica.io/api-key/YOUR_API_KEY

Subscribe to Transaction Events

Monitor transactions in real-time with flexible filtering options. This example subscribes to confirmed transactions involving specific accounts:

const ws = new WebSocket('wss://solana-mainnet.chainstream.syndica.io/api-key/YOUR_API_KEY')

ws.onopen = () => {
console.log('Connected to ChainStream')

// Subscribe to filtered transaction events
ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'transactionsSubscribe',
params: {
network: 'solana-mainnet',
verified: false,
filter: {
commitment: 'confirmed',
excludeVotes: true,
accountKeys: {
// All these keys must be present
all: ['675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'],
// At least one of these must be present
oneOf: [
'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
],
},
},
},
})
)
}

ws.onmessage = (event) => {
const data = JSON.parse(event.data)

if (data.result) {
console.log('Subscription ID:', data.result)
} else if (data.method === 'transactionNotification') {
const tx = data.params.result
console.log('Transaction:', tx.context.signature)
console.log('Slot:', tx.value.slot)
}
}

ws.onerror = (error) => {
console.error('ChainStream error:', error)
}

ws.onclose = () => {
console.log('ChainStream connection closed')
}

Understanding the Request

ChainStream subscription requests include these key parameters:

  • network - The Solana network (solana-mainnet or solana-devnet). Required for all subscriptions.
  • verified - When true, waits for multiple validators to confirm transactions at the processed commitment level (adds ~400ms maximum delay). Only supported with commitment: "processed".
  • filter.commitment - Commitment level: processed (fastest), confirmed (balanced), or finalized (safest).
  • filter.excludeVotes - When true, filters out validator vote transactions to reduce noise.
  • filter.accountKeys - Filter transactions by accounts:
    • all: Transaction must include all specified keys
    • oneOf: Transaction must include at least one specified key
    • exclude: Transaction must not include any specified keys

Expected Response

Subscription Confirmation:

{
"jsonrpc": "2.0",
"result": 446257156701906,
"id": 1
}
Save this subscription ID if you need to explicitly unsubscribe before disconnecting.

Disconnecting the WebSocket automatically unsubscribes all active subscriptions.

Transaction Notification:

{
"jsonrpc": "2.0",
"method": "transactionNotification",
"params": {
"subscription": 446257156701906,
"result": {
"context": {
"slotStatus": "confirmed",
"nodeTime": "2025-10-01T22:20:38.121983224Z",
"signature": "5k5MgvCWxrZ2haxKKDjigAp2oPoaCEYUf2Ct4qDfhUTT...",
"index": 62,
"isVote": false
},
"value": {
"slot": 370568409,
"meta": {
"err": null,
"fee": 5000,
"logMessages": [
"Program invoke...",
"Program success"
],
"computeUnitsConsumed": 28215,
"innerInstructions": [],
"loadedAddresses": {
"writable": [],
"readonly": []
},
"postBalances": [
49809089923,
...
],
"postTokenBalances": [],
"preBalances": [
49809098321,
...
],
"preTokenBalances": [],
"rewards": [],
"returnData": null,
"costUnits": 1939
},
"transaction": {
"message": {
"accountKeys": [
"4dxRtLucVXZ4o9drN5jtCs5X9TJdv79KwPDp4fsVqtqh",
...
],
"version": 0,
"addressTableLookups": [],
"header": {
"numReadonlySignedAccounts": 0,
"numReadonlyUnsignedAccounts": 3,
"numRequiredSignatures": 1
},
"instructions": [
{
"programIdIndex": 4,
"accounts": [
0,
...
],
"data": "9CJyjpsEQ4fyzLcwYUZS2uzaMe2PJUdJ18744eCk63M8g2HF3B8PFdu14Sq4rJnrKdLQdrruQyFkAcybovQ5RXwHQ"
},
...
],
"recentBlockhash": "4JsY3dvQaRTTwrYvAqdRpcmJTvkmryvF5SsEXu7GYLVj"
},
"messageHash": "6ChShqpS1zxurZ2gNpvrGWUtK2NXPS6RxicHJkhZmsHj",
"signatures": [
"5k5MgvCWxrZ2haxKKDjigAp2oPoaCEYUf2Ct4qDfhUTT..."
]
}
}
}
}
}

Available Stream Types

Beyond transaction streams, ChainStream supports:

  • slotSubscribe - Slot progression events showing blockchain advancement
  • blockSubscribe - Complete block data including all transactions
  • encodedBlockSubscribe - Encoded block data for efficient processing

For detailed documentation on each stream type including payload examples and filtering options, see the ChainStream API reference.

Unsubscribe from Events

Stop receiving notifications using the subscription ID:

ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 3,
method: 'transactionsUnsubscribe',
params: [446257156701906], // Your subscription ID
})
)

Monitor Your Streams

Real-time WebSocket analytics dashboard
Real-time WebSocket analytics dashboard

After connecting, monitor your ChainStream activity on the analytics dashboard:

  • Active subscription count and connection status
  • Message and data throughput in real-time
  • Historical usage patterns and trends
  • Connection health and error rates

Access your ChainStream analytics from the ChainStream API page in your dashboard.

FAQ and Troubleshooting

What's the difference between WebSocket subscriptions and ChainStream?

Standard WebSocket subscriptions connect directly to whichever validator your connection reaches and expose the base Solana RPC methods (slotSubscribe, logsSubscribe, accountSubscribe, etc.). That keeps them lightweight and available on every plan, but you own the operational work when the validator you hit lags or restarts.

ChainStream is a separate endpoint (wss://solana-mainnet.chainstream.syndica.io/api-key/...) that streams data from the validator's geyser interface. It aggregates streams from multiple validators using a "fastest-wins" strategy to provide redundancy and high availability. ChainStream also unlocks capabilities standard WebSockets do not provide:

  • transactionsSubscribe, blockSubscribe, and encodedBlockSubscribe for full transaction/block payload streaming
  • Rich account filtering via all, oneOf, and exclude matchers plus the verified flag for multi-validator confirmation
  • Built-in delivery guarantees so you no longer maintain resend buffers or custom analytics

ChainStream requires Scale Mode or higher (see plans and pricing); standard WebSockets work on all plans.

When should I use ChainStream verified transactions?

Set verified: true when you need confirmation that multiple validators have processed a transaction before acting on it. This adds up to ~400ms delay but provides additional data correctness guarantees.

Only use verified: true with commitment: "processed". For confirmed or finalized commitment, the network itself provides multi-validator consensus, making the verified flag unnecessary.

How many concurrent ChainStream streams can I have?

Scale Mode includes one ChainStream subscription. You can add up to 9 additional subscriptions ($0.14/hour each) for a maximum of 10 concurrent streams. Each subscription represents one WebSocket connection with one or more active event subscriptions. You can also configure custom rate limits for ChainStream subscriptions on your API keys. Refer to plans and pricing for current limits.

What commitment level should I use with ChainStream?

Choose based on your use case:

  • Processed: Fastest notifications as transactions are processed by the validator, ideal for price feeds and real-time applications.
  • Confirmed: Balanced option with network consensus, good for most applications.
  • Finalized: Guaranteed by network finality, ~13 second delay, required for financial settlement.

Review the commitment levels documentation for deeper detail.

Can I filter ChainStream traffic by multiple account keys?

Yes, the accountKeys filter supports three operators:

  • all: Transaction must include all specified keys
  • oneOf: Transaction must include at least one specified key
  • exclude: Transaction must not include any specified keys

You can combine operators—filters apply in order: exclude first, then all, then oneOf. See the ChainStream API documentation for examples.

How do I reduce ChainStream bandwidth usage?

Syndica automatically offers Per-Message Deflate compression (RFC 7692) on every ChainStream endpoint, typically reducing bandwidth by 70-90%. Most client libraries negotiate this extension automatically, but some require you to enable compression explicitly or install an additional dependency—check your client's docs to confirm it advertises permessage-deflate during the handshake.

For transaction-heavy streams you can further trim payloads by:

  • Setting metadataOnly: true to receive signatures, slots, and metadata without full transaction data.
  • Using excludeVotes: true to drop validator vote transactions.
  • Applying accountKeys filters to limit events to the accounts you care about.
Why is my ChainStream connection failing?

Common issues:

  • Scale Mode not enabled: ChainStream requires Scale Mode or higher. Upgrade your plan or review plans and pricing.
  • ChainStream not enabled: Enable ChainStream from your dashboard's ChainStream API page.
  • No available streams / Error 7429 (subscription method exceeded limit): More concurrent ChainStream streams are active than your plan allows (Scale includes one stream). Close unused streams or enable additional streams—see plans and pricing for current costs.
  • Invalid API key: Verify your API key has ChainStream access enabled.

Check your subscription status and limits on the ChainStream API page in your dashboard.

What happens if a validator goes offline when using ChainStream?

ChainStream automatically routes around validator outages. Since data is aggregated from multiple validators, you continue receiving events from healthy validators without interruption. This multi-validator redundancy is a key advantage over single-node WebSocket connections.

How do I use ChainStream with devnet?

Use the devnet endpoint and set the network parameter to solana-devnet:

const ws = new WebSocket('wss://solana-devnet.chainstream.syndica.io/api-key/YOUR_API_KEY')

ws.send(
JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'transactionsSubscribe',
params: {
network: 'solana-devnet', // Use devnet
verified: false,
filter: { commitment: 'confirmed' },
},
})
)
What latency should I expect from ChainStream?

Once a validator feeding ChainStream timestamps an event at the geyser interface, it takes ≤10 ms to reach clients co-located in the same AWS region (RTT under 10 ms). Over typical public-internet links you can expect 50–100 ms end-to-end latency, depending on your ISP and geography. To measure your real-world performance, compare the nodeTime field (UTC timestamp) in each ChainStream message with your local clock and log the delta over time.

What You Can Do Next

Now that you're streaming with ChainStream: