bdn.submitBundle → mod_bdn → the Jito block engine. You sign
the transactions yourself; FirstByte forwards the already-signed payload
without modifying it or reordering it.
When to use a bundle instead of a single submit
Use a bundle when the correctness of transaction n depends on transaction n-1 having executed in the same slot — the classic cases being a back-run, a sandwich, a liquidation paired with the swap that funds it, or any sequence where a partial fill is worse than no fill. Use a single submit (BDN fan-out or direct TPU) when each transaction stands on its own and you only care about inclusion latency. A bundle is the wrong tool there: it adds the tip transaction and the all-or-nothing constraint for no benefit.Building the bundle payload
The bundle builder takes one base64-encoded signed transaction per line. Blank lines are ignored. Line order is the execution order — the first line executes first.
The base64 check runs per line and reports the first offending line by its
position in the textarea, counting blank lines, so the number matches what you
see in the editor. A line fails if it contains characters outside
A–Z a–z 0–9 + / =, or if it matches that character set but still does not
decode.
The live counter under the textarea shows txs N / 5 and turns red once you
pass five lines.
Before submitting, the console joins the non-blank, trimmed lines back together
with newlines. Leading and trailing whitespace on each line is therefore
harmless; whitespace inside a base64 payload is not, because it breaks the
character check.
Tipping
There is no separate tip field, and no tip parameter on the submit call. Include the Jito tip transfer as one of the transactions in the signed bundle itself. The BDN forwards the bundle atomically, so the tip transfer lands or fails with the rest of the bundle. Because the tip is just another transaction, it counts against the five-transaction limit: a bundle with a tip has at most four transactions of your own logic. Where you place the tip line is your decision, and it is a real one — the tip executes in the position you put it in. A tip on the last line is only paid if the preceding transactions all succeed, which is the usual reason to put it there. The Recent bundles table reads the tip back out of each bundle and renders it in SOL, converted from lamports.Submitting and reading the bundle id
Submission is a single mutation:
The response is read as follows:
- Anything where
okis notfalseis treated as accepted. If the response carries abundleId, the console shows it (truncated) next to a livesubmittedpill; if it does not, it showsbundle accepted. - If
okisfalse, the console surfaceserras the failure reason, falling back tobundle submit failed. - A transport-level failure surfaces the thrown error’s
message, falling back torequest failed.
bundleId. It is the handle that links this submission to the row that
later appears in Recent bundles, and therefore to the slot the bundle landed
in.
While the mutation is pending the button reads Landing…, so treat the
in-flight window as “outcome not yet known” rather than “not submitted”.
Signing in on the portal is what enables the submit button in the console. The
API itself accepts your key regardless of portal session state — see the
API keys screen for the direct call.
Bundle states and the slot column
Recent bundles lists bundles submitted via the BDN for the org, with one row per bundle:landed is the terminal success state, and the only one the table marks as
live. A row in any other state has no landed slot, so its Slot cell shows
—: the slot is populated precisely when the block engine has included the
bundle. That makes the pairing of State and Slot the thing to read — a
bundle id with a slot is on-chain, a bundle id without one is not.
A bundle that does not land keeps its all-or-nothing property: none of its
transactions executed, including the tip transfer. You are free to rebuild and
resubmit, but do so with fresh signed transactions rather than reusing the same
payload blindly, since blockhash validity and account state both move on.
Failures that happen before the block engine sees the bundle never produce a
row here at all — they come back inline on the submit call as ok: false with
an err, or as a request error.
Limits and cluster scope
- Five transactions per bundle, inclusive of the tip transfer. The console blocks a sixth line client-side.
- One base64 signed transaction per line. FirstByte does not sign, re-encode, or reorder anything in the payload.
- Atomic and ordered. The bundle lands whole, in your line order, or not at all.
- The console submits to
mainnet. Theclusterfield is what selects the target, so a different cluster is a different value on the same call rather than a different endpoint.
orgId;
switching the active org switches the Recent bundles list with it.
Related
- Authentication — API keys for direct
submitBundlecalls from your backend - Telemetry — metrics and traces for submission paths