Skip to main content

Tx · broadcast (relay)

POST /v1/tx/broadcast is a convenience relay — it takes a raw signed transaction and forwards it to the chain's RPC.

The server never signs anything. You must sign locally; this endpoint just saves you from running an RPC connection of your own.

Request

{
"chainId": 8453,
"signedTx": "0x02f8b1820a4b..."
}

signedTx must be a 0x-prefixed hex string — the raw RLP/EIP-1559 encoded signed transaction.

Response (success)

{
"data": {
"chainId": 8453,
"txHash": "0xabc0...",
"from": "0xCAB3...",
"to": "0xbCC5...",
"nonce": 42,
"gasLimit": "250000"
}
}

Errors

StatuscodeWhen
400validation_errorMissing chainId / signedTx or signedTx isn't 0x-hex
502upstream_errorRPC rejected the tx (insufficient funds, nonce too low, replacement underpriced, execution would revert…)

The error message includes the RPC's shortMessage (or message) verbatim — "RPC rejected the transaction: nonce too low".

When to use it

  • Browser wallets that already have an RPC connection: don't use this. Send via window.ethereum / wagmi / viem directly.
  • Server-side bots with no RPC infra: useful as a quick path. For production traffic, run your own RPC to control mempool routing / private pools / MEV protection.
  • Mobile-first dapps with no native broadcast layer: handy.

Concrete example

import { ethers } from "ethers";

const wallet = new ethers.Wallet(privKey);

// 1. Build the calldata
const { data: tx } = await (
await fetch("https://api.blockfinax.com/v1/tx/hedge/buy-protection", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chainId: 8453, eventId: 12,
notional: "100000000", maxCost: "110000000",
deadline: String(Math.floor(Date.now() / 1000) + 300),
}),
})
).json();

// 2. Sign locally (you need a nonce + gas — read from anywhere you like;
// a public RPC works for this read-only call)
const provider = new ethers.JsonRpcProvider("https://mainnet.base.org");
const nonce = await provider.getTransactionCount(wallet.address);
const gasLimit = await provider.estimateGas({
from: wallet.address, to: tx.to, data: tx.data, value: BigInt(tx.value),
});
const feeData = await provider.getFeeData();

const signedTx = await wallet.signTransaction({
type: 2, chainId: tx.chainId, nonce,
to: tx.to, data: tx.data, value: BigInt(tx.value),
gasLimit,
maxFeePerGas: feeData.maxFeePerGas!,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas!,
});

// 3. Relay via the integrator API
const relay = await fetch("https://api.blockfinax.com/v1/tx/broadcast", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ chainId: tx.chainId, signedTx }),
}).then(r => r.json());

console.log("submitted:", relay.data.txHash);