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 is available on all paid plans — 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 includeSource → failed → regionInclude → signatures → accountExclude → accountRequired → accountInclude → signerExclude → signerInclude → instructions.
  • BAM preconfirmations with unknown status ignore the failed filter. Helius preconfirmations with unknown status do not match an explicit failed filter.
  • includeSource must be an array containing only helius and bam. An invalid value returns JSON-RPC error -32602 (invalid params).
  • Accounts are base58-encoded pubkeys. An invalid value returns JSON-RPC error -32602 (invalid params).
  • Each account or signer list is capped at 10,000 entries. signatures is capped at 1,000 entries.
The deprecated includeBam filter remains available for backward compatibility. includeBam: false equals includeSource: ["helius"]. includeBam: true or an omitted field selects both sources. Do not send includeBam and includeSource together.
To receive Helius preconfirmations only:

Signer and signature filtering

Use signerInclude to match transactions signed by a specific account. Use signerExclude to remove transactions signed by any listed account. A referenced account does not count as a signer. Use signatures when you already know the transactions you want to track. The filter matches the first transaction signature, which is the signature used by Solana RPC methods. The filter cannot change after you subscribe, so create a new subscription to track new signatures.

Instruction filtering

Use instructions to match top-level instructions by program and instruction data. Each instruction filter supports these fields: Each memcmp entry accepts base58, base64, or hex encoding. The default is base58. A transaction matches when one top-level instruction passes every condition in any instruction filter. The following request matches pump.fun buy instructions by their Anchor discriminator:
The filter only checks top-level instructions. It cannot match instructions invoked through cross-program invocation (CPI) because those instructions do not exist before execution. You can provide up to 16 instruction filters and four memcmp entries per instruction filter. Each memcmp value must decode to 1–128 bytes. A memcmp end offset and dataSize must not exceed 4,096 bytes.

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 other sources may also report 0.

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 includeSource: ["helius"] or includeSource: ["bam"]. A Helius-only stream contains preconfirmations emitted at leader execution.
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 are available on all paid plans: Developer, Business, Professional, and Enterprise. Free plans are not eligible. See Credits for details. Slots with zero delivered messages cost zero credits, even when the slot has preconfirmation coverage. When a slot delivers at least one message, each open preconfSubscribe subscription is billed the greater of 300 credits or 10 credits per delivered message. Uncovered slots cost zero. See Pricing for source and region billing eligibility. Each concurrent subscription is billed independently when it receives at least one message. Close subscriptions you no longer need with preconfUnsubscribe. With includeSource: ["helius"], BAM-only covered slots are excluded from billing. When regionInclude is set, covered slots outside the selected regions cost zero for that subscription; matching slots are billed only when the subscription receives at least one message. Billing is per message, not per unique signature. A transaction delivered by both Helius and BAM counts twice. Set includeSource: ["helius"] if you only want Helius preconfirmations.
To control costs, consolidate account filters into one subscription where practical, use regionInclude to limit billing to the regions you need, set includeSource: ["helius"] when you do not need BAM, and monitor credits in the Helius Dashboard.
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.