alchemy_simulateExecutionBundle — Ethereum JSON-RPC
Simulates an ordered bundle of Ethereum transactions against a chosen block state and returns the per-transaction execution result for each one, without broadcasting anything on-chain.
https://triport.io/eth- Network
- Ethereum
- Auth
- x-token: $TRIPORT_API_KEY (or Authorization: Bearer)
- Rate limit
- Pro — 5 RPS sustained · up to 10 burst · Business — 15 RPS sustained · up to 30 burst; Burst capacity
Endpoint and plans: Ethereum RPC endpoint.
alchemy_simulateExecutionBundle runs a list of transactions in sequence
against the EVM state at a given block, exactly as if they had been mined back
to back in a single block, and returns a result entry for each transaction.
State changes made by an earlier transaction in the bundle are visible to the
transactions that follow it, so you can model multi-step flows (approve →
swap → settle, sandwich detection, complex arbitrage paths) before you ever
sign or send them.
Nothing is broadcast and no state is persisted — the call is a read-only
simulation over a forked copy of the chosen block state. Use it to estimate
gas across a whole bundle, to confirm that every step would succeed before you
submit the real bundle with eth_sendBundle (not served on the shared Ethereum endpoint), or to
inspect the raw return data of each call.
This method belongs to the eth_trace category. It is available on the pro
tier (5 RPS) and business tier (15 RPS); calls on lower tiers are rejected
with HTTP 403 tier_insufficient (see Errors).
Parameters
A single positional parameter: a bundle object.
txsstring[]required0x-prefixed hex). They are simulated in array order.blockNumberstringoptional"0x149e2c2") or a tag ("latest", "pending"). Defaults to "latest".timestampnumberoptionalblock.timestamp during simulation. Defaults to the timestamp of the target block.Response
Response fields
| Field | Type | Description |
|---|---|---|
result.blockNumber | string | Hex block number whose state the bundle was simulated against. |
result.totalGasUsed | string | Hex total gas consumed by all transactions in the bundle. |
result.results | object[] | Per-transaction results, in the same order as the txs input. |
result.results[].success | boolean | true if the transaction executed without reverting. |
result.results[].gasUsed | string | Hex gas used by this individual transaction. |
result.results[].returnData | string | 0x-prefixed raw return data of the call. |
result.results[].error | string | null | Revert reason or execution error for this transaction, or null on success. |
Errors
Upstream node errors arrive in the standard JSON-RPC error object. Tier and
rate-limit rejections do not: they are decided before the request reaches the
RPC layer and come back as plain HTTP responses. See the shared
Errors reference for both shapes.
| Code | Meaning | When it happens |
|---|---|---|
403 | tier_insufficient | Your key is below the pro tier required for this method. A plain HTTP body carrying current_tier, required_tier, method, category and upgrade_url at the top level, plus an X-Required-Tier header. |
429 | rate_limited | You exceeded your tier's RPS for the eth_trace category (5 RPS sustained · up to 10 burst pro / 15 RPS sustained · up to 30 burst business). A plain HTTP body carrying limit_rps, burst_capacity and retry_after_sec; the response also sets Retry-After and X-RateLimit-Reset headers. |
Example tier_insufficient response (HTTP 403, plain body — no JSON-RPC envelope):
{
"error": "tier_insufficient",
"message": "Method 'alchemy_simulateExecutionBundle' requires pro tier or higher",
"current_tier": "free",
"required_tier": "pro",
"method": "alchemy_simulateExecutionBundle",
"category": "eth_trace",
"upgrade_url": "https://triport.io/upgrade/pro"
}Examples
JavaScript (fetch)
const res = await fetch("https://triport.io/eth", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "alchemy_simulateExecutionBundle",
params: [{
txs: [rawTx1, rawTx2],
blockNumber: "latest",
}],
}),
});
const { result, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);
console.log(`bundle gas: ${parseInt(result.totalGasUsed, 16)}`);
for (const [i, tx] of result.results.entries()) {
console.log(`tx[${i}] success=${tx.success} gas=${parseInt(tx.gasUsed, 16)}`);
}Notes
- Transactions are simulated in order and share state — a later transaction sees the effects of every earlier one in the same bundle.
- This is a simulation only; it neither broadcasts transactions nor changes
on-chain state. To actually submit a validated bundle for inclusion, use
eth_sendBundlethrough the private RPC forwarder; it is not served on the shared Ethereum endpoint. - Rate limiting is RPS-per-tier with a burst allowance; there is no daily quota.
On HTTP
429rate_limited, honor theRetry-Afterheader before retrying. - All numeric quantities (
gasUsed,totalGasUsed, block numbers) are0x-prefixed hex, following standard Ethereum JSON-RPC conventions.