Decode a Base transaction by hash

Method
GET
Path
/api/v1/decode/{txHash}
Price
$0.005 USDC
Latency
Target p95 < 500 ms

Overview

GET /api/v1/decode/{txHash} turns a confirmed Base transaction into a human-readable action plus normalized asset movements — each with token, amount and USD value. Pass the transaction hash as a path parameter; the endpoint resolves the receipt, decodes the logs and returns structured JSON.

Add ?verbose=true for the full per-log breakdown. The price is the same with or without it: a flat $0.005 in USDC on Base via x402, with no account and no API key.

Request

One required path parameter and one optional query parameter. Unknown query parameters are ignored for forward-compatibility.

Parameter In Type Required Description
txHash path ^0x[0-9a-fA-F]{64}$ Yes Hash of the confirmed Base transaction to decode.
verbose query enum true | false No Include the full per-log decoding breakdown. Defaults to false; the price is unchanged.

Response

A successful call returns 200 with the decoded transaction as JSON. Example for transaction 0x7fa442ef…be90:

200 OK
{
  "decoder": {
    "version": "1.0.0",
    "schema": "v1",
    "decoded_at": "2026-06-13T09:12:04Z"
  },
  "tx": {
    "hash": "0x7fa442ef978286a2436b82a92dca545c3578c15cd5097aa31fa1831ee13ebe90",
    "chain_id": 8453,
    "network": "eip155:8453",
    "status": "success",
    "block_number": 47246941,
    "block_hash": "0x226592780c490ebfd3a72625a3fff67b0232a956eb24d4afaebf7b9c36cb183c",
    "block_timestamp": 1781283229,
    "block_timestamp_iso": "2026-06-12T16:53:49Z",
    "finality": "finalized",
    "from": "0x7bfd6606628a520888be12431d2d896e116f5c6d",
    "to": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "to_label": "USDC token contract",
    "value": {
      "raw": "0",
      "formatted": "0"
    },
    "nonce": 134,
    "transaction_index": 31,
    "gas": {
      "gas_used": 45047,
      "effective_gas_price_wei": "6000000",
      "l1_fee_wei": "3313208105",
      "total_fee_wei": "273595208105",
      "total_fee_eth": "0.000000273595208105",
      "fee_usd": 0.000457099,
      "fee_pricing": {
        "status": "ok",
        "source": "defillama",
        "price_usd": 1670.7138540734327,
        "priced_at": 1781283244,
        "confidence": 0.99
      }
    },
    "explorer_url": "https://basescan.org/tx/0x7fa442ef978286a2436b82a92dca545c3578c15cd5097aa31fa1831ee13ebe90"
  },
  "principal": {
    "address": "0x7bfd6606628a520888be12431d2d896e116f5c6d",
    "basis": "tx-sender"
  },
  "action": {
    "type": "token-transfer",
    "family": "transfer",
    "protocols": [
      "erc20"
    ],
    "executed": true,
    "description": "ERC-20 token transfer",
    "details": {
      "sender": "0x7bfd6606628a520888be12431d2d896e116f5c6d",
      "recipient": "0xe8ea93eb0947ec6bedb8fa6396cb3a168276ddb3",
      "amount": {
        "asset": {
          "type": "erc20",
          "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
          "symbol": "USDC",
          "name": "USD Coin",
          "decimals": 6,
          "token_id": null
        },
        "raw": "400",
        "formatted": "0.0004",
        "value_usd": 0.000399916,
        "pricing": {
          "status": "ok",
          "source": "defillama",
          "price_usd": 0.9997890644178156,
          "priced_at": 1781283244,
          "confidence": 0.99
        },
        "inferred": false
      }
    },
    "secondary": []
  },
  "summary": "Sent 0.0004 USDC ($0.0004) to 0xe8ea…ddb3",
  "movements": [
    {
      "index": 0,
      "kind": "transfer",
      "asset": {
        "type": "erc20",
        "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
        "symbol": "USDC",
        "name": "USD Coin",
        "decimals": 6,
        "token_id": null
      },
      "amount": {
        "raw": "400",
        "formatted": "0.0004"
      },
      "from": "0x7bfd6606628a520888be12431d2d896e116f5c6d",
      "from_label": null,
      "to": "0xe8ea93eb0947ec6bedb8fa6396cb3a168276ddb3",
      "to_label": null,
      "direction": "out",
      "value_usd": 0.000399916,
      "pricing": {
        "status": "ok",
        "source": "defillama",
        "price_usd": 0.9997890644178156,
        "priced_at": 1781283244,
        "confidence": 0.99
      },
      "log_index": 368,
      "inferred": false,
      "inferred_from": null
    }
  ],
  "approvals": [],
  "net_flows": [
    {
      "address": "0x7bfd6606628a520888be12431d2d896e116f5c6d",
      "address_label": null,
      "is_principal": true,
      "deltas": [
        {
          "asset": {
            "type": "erc20",
            "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
            "symbol": "USDC",
            "name": "USD Coin",
            "decimals": 6,
            "token_id": null
          },
          "amount": {
            "raw": "-400",
            "formatted": "-0.0004"
          },
          "value_usd": -0.000399916,
          "price_status": "ok"
        }
      ]
    },
    {
      "address": "0xe8ea93eb0947ec6bedb8fa6396cb3a168276ddb3",
      "address_label": null,
      "is_principal": false,
      "deltas": [
        {
          "asset": {
            "type": "erc20",
            "address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
            "symbol": "USDC",
            "name": "USD Coin",
            "decimals": 6,
            "token_id": null
          },
          "amount": {
            "raw": "400",
            "formatted": "0.0004"
          },
          "value_usd": 0.000399916,
          "price_status": "ok"
        }
      ]
    }
  ],
  "usd": {
    "total_value_usd": 0.000399916,
    "basis": "transfer-amount",
    "total_price_status": "ok",
    "priced_movements": 1,
    "unpriced_movements": 0
  },
  "completeness": {
    "engine": "logs-only",
    "native_eth_visibility": "tx-value-and-weth-events-only",
    "decoded_logs": 1,
    "interpreted_logs": 1,
    "uninterpreted_logs": 0,
    "level": "full",
    "flags": []
  }
}

