Skip to main content
Use Sender Max (min tip: 0.001 SOL) to act on Preconfirmations. A preconfirmation only pays off if you land your transaction first — Sender Max is the fastest way to do that. Build on Sender Max from the start to get the full benefit of Preconfirmations.

What is preconfSubscribe?

preconfSubscribe is a Helius WebSocket method that streams Preconfirmations — transactions delivered before they are collected into entries and shredded. It is the lowest-latency transaction signal Helius offers. One subscription delivers both Helius preconfirmations, emitted the instant the leader executes the transaction and carrying its execution status, and BAM preconfirmations from validators running Jito’s Block Assembly Marketplace client, emitted when the validator commits to executing the transaction. Access requires a Professional plan or higher — see Pricing.
The stream is not continuous. Coverage scales with the share of stake forwarding to Helius or running BAM, so expect slots with no messages — handle these gaps gracefully. See Coverage.
preconfSubscribe is served from wss://beta.helius-rpc.com — the Helius Gatekeeper endpoint — rather than mainnet.helius-rpc.com. Authenticate with your API key as a query parameter.
The beta hostname refers to the Gatekeeper rollout, not the maturity of Preconfirmations. Preconfirmations launch on the Gatekeeper endpoint first; it will become the standard endpoint as Helius migrates traffic to Gatekeeper.

Subscribe

Send a JSON-RPC request with the preconfSubscribe method. The server responds with a subscription ID, then streams a notification for each transaction. Pass an optional filter as the first params element to receive only matching transactions; omit params to receive the full stream from both Helius and BAM.

Subscribe Response

Store the result — it is the subscription ID you use to unsubscribe. After this acknowledgement, notifications stream as binary frames (see below).

Filtering

By default preconfSubscribe streams every transaction from both sources. To narrow the stream, pass a filter object as the first element of params. Filtering happens server-side, so you only pay for and receive the transactions you care about.
Every field is optional — a missing field means “no constraint” for that predicate, so an empty filter (or no params) matches every transaction from both sources. Filter rules:
  • All predicates are ANDed together, evaluated in the order includeBam → failed → regionInclude → accountExclude → accountRequired → accountInclude → signerInclude.
  • Preconfirmations with unknown status ignore the failed status filter and are still delivered if they match the source, region, and account filters.
  • Accounts are base58-encoded pubkeys. An invalid value returns JSON-RPC error -32602 (invalid params).
  • Each account list is capped at 500 entries.
To receive Helius preconfirmations only:

Address lookup table (ALT) resolution

Account filters match more than the transaction’s static account keys — Helius resolves v0 address lookup tables server-side, so accountInclude, accountExclude, and accountRequired also match accounts a transaction loads through an ALT. This means you can filter on any account a transaction touches, even when it only appears behind a lookup table — no need to maintain ALT mappings or resolve tables yourself. Just pass the account’s pubkey and Helius handles the resolution before the filter is applied.

Location filtering

Use regionInclude to receive only transactions that originate from specific regions. Pass one or more region codes; a transaction passes when its origin region matches any of them.
The origin region depends on the source. For Helius preconfirmations it is the Helius region that ingested the transaction. For BAM preconfirmations it is the regional BAM endpoint that emitted the preconfirmation, not where Helius ingested it. BAM’s Singapore and Dallas endpoints map to sgp and dal. Valid region codes:
When regionInclude is set, transactions that don’t carry region information are dropped. An unrecognized region code returns JSON-RPC error -32602 (invalid params).

Notification payload

Notifications are delivered as binary WebSocket frames (not JSON). Helius and BAM preconfirmations share the same layout. Each frame is a packed byte layout carrying a single transaction: The payload has no source field. Don’t infer a BAM origin from tx_index = 0, since Helius preconfirmations can carry the same values.

Telling the two sources apart

Because there is no source field, you cannot label an arbitrary message as Helius or BAM. The status byte gives you a one-way classifier:
  • status is 0 or 1 — the message is a Helius preconfirmation and the transaction has executed. BAM never reports these values.
  • status is 2 — the source is ambiguous: either a BAM preconfirmation, or a Helius preconfirmation whose execution status was unavailable.
No other field discriminates. BAM’s sequence ID and bundle position are not carried on this stream, so there is no BAM ordering metadata to key on, and regionInclude is a subscription filter rather than a payload field, so it can’t be read per message. If you need every message on a stream to carry the same kind of evidence, set includeBam: false — that leaves only Helius preconfirmations, all emitted at leader execution. There is no BAM-only filter.
Always read and check the version byte first. It is currently 1. If Helius needs to update the payload format, the version will increment — branch on it so your decoder keeps working across schema changes.
A preconfirmation is an early signal, not a guarantee. The transaction has not yet landed onchain and could still be dropped — and a Helius preconfirmation’s execution status reflects the leader’s local result, which is not final until the block is confirmed. Confirm landing through standard commitment checks before treating it as final.

Decoding the transaction

The transaction bytes are forwarded exactly as the validator serialized them, in the standard wire encoding for the transaction’s version. Legacy and v0 transactions use the signatures-first layout that bincode produces. Transaction v1 (SIMD-0385) uses a message-first layout with signatures at the end, so bincode fails on v1 payloads. Use a decoder that handles every version:
  • Rust: agave-transaction-view parses legacy, v0, and v1 transactions in place, without an intermediate copy. This is the recommended option. wincode, the bincode-compatible serializer used by current Solana SDKs, also decodes v1 into VersionedTransaction.
  • JavaScript / TypeScript: make sure your library version supports transaction v1. Older VersionedTransaction.deserialize implementations only handle legacy and v0. Use @solana/kit 8.0+ or @solana/web3.js v3. See Transaction v1 support.

Duplicate notifications

Helius and BAM preconfirmations are deduplicated per source, not across sources. A small share of transactions reach Helius through both, so you can receive the same signature twice, and the two copies may report different slots. Deduplicate by signature on the client and make transaction-triggered actions idempotent, so a second notification does not fire the same action twice. Confirm execution and landing through standard commitment checks.

Example

Unsubscribing

To stop receiving notifications, call preconfUnsubscribe with the subscription ID returned from preconfSubscribe.

Pricing

Preconfirmations require a Professional plan or higher and cost 10 credits per message — one message per streamed transaction — billed from your plan. See Credits for details. Billing is per message, not per unique signature. A transaction delivered by both Helius and BAM counts twice. Set includeBam: false if you only want Helius preconfirmations.
Preconfirmations is a new product and pricing is subject to change.

Preconfirmations Overview

What Preconfirmations are and where they sit in the validator pipeline.

transactionSubscribe

Stream confirmed-commitment transactions with rich filtering.

preconfSubscribe API reference

Request parameters, filter fields, and the binary notification layout.