Builders
Builder API reference
Endpoints, exact-body authentication, context fields, Capella payloads, submission status, and errors.
3 min readEndpoints#
| Method | Endpoint | Purpose |
|---|---|---|
| GET | https://rpc.blockferret.win/v1/builder-context | Current public template |
| POST | https://rpc.blockferret.win/builders | Signed builder JSON-RPC |
Exact-body authentication#
Every builder POST includes X-Flashbots-Signature: ADDRESS:SIGNATURE. Personal-sign the UTF-8 hex string of the exact body’s Keccak-256 hash, including its 0x prefix. With ethers 6:
import { id } from 'ethers';
const body = JSON.stringify(request);
const signature = await authWallet.signMessage(id(body));
const header = `${authWallet.address}:${signature}`;
// Send exactly `body` with X-Flashbots-Signature: header.Do not sign decoded hash bytes or change the body after signing. This uses the Flashbots authentication convention. The authentication wallet can be unfunded; actual payment transactions need their own funds and signatures.
Context fields#
| Field | Meaning |
|---|---|
slot | Decimal JSON number for the target duty |
proposerPubkey | 48-byte hex proposer public key |
parentHash, prevRandao | 32-byte hex execution attributes |
blockNumber, timestamp, gasLimit | Decimal numbers in context; hex quantities inside the payload |
feeRecipient, extraData, baseFeePerGas | Exact payload attributes; base fee is a hex quantity |
withdrawals | Ordered Capella withdrawals; preserve every value and their order |
publicTransactions | Signed public transactions to retain in order with unchanged outcomes |
validatorRecipient, builderWallet | Payment recipients |
baselinePayoutValueWei | Decimal string for reference; independent replay decides actual payment |
payoutGasLimit | Decimal number for the baseline payout gas limit |
snapshotHash, snapshotRevision, baselineBlockHash | Baseline identity; rebuild when it changes |
expiresAt, executionLimits | Expiry and current execution scope |
transactionCapabilities | Supported active-chain transaction formats |
blockferret_sendCandidateBlock#
The following is a JavaScript request shape. Replace the named values with the current context and your locally built complete payload.
const request = {
jsonrpc: "2.0",
id: 1,
method: "blockferret_sendCandidateBlock",
params: [{
slot: CURRENT_SLOT,
proposerPubkey: CURRENT_PROPOSER,
executionPayload: YOUR_COMPLETE_CAPELLA_PAYLOAD,
}],
};The payload requires parentHash, feeRecipient, stateRoot, receiptsRoot, logsBloom, prevRandao, blockNumber, gasLimit, gasUsed, timestamp, extraData, baseFeePerGas, blockHash, transactions, and withdrawals.
Payload quantities use hex strings. Withdrawal fields are index, validatorIndex, address, and amount. The outer slot is a decimal number.
Legacy, EIP-2930 access-list, and EIP-1559 transactions are supported on the current Capella path. Replay-protected signatures use chain ID 369. Check current context capabilities; blob and EIP-7702 envelopes are outside this path.
blockferret_getSubmissionStatus#
Acceptance returns a submissionId, bundleHash, state, and mode. Check status with the same authentication identity and a newly signed body:
{
"jsonrpc": "2.0",
"id": 1,
"method": "blockferret_getSubmissionStatus",
"params": [
{
"submissionId": "0xYOUR_32_BYTE_SUBMISSION_ID"
}
]
}A returned ID does not guarantee selection, a relay win, or canonical inclusion. There is no complete-block cancellation method and no automatic public broadcast fallback.
Limits#
| Limit | Current allowance |
|---|---|
| Request body | 8 MiB |
| Transactions per block | 10,000 |
| Builder submission and context, shared | 600 requests/minute |
| Per signing identity | 60 requests/minute |
| Concurrent builder requests | 2 |
| Complete-block queue | 16 entries |
| Complete-block queue accounting | 16 MiB at the current 32 MiB default |
| Maximum queue lifetime | 2 minutes; duty or parent may expire sooner |
Wallet HTTP capacity is separate and wallet work is scheduled first. The queue is held in memory, so a restart may require resubmission.
Errors#
| Response | Meaning / action |
|---|---|
| HTTP 401 | Missing or invalid authentication; check exact-body signing |
| HTTP 429 | Request, identity, or concurrency limit; back off |
| HTTP 503 | No fresh context, changed parent, or service not ready; retry a later window |
JSON-RPC -32602 | Invalid parameters or stale target |
JSON-RPC -32005 | Queue capacity reached |
Download the full API guide and example client.