
Searcher Builder
- 3 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Reference the Ethereum Builder API for proposer-builder separation - validator registration, getHeader, submit blinded block, and fork-specific payloads.
About
A reference skill for the Ethereum Builder API (builder-specs) covering proposer-builder separation, validator registration, header/bid fetching, and blinded block submission. A developer uses it when implementing or integrating builders, relays, or validator tooling.
- Validator registration, getHeader, and blinded block submit
- Fork-specific payload types from Bellatrix to Fulu
Searcher Builder by the numbers
- 3 all-time installs (skills.sh)
- Ranked #390 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill searcher-builderAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Reference the Ethereum Builder API for proposer-builder separation - validator registration, getHeader, submit blinded block, and fork-specific payloads.
Files
Skill is based on Ethereum builder-specs (Builder API), generated at 2026-02-24.
The Builder API lets consensus-layer clients obtain blocks from external builders (proposer-builder separation). It covers validator registration, fetching execution payload headers (bids), submitting signed blinded blocks, and fork-specific types (Bellatrix through Fulu). Use this skill when implementing or integrating with builders, relays, or validator tooling that speak the Builder API.
Core References
| Topic | Description | Reference |
|---|---|---|
| Builder API overview | Purpose, PBS context, roles, base URL, endpoint summary | core-overview |
| Endpoints | Validators, getHeader, blinded_blocks v1/v2, status — request/response | core-endpoints |
| Types and signing | ValidatorRegistration, BuilderBid, SignedBuilderBid, blinded blocks, DOMAIN_APPLICATION_BUILDER | core-types-and-signing |
Features
Registration and bidding
| Topic | Description | Reference |
|---|---|---|
| Validator registration | Eligibility, process_registration, validation rules | features-registration |
| getHeader and bidding | Bid eligibility, constructing BuilderBid, getHeader semantics | features-get-header-and-bidding |
| Submit blinded block | v1 vs v2, verification, payload reveal, builder publish | features-submit-blinded-block |
| Fork versions | Bellatrix/Capella/Deneb/Electra/Fulu bid and payload differences | features-fork-versions |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Encoding and headers | JSON vs SSZ, Content-Type, Accept, Eth-Consensus-Version, optional headers | best-practices-encoding-and-headers |
| Bid value verification | Deneb+ excluding withdrawals from bid value, relay verification | best-practices-bid-value-verification |
Generation Info
- Source:
sources/searcher-builder(https://github.com/ethereum/builder-specs) - Git SHA:
13bec3d8e74bf7570922b3735a79ad0a53fcc9a5 - Generated: 2026-02-24
Bid Value Verification (Deneb+)
From Deneb, withdrawals exist in the execution payload. The value in a BuilderBid must equal the payment to the proposer (fee_recipient), excluding any withdrawal amounts to that same address. Relays must enforce this before serving bids to proposers.
Why exclude withdrawals
Withdrawals change the fee_recipient balance as part of consensus. If the bid value included those amounts, the builder could inflate the bid with withdrawal funds. So the bid value is defined as the payment from the block’s transaction/block rewards to the fee_recipient, not including withdrawal payouts to that address.
Verification (relay / builder)
Compute:
balance_difference = post_state_balance - pre_state_balancefor the fee_recipient after applying the execution payload.excluded_amount = sum(w.amount for w in execution_payload.withdrawals if w.address == fee_recipient).proposer_payment = balance_difference - excluded_amount.
Then require proposer_payment == bid_value. Submissions that fail this check must be treated as invalid and must not be served to proposers.
Builder rules
Builders MUST not include withdrawal amounts to the fee_recipient when computing the value for their BuilderBid. Only the “true” payment (e.g. block reward, tx fees) should count toward value.
Agent usage
- Builder: When computing
valuefor a Deneb+ bid, subtract from the fee_recipient balance delta any withdrawals to that address. - Relay: After receiving an execution payload and bid, simulate the payload, compute
balance_difference, then run the verification above; reject or do not forward bids that fail.
<!-- Source references:
- sources/searcher-builder/specs/deneb/builder.md (Block scoring, Relaying, verify_bid_value)
-->
Encoding and Headers
JSON (default)
- Request:
Content-Type: application/json,Accept: application/json. - Response: Server sets
Content-Type: application/jsonon JSON responses.
All endpoints support JSON. Use it unless you need SSZ for size or compatibility.
SSZ
- Request with SSZ body:
Content-Type: application/octet-stream(e.g. validators, blinded_blocks). - Request SSZ response:
Accept: application/octet-stream;q=1.0,application/json;q=0.9(e.g. getHeader). - Only a subset of endpoints support SSZ in request or response; the spec notes which.
If the server cannot satisfy the requested format it returns 406 Not Acceptable. If the request body format is not supported it returns 415 Unsupported Media Type. When no Accept is sent, treat as application/json.
Builder-specific headers
- Eth-Consensus-Version: Required when the request or response is SSZ; indicates the consensus version (bellatrix, capella, deneb, electra, fulu). Optional for JSON.
- Date-Milliseconds: Optional; Unix timestamp in milliseconds when the getHeader request was sent; used for latency measurement.
- X-Timeout-Ms: Optional; proposer timeout in milliseconds for getHeader; relays may use it to time when to forward the request.
Agent usage
- Prefer JSON for simplicity; set
Content-TypeandAcceptexplicitly when using SSZ. - For getHeader, agents acting as relays can send
X-Timeout-Msso the builder/relay can optimize timing; includeEth-Consensus-Versionwhen requesting or sending SSZ.
<!-- Source references:
- sources/searcher-builder/builder-oapi.yaml (description, headers)
- sources/searcher-builder/apis/builder/header.yaml
- sources/searcher-builder/apis/builder/blinded_blocks.yaml
-->
Builder API Overview
The Builder API is an interface for consensus-layer (CL) clients to obtain blocks built by external builders. It enables proposer-builder separation (PBS): validators delegate block building to builders who compete on bid value; the proposer receives a blinded execution header and a payment, signs a blinded block, then the builder reveals the full payload.
Roles
- Builder: Builds execution payloads, registers validator preferences, returns
SignedBuilderBidfor a slot/parent/pubkey, and revealsExecutionPayload(and blobs when applicable) when the proposer submits a validSignedBlindedBeaconBlock. - Proposer (validator): Registers with builders, requests a header via
getHeader, signs the blinded block, then either receives the payload (v1) or relies on the builder to publish (v2).
Proposers typically connect to builders through relays or builder multiplexers (e.g. mev-boost, mev-rs, commit-boost).
Base URL and versioning
- Default base URL:
http://localhost:18550(configurableserver_url). - Paths: Under
/eth/v1/builder/or/eth/v2/builder/; endpoints are individually versioned (v1 vs v2 is per-path, not a global API version).
Endpoints summary
| Method | Path | Purpose |
|---|---|---|
| POST | /eth/v1/builder/validators | Register or update validator block-building preferences (fee recipient, gas limit). |
| GET | /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey} | Get execution payload header (SignedBuilderBid) for a slot. |
| POST | /eth/v1/builder/blinded_blocks | Submit signed blinded block; receive unblinded execution payload (v1, deprecated after Fulu). |
| POST | /eth/v2/builder/blinded_blocks | Submit signed blinded block; builder publishes block and blobs (v2). |
| GET | /eth/v1/builder/status | Health check. |
Consensus versions
Supported consensus versions in payloads and headers: bellatrix, capella, deneb, electra, fulu. Response shapes (e.g. blob commitments, execution_requests) depend on the fork.
<!-- Source references:
- sources/searcher-builder/README.md
- sources/searcher-builder/builder-oapi.yaml
-->
Builder API Types and Signing
Validator registration
- ValidatorRegistration:
fee_recipient(ExecutionAddress),gas_limit(uint64),timestamp(uint64),pubkey(BLSPubkey). - SignedValidatorRegistration:
message(ValidatorRegistration),signature(BLSSignature). Sent in bulk toPOST /eth/v1/builder/validators.
Builders must honour the latest registration per pubkey: fee recipient and gas limit for built blocks.
Builder bid
- BuilderBid (fork-dependent):
- Bellatrix/Capella:
header(ExecutionPayloadHeader),value(uint256, wei to fee_recipient),pubkey(builder BLS pubkey). - Deneb+: Adds
blob_kzg_commitments(list of KZG commitments for blobs). - Electra+: Adds
execution_requests(ExecutionRequests). - SignedBuilderBid:
message(BuilderBid),signature(BLSSignature). Returned bygetHeaderindata.
Blinded blocks
- BlindedBeaconBlock: Beacon block with
execution_payload_headerinstead of full execution payload (andblob_kzg_commitmentsfrom Deneb). - SignedBlindedBeaconBlock:
message(BlindedBeaconBlock),signature. Proposer signs this after choosing a bid; builder uses it to bind and reveal.
Signing domain
Builder API–specific messages (validator registration, builder bid) use:
- Domain:
DOMAIN_APPLICATION_BUILDER=DomainType('0x00000001'). - Signing root:
compute_signing_root(message, domain)withcompute_domain(DOMAIN_APPLICATION_BUILDER, fork_version=None, genesis_validators_root=None).
In-protocol messages (e.g. BlindedBeaconBlock) use the beacon block proposal domain from consensus-specs.
Constants
- MAX_REGISTRATION_LOOKAHEAD: 10 seconds — registration
timestampmust be ≤current_timestamp + MAX_REGISTRATION_LOOKAHEAD.
<!-- Source references:
- sources/searcher-builder/beacon-apis/types/registration.yaml
- sources/searcher-builder/types/bellatrix/bid.yaml
- sources/searcher-builder/types/capella/bid.yaml
- sources/searcher-builder/types/deneb/bid.yaml
- sources/searcher-builder/specs/bellatrix/builder.md
-->
Fork-Specific Builder Types
Builder API payloads and bids vary by consensus version. Use the correct schema and Eth-Consensus-Version when sending or interpreting SSZ.
Bellatrix / Capella
- BuilderBid:
header(ExecutionPayloadHeader),value,pubkey. - Submit response (v1):
ExecutionPayload(no blobs).
Capella adds withdrawals; ExecutionPayloadHeader includes withdrawals_root.
Deneb
- BuilderBid: Adds
blob_kzg_commitments(list of KZG commitments for blobs). - getHeader: Response includes blob KZG commitments.
- Submit (v1):
ExecutionPayloadAndBlobsBundle—execution_payload+blobs_bundle(commitments, proofs, blobs). - Block scoring: Builder must not include withdrawal
amounts in the bidvalue. Relays verify:proposer_payment = balance_difference - sum(withdrawal amounts to fee_recipient)and must equalbid_value.
Electra
- BuilderBid: Same as Deneb plus
execution_requests(ExecutionRequests). - BlindedBeaconBlockBody: Attester/proposer slashing and attestation list limits updated (EIP-7549); adds
execution_requests.
Fulu
- BlobsBundle:
proofslength changes (EIP-7594):FIELD_ELEMENTS_PER_EXT_BLOB * MAX_BLOB_COMMITMENTS_PER_BLOCK. - ExecutionPayloadAndBlobsBundle: Uses the updated BlobsBundle.
- v1 blinded_blocks: Deprecated; use v2.
Agent usage
- When parsing or building requests/responses, branch on
versionorEth-Consensus-Version(bellatrix, capella, deneb, electra, fulu). - For Deneb+, implement or rely on relay
verify_bid_valuelogic that excludes withdrawals from the proposer payment when validating bid value.
<!-- Source references:
- sources/searcher-builder/specs/bellatrix/builder.md
- sources/searcher-builder/specs/capella/builder.md
- sources/searcher-builder/specs/deneb/builder.md
- sources/searcher-builder/specs/electra/builder.md
- sources/searcher-builder/specs/fulu/builder.md
- sources/searcher-builder/builder-oapi.yaml (ConsensusVersion enum)
-->
getHeader and Bidding
getHeader semantics
GET /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey} returns a SignedBuilderBid when the builder has a valid bid for that (slot, parent_hash, pubkey). Return 204 when no bid is available (e.g. no block built, or not eligible).
Optional headers:
- Date-Milliseconds: Unix timestamp in ms when the request was sent (for latency measurement).
- X-Timeout-Ms: Proposer’s timeout in ms; relays may delay forwarding getHeader to maximize rewards while staying within this timeout.
Bid eligibility (builder side)
The builder should only return a bid when is_eligible_for_bid(state, registrations, slot, parent_hash, pubkey) holds:
state.slot == slot.pubkeyis inregistrations(validator has registered).pubkeyis the beacon proposer forslot(get_beacon_proposer_index(state)).parent_hash == state.latest_execution_payload_header.block_hash.
Constructing the bid
- Build an ExecutionPayload that pays the validator’s
fee_recipientas much as possible and respects the registeredgas_limit(or as close as consensus allows). - Build ExecutionPayloadHeader from the payload (e.g.
transactions_root = hash_tree_root(payload.transactions)). - BuilderBid:
header,value(wei to fee_recipient),pubkey(builder). Deneb+: addblob_kzg_commitments; Electra+: addexecution_requests. - SignedBuilderBid: Sign the bid with builder’s BLS key using
DOMAIN_APPLICATION_BUILDER; setmessageandsignature.
Agent usage
- Proposer/relay: Call getHeader at slot start with (slot, parent_hash, proposer pubkey); handle 200 (use
data) and 204 (no bid). - Builder: Maintain consensus state and registration store; only respond 200 when eligibility holds and you have a bid; otherwise 204 or 400.
<!-- Source references:
- sources/searcher-builder/specs/bellatrix/builder.md (Building, Bidding)
- sources/searcher-builder/apis/builder/header.yaml
-->
Submit Blinded Block (v1 and v2)
The proposer commits to a bid by signing a SignedBlindedBeaconBlock and submitting it to the builder. The builder then either returns the full payload (v1) or publishes the block and blobs itself (v2).
v1: POST /eth/v1/builder/blinded_blocks
- Response 200: Body is
{ version, data }wheredatais the unblinded ExecutionPayload (Bellatrix/Capella) or ExecutionPayloadAndBlobsBundle (Deneb+). The proposer/relay is responsible for publishing the block and blobs. - Deprecated after Fulu; use v2 for new integrations.
v2: POST /eth/v2/builder/blinded_blocks
- Response 202: Accepted. The builder MUST publish the signed unblinded beacon block and blobs to the network. No payload is returned to the client.
- Preferred for Deneb+ and when the builder should handle propagation.
Builder verification
Before accepting, the builder must verify:
- The signed blinded beacon block is valid under consensus rules.
- Blinded block signature:
verify_blinded_block_signature(state, signed_block)— check that the signature is from the expected proposer for the block’s slot using the beacon block proposal domain.
The proposer must accept at most one bid per slot to avoid proposer slashing.
Request format
- Eth-Consensus-Version: Required when sending SSZ; optional for JSON.
- Body: SignedBlindedBeaconBlock (JSON or SSZ). Fork-specific (Bellatrix/Capella/Deneb/Electra/Fulu); from Deneb the block body includes
blob_kzg_commitments.
Agent usage
- Proposer/relay: After selecting a bid, build the BlindedBeaconBlock, sign it, POST to v1 (to receive payload and publish yourself) or v2 (builder publishes). Prefer v2 when supported.
- Builder: On submit, verify signature and consensus validity; for v1 return payload/blobs; for v2 return 202 and publish block and blobs to the network.
<!-- Source references:
- sources/searcher-builder/apis/builder/blinded_blocks.yaml
- sources/searcher-builder/apis/builder/blinded_blocks_v2.yaml
- sources/searcher-builder/specs/bellatrix/builder.md (Revealing the ExecutionPayload, verify_blinded_block_signature)
-->