TriportRPC

trace_transaction

POSThttps://api.triport.io/v1/polygon

Returns the Parity-style call tree for a single already-mined Polygon transaction, identified by its hash.

Polygonpolygon_tracePro and up — pro 3 rps · business 10 rps

trace_transaction replays one transaction that has already been included in a block and returns its execution as a flat list of Parity-style trace frames — one entry per internal call (call, create, suicide, reward), each tagged with its position in the call tree. It is the most convenient method for single-transaction forensic analysis: MEV path reconstruction, internal token-transfer tracing, and revert diagnosis without having to pull and walk a whole block.

Compared to its siblings, trace_transaction is the lightest of the block-scoped trace methods — it returns only the frames for one transaction, so it is far cheaper than trace_block (the full-block call tree) or trace_replayBlockTransactions (full block replay with state diffs), yet richer than eth_getTransactionReceipt, which gives you only the top-level result and logs.

This is a trace-namespace (Parity) method available on the Pro tier and above. It is rate limited per tier (3 RPS on Pro, 10 RPS on Business) with a short burst allowance; there is no daily quota. If the hash does not correspond to a mined transaction — unknown, or still pending in the mempool — the method returns null rather than an error.

Parameters

One positional parameter.

txHashstringrequired
The 0x-prefixed 32-byte hash of the transaction to trace. The transaction must already be mined into a block; pending or unknown hashes yield a null result.

Response

The result is an array of trace frames, ordered by traceAddress (execution order). A simple transfer plus one internal call looks like this:

For an unknown or pending transaction, the result is null:

{ "jsonrpc": "2.0", "id": 1, "result": null }
actionobject
What the frame did. For a call frame: callType (call, delegatecall, staticcall, callcode), from, to, gas, input, value. create frames carry init and creationMethod; suicide frames carry address, refundAddress, balance.
resultobject
Outcome of the frame: gasUsed, and output for calls or address/code for creates. Absent (replaced by error) when the frame failed.
errorstring
Present only on failure — the reason, e.g. Reverted, Out of gas.
subtracesinteger
Number of direct child frames spawned by this frame.
traceAddressarray
Path of this frame within the call tree (e.g. [0, 1]). Empty for the top-level call.
typestring
Frame type — call, create, suicide, or reward.
blockHashstring
Hash of the block containing the transaction.
blockNumberinteger
Number of the block containing the transaction.
transactionHashstring
Hash of the traced transaction (equals your txHash).
transactionPositioninteger
Index of the transaction within its block.

Errors

CodeMeaningWhen it happens
-32002tier_insufficientYour API key's tier is below Pro; this trace-namespace method is not enabled for it. The error.data carries current_tier, required_tier, method, category, and upgrade_url.
-32003rate_limitedYou exceeded your tier's request rate (3 RPS on Pro, 10 RPS on Business) including burst. Honor the Retry-After header / error.data.retry_after_sec and retry after a short back-off.

Note that an unknown or pending transaction is not an error — it returns a null result with HTTP 200. See the shared error envelope reference for the full error object shape and handling guidance.

Examples

JavaScript (fetch)

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


const { result } = await res.json();
if (result === null) {
  console.log("transaction not found (unknown or pending)");
} else {
  console.log(`${result.length} trace frames`);
}

TypeScript SDK (@triport/sdk)

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


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


const frames = await triport.polygon.request("trace_transaction", [
  "0x3a1f2b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a",
]);


for (const f of frames ?? []) {
  console.log(f.type, f.traceAddress.join("."), f.action.from, "→", f.action.to);
}

Python (triport-sdk)

import os
from triport import Triport


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


frames = triport.polygon.request(
    "trace_transaction",
    ["0x3a1f2b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a"],
)


if frames is None:
    print("transaction not found (unknown or pending)")
else:
    print(f"{len(frames)} trace frames")

Notes

  • Parity shape, not Geth. trace_transaction returns the flat Parity trace format (frames keyed by traceAddress), which differs from the nested callTracer tree returned by Geth-style debug methods. If your tooling expects the Geth shape, reach for the debug namespace instead; if you index both, normalise one format to the other.
  • Bor quirk. Polygon's Bor client can map a frame's callType slightly differently from a vanilla Geth/Parity node (for example call vs delegatecall for proxy dispatch). Handle both when reconstructing call trees.
  • null means not found. A null result is the expected answer for a hash that is unknown or still pending — poll again once the transaction is mined rather than treating it as a failure.
  • Related methods. For the full call tree of every transaction in a block, use trace_block; for a range query across many blocks, use trace_filter; to simulate a not-yet-sent transaction, use trace_call. See the Polygon RPC overview for the full trace namespace.