sendBundle — Solana JSON-RPC

Status: Available

Submits an ordered MEV bundle — a list of Solana transactions — to be landed atomically, all-or-nothing, in a single block.

POSThttps://triport.io/sol
Network
Solana
Scope
sol_send_bundle
Auth
x-token: $TRIPORT_API_KEY (or Authorization: Bearer)
Rate limit
pro+ — 10 / 30 RPS sustained · short burst 20 / 60 (pro / business); Burst capacity

Endpoint and plans: Solana RPC endpoint.

sendBundle submits an ordered bundle of fully-signed Solana transactions to be executed back-to-back, atomically, within a single block. Either every transaction in the bundle lands in the given order, or none of them do — there is no partial execution. This is the submission counterpart to simulateBundle, which dry-runs the same bundle without broadcasting it.

Because the bundle lands atomically and in order, later transactions can safely depend on the state changes produced by earlier ones (for example, a swap that funds a later repay). Use it for MEV / atomic-arbitrage strategies and any sequence of dependent transactions that must not be interleaved with other traffic.

This is a pro-tier-only method, rate-limited separately under the sol_send_bundle category at 10 RPS (pro) / 30 RPS (business), with burst headroom of twice the sustained limit. Always simulateBundle first: a bundle that would revert is rejected at submission, and you still consume your send budget.

Parameters

JSON-RPC params is a positional array whose first element is the transaction array itself: [[tx1, tx2, ...], config?].

params[0]string[]required
Ordered list of fully-signed, base64-encoded transactions. Landed in array order, atomically.
params[1]objectoptional
Optional submission config, e.g. { "encoding": "base64" }.

Response

The result is an open object; additional fields may appear.

resultobject
Open response envelope (additionalProperties allowed).
result.bundleIdstring
Opaque identifier for the accepted bundle. Use it to track landing status.
result.signaturesstring[]
Per-transaction signatures, base-58 encoded, in bundle order.

Errors

Errors are returned in the standard JSON-RPC error envelope. See the shared errors reference for the full envelope shape and shared codes.

CodeMeaningWhen it happens
-32602Invalid paramsparams[0] is missing/empty ("bundle has no transactions"), not an array, or a transaction is not decodable under the chosen encoding.
403Tier insufficientThe key's tier is below pro. An HTTP error with a plain JSON body — there is no JSON-RPC envelope: {"error":"tier_insufficient", …} with current_tier, required_tier, method, category (sol_send_bundle) and upgrade_url, plus an X-Required-Tier header.
429Rate limitedMore than your tier's sustained RPS on sol_send_bundle (10 pro / 30 business). Body {"error":"rate_limited", …} with limit_rps, burst_capacity and retry_after_sec; honour Retry-After (and X-RateLimit-Reset).
401UnauthorizedMissing or invalid Authorization: Bearer key.

A tier-insufficient response is an HTTP 403 with a plain body — there is no JSON-RPC envelope:

{
  "error": "tier_insufficient",
  "message": "Method 'sendBundle' requires pro tier or higher",
  "current_tier": "free",
  "required_tier": "pro",
  "method": "sendBundle",
  "category": "sol_send_bundle",
  "upgrade_url": "https://triport.io/upgrade/pro"
}

Examples

JavaScript (fetch)

const res = await fetch("https://triport.io/sol", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "sendBundle",
    params: [
      [base64Tx1, base64Tx2],
      { encoding: "base64" },
    ],
  }),
});


const { result, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);


console.log("bundle accepted:", result.bundleId);

Notes

  • Encoding: transactions are base64-encoded strings passed directly as the params[0] array. The result envelope is open — new fields may be added.
  • Pro tier only: sol_send_bundle has no free or basic access — see rate limits and tiers.
  • Atomic and ordered: the whole bundle lands together in array order or not at all — there is no partial inclusion.
  • Simulate first: dry-run with simulateBundle before submitting; it shares the bundle model and catches reverts without spending your send budget.
  • Acceptance ≠ landing: a successful response means the bundle was accepted, not confirmed. Poll getSignatureStatuses or getTransaction to verify it landed.
  • Single transactions: to broadcast one transaction at a time, use sendTransaction instead.