TriportRPC

Beacon API reverse proxy (CL path router)

GEThttps://api.triport.io/rpc/eth-beacon/eth/v1/node/syncing

Forwards Ethereum Consensus-Layer (Beacon) REST calls through to Triport's pooled CL nodes (Prysm / Lighthouse / Nimbus), with tier, family, and rate-limit enforcement applied per path.

Ethereumper-path feature (e.g. eth.beacon_standard) — see [Parameters](#parameters)Starter+ for standard reads; 5 rps light / 0.5 rps state-dump / 0.2 rps analysis (per-customer)

This endpoint is a path router that sits in front of Triport's Consensus-Layer node pool. You issue a normal Beacon Node REST API request, but prefixed with /rpc/eth-beacon/, and the platform picks a healthy CL host, forwards your GET, and streams the upstream response back to you with provider-identifying headers and fields removed.

The router exposes a curated whitelist of standard CL paths rather than the entire Beacon API surface. Paths fall into two groups:

  • Any-family standard paths (/eth/v1/node/*, /eth/v1/debug/*) — served by whatever CL client is healthy.
  • Client-specific namespaces (/lighthouse/*, /prysm/* + /eth/v1alpha1/*, /nimbus/*) — routed only to a host of the matching family.

A request to a path that is not on the whitelist returns 404 route_not_found; the surface is intentionally closed. The router accepts GET only — every other HTTP method returns 405 method_not_allowed.

Two behaviours are worth calling out up front:

  • The Server-Sent Events stream /rpc/eth-beacon/eth/v1/events is handled by a separate, higher-specificity handler — see the Beacon events (SSE) page. If that handler is not mounted, the path router returns 501 sse_handler_not_wired for it rather than attempting a normal forward.
  • Tier and per-path rate limits are enforced here. Heavy amplifier paths (state dumps, Lighthouse analysis) require higher tiers and have much lower per-customer RPS ceilings (see Notes).

Parameters

The "parameter" is the Beacon API path you append after /rpc/eth-beacon/, plus any query string, which is forwarded verbatim to the upstream node. Only the paths below are routable.

Path: any CL familyobject
Path: Lighthouse familyobject
Path: Prysm familyobject
Path: Nimbus familyobject
Headersobject

Response

The upstream Beacon API response body is returned unchanged except that operator-identifying fields are stripped. Headers are passed through, except that Server is replaced with Triport and hop-by-hop / Content-Length headers are recomputed.

data.head_slotstring
Slot of the node's current head.
data.sync_distancestring
Slots behind the chain head (0 when fully synced).
data.is_syncingboolean
Whether the node is still syncing.
data.is_optimisticboolean
Whether the head is optimistically imported.
data.el_offlineboolean
Whether the paired Execution-Layer client is unreachable.

Errors

Errors use a stable typed envelope:

{ "error": "route_not_found", "code": 404 }
Codeerror valueWhen it happens
403namespace_disabledPath resolves to a classified/admin capability that is not exposed.
404route_not_foundPath is not on the routable whitelist (or is exactly /rpc/eth-beacon/).
405method_not_allowedAny HTTP method other than GET.
500router_not_initializedCL pool is not configured on this deployment.
501sse_handler_not_wired/eth/v1/events reached the path router with no SSE handler mounted.
503cl_beacon_unavailableNo healthy CL host of the required family after a retry.
503cl_archive_unavailableSame as above for archive state-dump paths when strict archive routing is on.

4xx responses produced by the upstream Beacon node (e.g. 404 for an unknown slot, 400 for a malformed query) are forwarded to you as-is — those are legitimate Beacon API responses, not Triport errors. See the shared Errors page for the full envelope contract.

Examples

JavaScript (fetch)

const res = await fetch(
  "https://api.triport.io/rpc/eth-beacon/eth/v1/node/syncing",
  { headers: { Authorization: `Bearer ${process.env.TRIPORT_API_KEY}` } }
);
if (!res.ok) {
  const { error, code } = await res.json();
  throw new Error(`beacon proxy error ${code}: ${error}`);
}
const { data } = await res.json();
console.log("head slot:", data.head_slot, "syncing:", data.is_syncing);

TypeScript SDK (@triport/sdk)

import { Triport } from "@triport/sdk";


const tp = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });


// Generic Beacon REST passthrough — path is appended to /rpc/eth-beacon/
const { data } = await tp.ethereum.beacon.get("/eth/v1/node/syncing");
console.log(data.head_slot, data.is_syncing);

Python (triport-sdk)

import os
from triport import Triport


tp = Triport(api_key=os.environ["TRIPORT_API_KEY"])


resp = tp.ethereum.beacon.get("/eth/v1/node/syncing")
print(resp["data"]["head_slot"], resp["data"]["is_syncing"])

Notes

  • Closed whitelist. Only the paths listed under Parameters are routable; this is not an open passthrough of the entire Beacon API. Anything else returns 404 route_not_found.
  • GET only. The router never forwards mutating methods.
  • Family routing. /lighthouse/*, /prysm/* + /eth/v1alpha1/*, and /nimbus/* are routed only to a CL host of the matching client family. If no such host is healthy, you get 503 cl_beacon_unavailable rather than a cross-family response.
  • Failover. The router tries up to two healthy hosts per request before returning 503.
  • Rate limits are per-path classes, not a daily quota:
    • light — 5 rps per customer (most node/diagnostic reads).
    • state_dump — 0.5 rps per customer + 5 rps aggregate per host (/eth/v1/debug/beacon/states/{slot}, bodies up to ~226 MiB).
    • lh_analysis — 0.2 rps per customer + 10 rps aggregate per host (/lighthouse/analysis/*, bodies up to ~230 MB). Response bodies are capped at 256 MiB.
  • Related pages: Beacon events (SSE) for the /eth/v1/events live stream, and the Ethereum JSON-RPC transport for Execution-Layer calls.