TriportRPC

Private RPC forwarder

POSThttps://api.triport.io/rpc/eth-private/protect

Submit raw transactions and bundles to MEV-protected private endpoints without ever touching the public mempool.

Ethereum— (gated by plan tier)Growth or Scale; per-tier RPS with burst (see [Rate limits](../../rate-limits.md))

The private RPC forwarder is a write-only JSON-RPC channel. You POST a signed transaction (or a bundle) to a named private-transaction endpoint and Triport forwards it verbatim, returning the upstream JSON-RPC response. Because the payload goes straight to a private builder/relay forwarder, it is never gossiped to the public mempool — which protects it from front-running and sandwich attacks.

The target forwarder is selected by the {forwarder_id} path segment. Each configured forwarder is a distinct privacy destination; the set of available IDs is deployment-specific. The path must contain exactly one segment after /rpc/eth-private/ — there are no sub-paths, because a write request is the entire forwarder endpoint.

Only write methods are accepted. The request body is parsed and every JSON-RPC method in it must be on the allow-list:

  • eth_sendRawTransaction
  • eth_sendBundle
  • mev_sendBundle

A batch (JSON array) is allowed, but every element must use an allowed method. Any read method (e.g. eth_getBalance) is rejected with 405 method_not_allowed_on_forwarder — deliberately a 405 (not 403) so a client SDK can transparently retry the read against a public RPC route.

The request body is capped at 2 MiB (large enough for a bundle), and the upstream forward has a configurable timeout (default 10 s). The Authorization header you send is consumed by Triport for tier resolution and is not forwarded upstream.

Parameters

Path parameters

forwarder_idstringrequired
Short identifier of the private-transaction forwarder to route through. Exactly one path segment; no sub-paths.
Request body (JSON-RPC)object
jsonrpcstringrequired
JSON-RPC version, "2.0".
idnumber | stringrequired
Client-chosen request id, echoed in the response.
methodstringrequired
One of eth_sendRawTransaction, eth_sendBundle, mev_sendBundle. Any other value → 405 method_not_allowed_on_forwarder.
paramsarrayrequired
Method params — e.g. the signed raw tx hex for eth_sendRawTransaction, or the bundle object for eth_sendBundle / mev_sendBundle.

Response

The upstream JSON-RPC response is returned as-is. For a successful eth_sendRawTransaction the result is the transaction hash:

jsonrpcstring
Always "2.0".
idnumber | string
Echoes the id from your request.
resultstring | object
Method result passed through from the forwarder — e.g. the transaction hash, or a bundle acknowledgement object.
errorobject
Present instead of result if the forwarder rejects the JSON-RPC call (standard JSON-RPC error object).

Errors

Transport-level failures use the shared error envelope {"error":"<code>","code":<http_status>}. See Errors for the full envelope.

CodeMeaningWhen it happens
400body_read_errorRequest body could not be read, or exceeds the 2 MiB cap.
401unauthorizedMissing or invalid Authorization bearer key.
403tier_lockedYour plan does not include the private RPC forwarder (Free and Starter are locked; Growth and Scale are permitted).
404invalid_pathPath is missing the {forwarder_id} segment or contains a sub-path.
404forwarder_not_foundThe {forwarder_id} is not a configured forwarder.
405method_not_allowedHTTP method other than POST.
405method_not_allowed_on_forwarderA JSON-RPC method in the body is not a write method on the allow-list.
429rate_limitedPer-tier RPS limit exceeded. There is no daily quota.
502forwarder_unavailableThe upstream forwarder did not respond (e.g. timed out).

Examples

JavaScript (fetch)

const res = await fetch("https://api.triport.io/rpc/eth-private/protect", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "eth_sendRawTransaction",
    params: [signedRawTx],
  }),
});


const { result, error } = await res.json();
if (error) throw new Error(error.message);
console.log("tx hash:", result);

TypeScript SDK (@triport/sdk)

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


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


const txHash = await triport.ethereum.privateRpc.send({
  forwarderId: "protect",
  method: "eth_sendRawTransaction",
  params: [signedRawTx],
});


console.log("tx hash:", txHash);

Python (triport-sdk)

import os
from triport import Triport


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


tx_hash = triport.ethereum.private_rpc.send(
    forwarder_id="protect",
    method="eth_sendRawTransaction",
    params=[signed_raw_tx],
)


print("tx hash:", tx_hash)

Notes

  • Write-only. Reads are intentionally rejected with 405 method_not_allowed_on_forwarder so SDKs can fall back to a public RPC route.
  • Bundles. eth_sendBundle and mev_sendBundle accept a bundle object in params; batch arrays are supported as long as every method is on the allow-list.
  • No key leakage. Your Authorization header is used only for tier checks and is never forwarded to the upstream forwarder.
  • Choosing a forwarder. The {forwarder_id} must match a configured destination; an unknown id returns 404 forwarder_not_found.
  • Related: for direct-to-builder submission see the block-builder direct RPC (POST /rpc/eth-builder/), and for the standard public transport use the Ethereum JSON-RPC endpoint (POST /rpc/eth).