This EIP specifies a binary SSZ transport for Engine API communication between consensus layer (CL) and execution layer (EL) clients. The binary transport replaces JSON-RPC with resource-oriented REST endpoints and raw SSZ encoding for fast, efficient CL-EL communication. SSZ container definitions are provided for all Engine API structures and methods across all forks for backwards compatibility.
Motivation
Fast communication between the consensus layer and execution layer is critical for block propagation and validation timing. The JSON-RPC transport introduces unnecessary overhead in this critical path:
Binary data (hashes, addresses, transactions, blobs) is hex-encoded, doubling wire size.
JSON parsing and generation adds CPU overhead on both sides.
The CL uses SSZ natively, forcing a round-trip conversion (SSZ → JSON, then JSON → internal types) at the Engine API boundary.
Binary SSZ eliminates all of this. The CL sends raw SSZ bytes over HTTP; the EL deserializes directly. No hex encoding, no JSON parsing, no intermediate representations. Payload sizes are reduced by ~50% compared to JSON-RPC, and serialization is no longer a bottleneck in the critical path between CL and EL.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Transport
The binary SSZ transport uses resource-oriented REST over HTTP. Endpoints are organized by resource type (payloads, forkchoice, blobs) with per-endpoint versioning, following the same conventions as the Beacon API.
Base URL
All endpoints are served under the /engine prefix on the existing Engine API port (default 8551):
http://localhost:8551/engine
Content Types
Header
Value
Description
Content-Type (request)
application/octet-stream
SSZ-encoded request container
Content-Type (response)
application/octet-stream
SSZ-encoded response (success)
Content-Type (response)
text/plain
Human-readable error message
Accept (request)
application/octet-stream
Client accepts SSZ-encoded responses
Request bodies are the SSZ serialization of the endpoint’s request container. Response bodies are the SSZ serialization of the endpoint’s response type. GET requests with no body SHOULD include the Accept header to indicate SSZ preference.
Authentication
The binary transport uses the same JWT authentication as the JSON-RPC endpoint. All requests MUST include a valid JWT bearer token in the Authorization header:
Authorization: Bearer <JWT token>
All existing authentication requirements from the Engine API specification apply.
Versioning
Endpoints use path-based versioning following Beacon API conventions. Each endpoint includes a version number in its path (e.g., /engine/v5/payloads). The version number corresponds to the JSON-RPC method version it replaces:
SSZ REST Endpoint
JSON-RPC Equivalent
POST /engine/v5/payloads
engine_newPayloadV5
GET /engine/v6/payloads/{payload_id}
engine_getPayloadV6
POST /engine/v4/forkchoice
engine_forkchoiceUpdatedV4
POST /engine/v3/blobs
engine_getBlobsV3
When a new fork introduces a new method version, a new versioned endpoint is added. Older versioned endpoints MAY be deprecated but SHOULD remain available for backwards compatibility.
HTTP Status Codes
Success
Status
Meaning
Usage
200
OK
Request succeeded, response body contains SSZ-encoded result
204
No Content
Null result (e.g., syncing), empty body
Client Errors
Status
Meaning
Usage
400
Bad Request
Malformed SSZ encoding
401
Unauthorized
Missing or invalid JWT token
404
Not Found
Unknown payload ID
409
Conflict
Invalid forkchoice state
413
Request Too Large
Request exceeds maximum element count
422
Unprocessable Entity
Invalid payload attributes
Server Errors
Status
Meaning
Usage
500
Internal Server Error
Unexpected server error
Error responses use Content-Type: text/plain with a human-readable error message body.
Each JSON-encoded base type used in the Engine API maps to a specific SSZ type:
JSON-RPC Type
SSZ Type
address (20 bytes)
Bytes20
hash32 (32 bytes)
Bytes32
bytes8 (8 bytes)
Bytes8
bytes32 (32 bytes)
Bytes32
bytes48 (48 bytes)
Bytes48
bytes256 (256 bytes)
ByteVector[256]
uint64
uint64
uint256
uint256
BOOLEAN
boolean
bytes (variable-length)
ByteList[MAX_LENGTH] (context-dependent)
bytesMax32 (0 to 32 bytes)
ByteList[32]
Array of T
List[T, MAX_LENGTH] (context-dependent)
T or null
List[T, 1]
Nullable types are represented as List[T, 1] in SSZ encoding. An empty list (0 elements) denotes absence (null). A list with one element denotes presence.
All endpoints use Content-Type: application/octet-stream for request and response bodies containing SSZ-encoded data. Error responses use Content-Type: text/plain.
Payloads
POST /engine/v{N}/payloads — Submit execution payload
Submit an execution payload for validation. The EL validates the payload and returns its status.
GET /engine/v{N}/payloads/{payload_id} — Retrieve built payload
Retrieve an execution payload previously requested via forkchoice update with payload attributes. The {payload_id} path parameter is the hex-encoded Bytes8 payload identifier (e.g., 0x1234567890abcdef).
Version
Fork
Response Type
JSON-RPC Equivalent
v1
Paris
ExecutionPayloadV1
engine_getPayloadV1
v2
Shanghai
GetPayloadResponseV2
engine_getPayloadV2
v3
Cancun
GetPayloadResponseV3
engine_getPayloadV3
v4
Prague
GetPayloadResponseV4
engine_getPayloadV4
v5
Osaka
GetPayloadResponseV5
engine_getPayloadV5
Request: No body. The payload ID is in the URL path.
Response:200 OK — SSZ-encoded response type from the table above.
POST /engine/v{N}/payloads/bodies/by-hash — Get payload bodies by hash
Retrieve execution payload bodies for a list of block hashes.
REST is well understood, easy to debug, and infrastructure already exists for it (load balancers, proxies, monitoring). The Beacon API already uses REST with SSZ and it works well. Going lower level (raw TCP, custom framing) adds complexity without a clear benefit for the EL-CL link, which is typically localhost communication.
Why same port instead of a separate port?
Serving both JSON-RPC and SSZ REST on the same port simplifies deployment and configuration. There’s no need for operators to manage an additional port, firewall rule, or JWT secret. The two transports coexist cleanly — JSON-RPC uses POST / with Content-Type: application/json, while SSZ REST uses resource-oriented paths with Content-Type: application/octet-stream.
Why application/octet-stream?
This is the standard content type for binary data. The Beacon API already uses it for SSZ responses. It signals that the body is raw bytes, not text, which is exactly what SSZ is.
Why text/plain for errors instead of JSON?
Errors are small, infrequent, and need to be human-readable for debugging. A plain text message body is the simplest possible approach — no parsing needed, just log it. JSON error bodies add complexity for minimal gain.
No hard fork required
This is purely a client-side change. It’s a new transport option for an existing API — no consensus changes, no state transition changes, no new opcodes. Clients can implement it whenever they want and roll it out with a regular release.
Backwards Compatibility
This EIP introduces a new transport protocol alongside the existing JSON-RPC Engine API. The JSON-RPC API remains fully functional and is always available. Clients that don’t implement binary SSZ are unaffected.
Security Considerations
The SSZ REST transport uses the same JWT authentication as the JSON-RPC endpoint. All existing authentication requirements apply.
SSZ deserialization MUST enforce the same size limits as JSON deserialization. Implementations MUST reject SSZ payloads exceeding defined maximum sizes before attempting full deserialization.
Implementations SHOULD use well-tested SSZ libraries and fuzz test SSZ parsing extensively.
The {payload_id} path parameter MUST be validated as a well-formed hex-encoded Bytes8 before processing.
Giulio Rebuffo (@Giulio2002), "EIP-8178: Binary SSZ Transport for the Engine API [DRAFT]," Ethereum Improvement Proposals, no. 8178, March 2026. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-8178.