Skip to main content

RPC Endpoint

danger

flashbots_getUserStats and flashbots_getBundleStats methods will be deprecated on March 31, 2023, use V2 methods!

How to interact directly with the Flashbots RPC endpoint#

Advanced users can interact with the RPC endpoint at relay.flashbots.net. The API provides JSON-RPC methods for interfacing with Flashbots which are documented below:

eth_sendBundle#

eth_sendBundle can be used to send your bundles to the Flashbots builder. The eth_sendBundle RPC has the following payload format:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_sendBundle",  "params": [    {      txs,               // Array[String], A list of signed transactions to execute in an atomic bundle      blockNumber,       // String, a hex encoded block number for which this bundle is valid on      minTimestamp,      // (Optional) Number, the minimum timestamp for which this bundle is valid, in seconds since the unix epoch      maxTimestamp,      // (Optional) Number, the maximum timestamp for which this bundle is valid, in seconds since the unix epoch      revertingTxHashes, // (Optional) Array[String], A list of tx hashes that are allowed to revert      replacementUuid,   // (Optional) String, UUID that can be used to cancel/replace this bundle    }  ]}

example:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_sendBundle",  "params": [    {      "txs": ["0x123abc...", "0x456def..."],      "blockNumber": "0xb63dcd",      "minTimestamp": 0,      "maxTimestamp": 1615920932    }  ]}

example response:

{  "jsonrpc": "2.0",  "id": "123",  "result": {    "bundleHash": "0x2228f5d8954ce31dc1601a8ba264dbd401bf1428388ce88238932815c5d6f23f"  }}

eth_callBundle#

eth_callBundle can be used to simulate a bundle against a specific block number, including simulating a bundle at the top of the next block. The eth_callBundle RPC has the following payload format:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_callBundle",  "params": [    {      txs,               // Array[String], A list of signed transactions to execute in an atomic bundle      blockNumber,       // String, a hex encoded block number for which this bundle is valid on      stateBlockNumber,  // String, either a hex encoded number or a block tag for which state to base this simulation on. Can use "latest"      timestamp,         // (Optional) Number, the timestamp to use for this bundle simulation, in seconds since the unix epoch    }  ]}

example:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_callBundle",  "params": [    {      "txs": ["0x123abc...", "0x456def..."],      "blockNumber": "0xb63dcd",      "stateBlockNumber": "latest",      "timestamp": 1615920932    }  ]}

example response:

{  "jsonrpc": "2.0",  "id": "123",  "result": {    "bundleGasPrice": "476190476193",    "bundleHash": "0x73b1e258c7a42fd0230b2fd05529c5d4b6fcb66c227783f8bece8aeacdd1db2e",    "coinbaseDiff": "20000000000126000",    "ethSentToCoinbase": "20000000000000000",    "gasFees": "126000",    "results": [      {        "coinbaseDiff": "10000000000063000",        "ethSentToCoinbase": "10000000000000000",        "fromAddress": "0x02A727155aeF8609c9f7F2179b2a1f560B39F5A0",        "gasFees": "63000",        "gasPrice": "476190476193",        "gasUsed": 21000,        "toAddress": "0x73625f59CAdc5009Cb458B751b3E7b6b48C06f2C",        "txHash": "0x669b4704a7d993a946cdd6e2f95233f308ce0c4649d2e04944e8299efcaa098a",        "value": "0x"      },      {        "coinbaseDiff": "10000000000063000",        "ethSentToCoinbase": "10000000000000000",        "fromAddress": "0x02A727155aeF8609c9f7F2179b2a1f560B39F5A0",        "gasFees": "63000",        "gasPrice": "476190476193",        "gasUsed": 21000,        "toAddress": "0x73625f59CAdc5009Cb458B751b3E7b6b48C06f2C",        "txHash": "0xa839ee83465657cac01adc1d50d96c1b586ed498120a84a64749c0034b4f19fa",        "value": "0x"      }    ],    "stateBlockNumber": 5221585,    "totalGasUsed": 42000  }}

eth_cancelBundle#

eth_cancelBundle is used to prevent a submitted bundle from being included on-chain. See bundle cancellations for more information.

ℹ️ replacementUuid must have been set when bundle was submitted.

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_cancelBundle",  "params": [    {      replacementUuid, // UUIDv4 to uniquely identify submission    }  ]}

eth_sendPrivateTransaction#

eth_sendPrivateTransaction is used to send a single transaction to Flashbots. Flashbots will attempt to build a block including the transaction for the next 25 blocks. See Private Transactions for more info.

eth_sendPrivateTransaction is also supported for free on Alchemy.

