Overview
OrbitFlare supports persistent WebSocket connections for real-time Solana data. WebSocket subscriptions push updates to your client as they occur on-chain — no polling required.
WebSocket endpoints use the wss:// scheme with the same region codes as the HTTP API:
wss://{region}.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY
For the auto-routed mainnet endpoint:
wss://mainnet.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY
Your license key is found in the Licenses section of your OrbitFlare Dashboard . Pass it as the api_key query parameter — the same key used for HTTP RPC.
Connecting
const WebSocket = require ( "ws" );
const ws = new WebSocket (
"wss://mainnet.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY"
);
ws . on ( "open" , () => {
console . log ( "Connected" );
});
ws . on ( "message" , ( data ) => {
const msg = JSON . parse ( data );
console . log ( "Received:" , msg );
});
ws . on ( "error" , ( err ) => {
console . error ( "WebSocket error:" , err );
});
ws . on ( "close" , ( code , reason ) => {
console . log ( `Connection closed: ${ code } ${ reason } ` );
});
WebSocket connections idle for more than 60 seconds without any message exchange are closed by the server. Send a ping or keep your subscriptions active to maintain the connection.
Subscription Methods
accountSubscribe
Receive updates whenever a specific account’s lamport balance or data changes.
ws . on ( "open" , () => {
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 1 ,
method: "accountSubscribe" ,
params: [
"83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri" ,
{ encoding: "base64" , commitment: "confirmed" }
],
}));
});
Update fields:
Field Description lamportsCurrent lamport balance dataAccount data (encoding determined by the encoding param) ownerOwning program public key executableWhether the account is an executable program rentEpochEpoch at which rent is next owed
logsSubscribe
Receive transaction log messages in real time. Optionally filter to a specific program.
// All transactions
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 2 ,
method: "logsSubscribe" ,
params: [ "all" ],
}));
// Filter to a specific program
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 3 ,
method: "logsSubscribe" ,
params: [
{ mentions: [ "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8" ] }, // Raydium AMM
{ commitment: "confirmed" }
],
}));
Update fields:
Field Description signatureTransaction signature (base-58) errnull if successful, error object if failedlogsArray of log message strings
slotSubscribe
Receive a notification each time a slot is processed.
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 4 ,
method: "slotSubscribe" ,
params: [],
}));
Update fields:
Field Description slotCurrent slot number parentParent slot number rootHighest confirmed root slot
signatureSubscribe
Receive a one-time notification when a specific transaction signature reaches a given commitment level.
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 5 ,
method: "signatureSubscribe" ,
params: [
"TRANSACTION_SIGNATURE_HERE" ,
{ commitment: "finalized" }
],
}));
The subscription automatically closes after the first notification is sent.
programSubscribe
Receive updates for all accounts owned by a specific program.
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 6 ,
method: "programSubscribe" ,
params: [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" , // SPL Token
{
encoding: "jsonParsed" ,
commitment: "confirmed" ,
filters: [{ dataSize: 165 }], // Standard token account size
}
],
}));
blockSubscribe
Receive full block data as each block is confirmed. Requires an add-on — contact support to enable.
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 7 ,
method: "blockSubscribe" ,
params: [ "all" , { commitment: "confirmed" , encoding: "base64" }],
}));
rootSubscribe
Receive the highest confirmed root slot each time it advances.
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 8 ,
method: "rootSubscribe" ,
params: [],
}));
voteSubscribe
Receive raw vote transactions as they are observed in the gossip network. High volume — filter carefully.
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 9 ,
method: "voteSubscribe" ,
params: [],
}));
Unsubscribing
Each subscription method has a corresponding Unsubscribe method. Pass the subscription ID returned in the initial subscription response.
// Subscribe and capture the subscription ID
ws . on ( "message" , ( data ) => {
const msg = JSON . parse ( data );
// Subscription confirmation contains the subscription ID
if ( msg . id === 1 && msg . result !== undefined ) {
const subscriptionId = msg . result ;
console . log ( "Subscribed, ID:" , subscriptionId );
// Unsubscribe later
ws . send ( JSON . stringify ({
jsonrpc: "2.0" ,
id: 10 ,
method: "accountUnsubscribe" ,
params: [ subscriptionId ],
}));
}
});
Available unsubscribe methods: accountUnsubscribe, logsUnsubscribe, slotUnsubscribe, signatureUnsubscribe, programUnsubscribe, blockUnsubscribe, rootUnsubscribe, voteUnsubscribe.
Keepalive
WebSocket connections are closed after 60 seconds of inactivity. Send a JSON-RPC ping periodically to keep the connection alive:
const pingInterval = setInterval (() => {
if ( ws . readyState === WebSocket . OPEN ) {
ws . send ( JSON . stringify ({ jsonrpc: "2.0" , id: 0 , method: "ping" }));
}
}, 30_000 );
ws . on ( "close" , () => clearInterval ( pingInterval ));
Reconnection
Implement automatic reconnection with exponential backoff for production applications:
function connect ( url , onMessage ) {
let ws ;
let delay = 1000 ;
let attempt = 0 ;
function createConnection () {
ws = new WebSocket ( url );
ws . on ( "open" , () => {
console . log ( "Connected (attempt" , attempt + 1 , ")" );
delay = 1000 ; // reset backoff on successful connection
attempt = 0 ;
// re-subscribe to all channels here
});
ws . on ( "message" , onMessage );
ws . on ( "close" , () => {
attempt ++ ;
const nextDelay = Math . min ( delay * 2 , 30_000 );
console . log ( `Reconnecting in ${ delay } ms...` );
setTimeout ( createConnection , delay );
delay = nextDelay ;
});
ws . on ( "error" , ( err ) => console . error ( "WebSocket error:" , err ));
}
createConnection ();
return () => ws ?. close ();
}
const disconnect = connect (
"wss://mainnet.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY" ,
( data ) => {
const msg = JSON . parse ( data );
console . log ( "Update:" , msg );
}
);
Connection Limits
WebSocket connections share the same per-IP limit as gRPC connections. See Authentication & Limits for details.
See Also
HTTP RPC API JSON-RPC 2.0 request format, batch requests, and all available methods.
Error Codes HTTP status codes, JSON-RPC errors, and how to handle them.