Top-level fields

These ten fields are present on every 200 response:

Field Description
decoder Decoder metadata: version, schema version and the decoded_at timestamp.
tx On-chain transaction facts: hash, chain_id, status, block, from/to, value and gas (with USD-priced fee).
principal The address the decode is framed around, plus the basis used to pick it (e.g. tx-sender).
action The primary interpreted action: type, family, protocols, a human description and structured details.
summary One-line natural-language sentence describing what the transaction did.
movements Normalized asset movements, one per relevant log: asset, amount, from/to, direction and USD value.
approvals ERC-20/ERC-721 approvals granted in the transaction (empty array when none).
net_flows Per-address net deltas after netting all movements, with USD value and price status per asset.
usd Aggregate USD accounting: total value, basis, price status and the priced/unpriced movement counts.
completeness Decode coverage signal: engine mode, native-ETH visibility, log counts, a level and any limitation flags.

With ?verbose=true the body is a superset: the same ten fields plus a per-log decoding breakdown. No field is removed, so a verbose response is safe to parse with the default schema.

Response headers

Header Meaning
ETag Content hash of the decoded response. A confirmed transaction is immutable, so the ETag is stable for conditional requests.
Cache-Control: private The response is bound to your paid request and must not be stored by shared caches.
X-Decoder-Version The decoder version that produced the response; mirrors decoder.version in the body.

Examples

The endpoint is pay-per-call: a plain request returns 402 with the payment requirements. The curl tab surfaces that 402; the JavaScript and Python tabs pay and retry through an x402 client.

bash
# The endpoint is pay-per-call: a plain request returns HTTP 402 with the
# payment requirements (price, network, asset). Paying requires an x402 client
# (see the JS/Python tabs); curl alone surfaces the 402, it does not pay.
curl -i https://txdecode.com/api/v1/decode/0x7fa442ef978286a2436b82a92dca545c3578c15cd5097aa31fa1831ee13ebe90
javascript
import { wrapFetchWithPayment, x402Client, decodePaymentResponseHeader } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

// EVM account that funds the call (USDC on Base). Keep the key server-side.
const account = privateKeyToAccount(process.env.PRIVATE_KEY);

// Register the exact-EVM client scheme for Base mainnet.
const client = new x402Client();
client.register("eip155:8453", new ExactEvmScheme(account));

// wrapFetchWithPayment handles the full flow: 402 -> sign EIP-3009 -> retry -> 200.
const fetchWithPay = wrapFetchWithPayment(fetch, client);
const res = await fetchWithPay("https://txdecode.com/api/v1/decode/0x7fa442ef978286a2436b82a92dca545c3578c15cd5097aa31fa1831ee13ebe90");

const decoded = await res.json();
console.log(decoded.summary);

// The settlement tx hash comes back in the PAYMENT-RESPONSE header.
const header = res.headers.get("PAYMENT-RESPONSE");
const settle = header ? decodePaymentResponseHeader(header) : null;
console.log("payment:", settle?.transaction);
python
# Python: use the official Coinbase x402 client (pip install x402).
# A plain request returns HTTP 402 with the payment requirements; the x402
# client signs the USDC payment on Base and retries automatically. The exact
# client API tracks the package version — see https://x402.org and
# https://github.com/coinbase/x402 (examples/python/clients/requests).
import requests

res = requests.get("https://txdecode.com/api/v1/decode/0x7fa442ef978286a2436b82a92dca545c3578c15cd5097aa31fa1831ee13ebe90")
print(res.status_code)            # 402 until paid
print(res.headers["PAYMENT-REQUIRED"])  # price, network, asset

Errors

Every error uses a JSON envelope with a stable code. The table below lists each code, its HTTP status, whether it is retryable and the suggested Retry-After.

HTTP Code Retryable Retry-After When
400 invalid-tx-hash no Path param does not match `^0x[0-9a-fA-F]{64}$`.
400 invalid-parameter no Invalid query param (e.g. `verbose` ≠ true/false). Unknown params are ignored (forward-compat).
404 tx-not-found no Well-formed hash unknown to the RPC fallback chain. May be another chain or a just-broadcast tx — see `details.note`.
422 tx-pending retryable 3 Transaction seen in mempool but no receipt yet: nothing to decode. Best-effort.
429 rate-limited retryable from header Pre-payment rate limit (30 requests per minute per IP per endpoint).
503 upstream-unavailable retryable 30 All RPCs in the fallback chain are down, or the circuit breaker is open.
500 internal-error retryable A bug on our side; `details.request_id` helps support.

No-settle guarantee. Non-200 responses are never settled — errors never cost $0.005.

See the full error reference for example bodies and per-code detail.

Rate limits

Before payment, requests are rate-limited to 30 requests per minute per IP per endpoint. Exceeding it returns 429 rate-limited with a Retry-After header. Paid calls are not subject to this pre-payment limit.

  • Error reference — every code, status and meaning.
  • Pricing — the flat $0.005 per-call model in USDC on Base.
  • Playground — run the full pay-per-call flow live.