This method has the following JSON-RPC format:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_sendPrivateTransaction",  "params": [{    tx,               // String, raw signed transaction    maxBlockNumber,   // Hex-encoded number string, optional. Highest block number in which the transaction should be included.    preferences: { fast: boolean } // optional. "fast" left for backwards compatibility; may be removed in a future version  }]}

example request:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_sendPrivateTransaction",  "params": [    {      "tx": "0x123abc...",      "maxBlockNumber": "0xcd23a0",      "preferences": { "fast": true } // "fast" left for backwards compatibility; may be removed in a future version    }  ]}

example response:

{  "jsonrpc": "2.0",  "id": 1,  "result": "0x45df1bc3de765927b053ec029fc9d15d6321945b23cac0614eb0b5e61f3a2f2a" // tx hash}

eth_cancelPrivateTransaction#

The eth_cancelPrivateTransaction method stops private transactions from being submitted for future blocks. A transaction can only be cancelled if the request is signed by the same key as the eth_sendPrivateTransaction call submitting the transaction in first place.

eth_cancelPrivateTransaction is also supported for free on Alchemy.

This method has the following JSON-RPC format:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_cancelPrivateTransaction",  "params": [{    txHash,   // String, transaction hash of private tx to be cancelled  }]}

example request:

{  "jsonrpc": "2.0",  "id": 1,  "method": "eth_cancelPrivateTransaction",  "params": [    {      "txHash": "0x45df1bc3de765927b053ec029fc9d15d6321945b23cac0614eb0b5e61f3a2f2a"    }  ]}

example response:

{  "jsonrpc": "2.0",  "id": 1,  "result": true // true if tx successfully cancelled, false if not}

flashbots_getUserStats#

caution

flashbots_getUserStats will be deprecated soon, use flashbots_getUserStatsV2

The flashbots_getUserStats JSON-RPC method returns a quick summary of how a searcher is performing in the Flashbots ecosystem, including their reputation-based priority. It is currently updated once every hour and has the following payload format:

{  "jsonrpc": "2.0",  "id": 1,  "method": "flashbots_getUserStats",  "params": [      blockNumber,       // String, a hex encoded recent block number, in order to prevent replay attacks. Must be within 20 blocks of the current chain tip.  ]}

example response:

{  "is_high_priority": true,  "all_time_miner_payments": "1280749594841588639",  "all_time_gas_simulated": "30049470846",  "last_7d_miner_payments": "1280749594841588639",  "last_7d_gas_simulated": "30049470846",  "last_1d_miner_payments": "142305510537954293",  "last_1d_gas_simulated": "2731770076"}

where

  • is_high_priority: boolean representing if this searcher has a high enough reputation to be in the high priority queue
  • all_time_miner_payments: the total amount paid to validators over all time
  • all_time_gas_simulated: the total amount of gas simulated across all bundles submitted to Flashbots. This is the actual gas used in simulations, not gas limit
note

Parameters with miner in the name are retrofitted with Flashbots block builder data to maintain backwards compatibility. This nomenclature will be changed in a future release to accurately reflect PoS Ethereum architecture.

flashbots_getBundleStats#

caution

flashbots_getBundleStats will be deprecated soon, use flashbots_getBundleStatsV2

The flashbots_getBundleStats JSON-RPC method returns stats for a single bundle. You must provide a blockNumber and the bundleHash, and the signing address must be the same as the one who submitted the bundle.

{  "jsonrpc": "2.0",  "id": 1,  "method": "flashbots_getBundleStats",  "params": [    {      bundleHash,       // String, returned by the flashbots api when calling eth_sendBundle      blockNumber,       // String, the block number the bundle was targeting (hex encoded)    }  ]}

example response:

{  "isSimulated": true,  "isSentToMiners": true,  "isHighPriority": true,  "simulatedAt": "2021-08-06T21:36:06.317Z",  "submittedAt": "2021-08-06T21:36:06.250Z",  "sentToMinersAt": "2021-08-06T21:36:06.343Z",  "receivedAt": "2022-10-06T21:36:06.250Z", // Added for POS, will be included as part of V2  "consideredByBuildersAt": [        {            "pubkey": "0x81babeec8c9f2bb9c329fd8a3b176032fe0ab5f3b92a3f44d4575a231c7bd9c31d10b6328ef68ed1e8c02a3dbc8e80f9",            "timestamp": "2022-10-06T21:36:06.343Z"        },        {            "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f",            "timestamp": "2022-10-06T21:36:06.394Z"        },        {            "pubkey": "0xa1dead1e65f0a0eee7b5170223f20c8f0cbf122eac3324d61afbdb33a8885ff8cab2ef514ac2c7698ae0d6289ef27fc",            "timestamp": "2022-10-06T21:36:06.322Z"        }    ], // Added for POS, will be included as part of V2  "sealedByBuildersAt": [    {      "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f",            "timestamp": "2022-10-06T21:36:07.742Z"        }  ] // Added for POS, will be included as part of V2}

flashbots_getUserStatsV2#

The flashbots_getUserStatsV2 JSON-RPC method returns a quick summary of how a searcher is performing in the Flashbots ecosystem, including their reputation-based priority. It is currently updated once every hour and has the following payload format:

{  "jsonrpc": "2.0",  "id": 1,  "method": "flashbots_getUserStatsV2",  "params": [    {      blockNumber       // String, a hex encoded recent block number, in order to prevent replay attacks. Must be within 20 blocks of the current chain tip.    }  ]}

example response:

{  "isHighPriority": true,  "allTimeValidatorPayments": "1280749594841588639",  "allTimeGasSimulated": "30049470846",  "last7dValidatorPayments": "1280749594841588639",  "last7dGasSimulated": "30049470846",  "last1dValidatorPayments": "142305510537954293",  "last1dGasSimulated": "2731770076"}

where

  • isHighPriority: boolean representing if this searcher has a high enough reputation to be in the high priority queue
  • allTimeValidatorPayments: the total amount paid to validators over all time
  • allTimeGasSimulated: the total amount of gas simulated across all bundles submitted to Flashbots. This is the actual gas used in simulations, not gas limit

flashbots_getBundleStatsV2#

The flashbots_getBundleStatsV2 JSON-RPC method returns stats for a single bundle. You must provide a blockNumber and the bundleHash, and the signing address must be the same as the one who submitted the bundle.

{  "jsonrpc": "2.0",  "id": 1,  "method": "flashbots_getBundleStatsV2",  "params": [    {      bundleHash,       // String, returned by the flashbots api when calling eth_sendBundle      blockNumber,       // String, the block number the bundle was targeting (hex encoded)    }  ]}

example response:

{  "isHighPriority": true,  "isSimulated": true,  "simulatedAt": "2022-10-06T21:36:06.317Z",  "receivedAt": "2022-10-06T21:36:06.250Z",  "consideredByBuildersAt": [        {            "pubkey": "0x81babeec8c9f2bb9c329fd8a3b176032fe0ab5f3b92a3f44d4575a231c7bd9c31d10b6328ef68ed1e8c02a3dbc8e80f9",            "timestamp": "2022-10-06T21:36:06.343Z"        },        {            "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f",            "timestamp": "2022-10-06T21:36:06.394Z"        },        {            "pubkey": "0xa1dead1e65f0a0eee7b5170223f20c8f0cbf122eac3324d61afbdb33a8885ff8cab2ef514ac2c7698ae0d6289ef27fc",            "timestamp": "2022-10-06T21:36:06.322Z"        }    ],  "sealedByBuildersAt": [    {      "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f",            "timestamp": "2022-10-06T21:36:07.742Z"        }  ]}

where

  • isHighPriority: boolean representing if this searcher has a high enough reputation to be in the high priority queue
  • isSimulated: boolean representing whether the bundle gets simulated. All other fields will be omitted except simulated field if API didn't receive bundle
  • simulatedAt: time at which the bundle gets simulated
  • receivedAt: time at which the bundle API received the bundle
  • consideredByBuildersAt: indicates time at which each builder selected the bundle to be included in the target block
  • sealedByBuildersAt: indicates time at which each builder sealed a block containing the bundle

API Response#

  • All method supports JSON-RPC standards for success response and not supported for error response(V2 methods are exceptions).
  • V2 methods supports JSON-RPC standards for both success and error response.

Authentication#

To authenticate your request, Flashbots endpoints require you to sign the payload and include the signed payload in the X-Flashbots-Signature header of your request.

curl -X POST -H "Content-Type: application/json" -H "X-Flashbots-Signature: 0x1234:0xabcd" --data '{"jsonrpc":"2.0","method":"eth_sendBundle","params":[{see above}],"id":1}' https://relay.flashbots.net

Any valid Ethereum key can be used to sign the payload. The Ethereum address associated with this key will be used by Flashbots to keep track of your requests over time and provide user statistics. You can change the key you use at any time.

The signature is calculated by taking the EIP-191 hash of the json body encoded as UTF-8 bytes. Here's an example using ethers.js:

import { Wallet, utils } from "ethers";
const privateKey = "0x1234";const wallet = new Wallet(privateKey);const body =  '{"jsonrpc":"2.0","method":"eth_sendBundle","params":[{see above}],"id":1}';const signature = wallet.address + ":" + wallet.signMessage(utils.id(body));