Skip to main content
HomeLanding pagesHow to track an AI agent's transactions
LANDING PAGE

How to track an AI agent's transactions

8 min read·Last updated June 2, 2026

Track an agent's transactions by capturing its payment.sent and payment.received webhook events into your own ledger, keyed by transaction id, and confirming any one with client.transactions.get(id). Each payment is also an on-chain transaction with a hash you can verify on a Base explorer. There is no list-all endpoint, so you build the ledger from the event stream and reconcile against the canonical records.

What you will track

A complete, trustworthy record of every payment an AI agent makes and receives, settled in USDC on Base. You will capture transactions as they happen, confirm any one of them on demand, and reconcile your record against both the API and the chain. By the end you have a ledger you can answer questions from: what did this agent spend, what did it earn, and did a specific payment really happen.

This is the tracking and reconciliation guide. The webhook plumbing it builds on is in how-to-add-webhook-to-ai-agent, and the receive flow in how-to-receive-payments-as-ai-agent. The payment API product page is the broader reference.

Two sources of truth

Tracking uses two complementary sources, and knowing which is which keeps your ledger honest.

The first is the webhook event stream. payment.sent and payment.received arrive the instant a payment settles, and they are your real-time feed. You do not poll for transactions; you record them as the events land. The second is client.transactions.get(id), the canonical record for a single transaction, which you call when you need to confirm status or amount rather than react. There is no list-all endpoint to page through, which is the part people expect and do not find: you build the running ledger yourself from the stream, and use the lookup to verify entries. Behind both sits a third, neutral source, the chain itself, which you reconcile against when it matters.

Prerequisites

Build a ledger from the event stream

Record each verified payment event into your own store, keyed by transaction id, separating outbound from inbound by event type.

TYPESCRIPT
import { webhooks } from "@blockchain0x/node";

// in a verified, raw-body webhook route:
const result = webhooks.verify({ headers: req.headers, rawBody: req.body, secret: process.env.B0X_WEBHOOK_SECRET! });
if (!result.ok) return res.status(400).json({ code: result.code });

if (result.eventType === "payment.sent" || result.eventType === "payment.received") {
  const payload = JSON.parse(req.body.toString("utf8"));
  await ledger.upsert({
    id: payload.transactionId,           // dedupe key
    direction: result.eventType === "payment.sent" ? "out" : "in",
    agentId: payload.agentId,
    deliveryId: result.deliveryId,
  });
}
return res.status(200).end();

upsert keyed on the transaction id is what makes this safe against the at-least-once delivery: a repeated event updates the same row instead of adding a second. That single discipline is the difference between a ledger you can trust and one that drifts.

Confirm a transaction by id

When you need the authoritative state of a transaction, for a support question, a refund decision, a nightly check, look it up:

TYPESCRIPT
import { createClient } from "@blockchain0x/node";

const client = createClient({ apiKey: process.env.B0X_API_KEY! });
const tx = await client.transactions.get("txn_...");
// the canonical record: status, amount, identifiers

Treat the webhook as the trigger and transactions.get as the source of truth. A sound tracker reacts to the event in real time and confirms against the record on a schedule, so a missed or delayed webhook never leaves your ledger silently wrong. Store the transaction id from every event so this lookup is a direct fetch rather than a search.

Reconcile against the chain

Because settlement is on chain, you have a neutral third source your own logs cannot fake: the Base block explorer. Every payment has a transaction hash, and pasting it into an explorer shows the transfer, amount, and addresses independently of any API.

Use this for the cases that matter. During development, the explorer confirms a test payment really moved the USDC you expected. In production, it settles a dispute: if your ledger, the API record, and the chain ever disagree, the chain is the arbiter. A sound reconciliation routine checks that all three agree for a sample of transactions periodically, and flags any mismatch, because a gap between them is exactly the kind of problem you want to find on your own schedule rather than during an incident.

What to record per transaction

A ledger is only as useful as the fields you keep, so record enough to answer questions later without going back to the source. At minimum, store the transaction id (your dedupe key), the direction (out or in), the agent id, the amount, the status, and a timestamp. Add the webhook delivery id so you can trace a row back to the exact event, and the on-chain transaction hash so reconciliation against the explorer is a direct lookup.

Resist storing only what you need today. The cheap insurance is recording the identifiers (transaction id, delivery id, chain hash) on every row, because those are what let you confirm, reconcile, and investigate any entry months later. A ledger that kept only amounts and dates can tell you what happened in aggregate but cannot prove any single payment, which is exactly what a dispute or an audit asks for. Keep the ids; they cost almost nothing and are the difference between a report and an evidence trail.

Attribute by agent

For a single agent this is trivial, but a fleet needs per-agent attribution, and the data supports it cleanly. Each agent's wallet has its own event stream, so record the agentId on every ledger entry and you can answer per-agent questions directly: which agent spent the most, which earned, which one's spend rate jumped.

That attribution is the payoff of one wallet per agent. Spend and revenue roll up per agent for cost accounting, and a per-agent view makes anomalies obvious, a researcher agent suddenly spending like a trading agent stands out immediately. Aggregate across agents for a workspace total, drill into one for detail, all from the same id-keyed ledger you built from the stream.

Turn the ledger into reports

Once the ledger is solid, the reports come almost for free, because you already have the fields. Group by agent and period for a spend-and-revenue breakdown; sum by direction for net flow; filter by status to find pending or failed payments that need attention. Because every entry carries a timestamp and an amount, time-series views (spend per day, revenue per week) are a query, not a new pipeline.

The same ledger feeds three audiences from one source. Finance wants totals per period for accounting. Engineering wants spend rate and failure counts to catch problems. A customer or counterparty asking "did my payment go through" wants a single transaction looked up by id and, if needed, the chain hash to prove it. Build the ledger once, with the identifiers intact, and you serve all three without standing up separate systems. Export it to your warehouse on a schedule if you want it alongside the rest of your business data, keyed by the same transaction ids so it joins cleanly.

Common pitfalls

Three traps tracking agent transactions.

Expecting a list endpoint. You build the ledger from the payment.sent/payment.received stream and confirm with transactions.get. Capture events as they arrive rather than waiting to page a list.

Double-counting redelivered events. Webhook delivery is at-least-once. Key the ledger on the transaction id and upsert, so a repeat updates rather than duplicates.

Trusting one source alone. Your logs, the API record, and the chain should agree. Reconcile periodically so a discrepancy surfaces early.

What to ship today

Capture payment.sent and payment.received into an id-keyed ledger from a verified webhook, confirm entries with transactions.get, and reconcile a sample against a Base explorer on a schedule. Record agentId on every entry so a fleet rolls up cleanly. For the webhook setup this builds on, see how-to-add-webhook-to-ai-agent. Pricing is on the pricing page.

FAQ

Frequently asked questions.

Is there an endpoint that lists all of an agent's transactions?

You track transactions by capturing the payment.sent and payment.received webhook events as they happen and recording them in your own store, then confirming a specific one with client.transactions.get(id). Build the running ledger from the event stream rather than expecting to page a list; the events are the feed and transactions.get is the lookup.

What is the difference between the webhook and transactions.get?

The webhook is the real-time trigger: it tells you a payment happened the moment it does. transactions.get(id) returns the canonical record for one transaction when you need to confirm status or amount after the fact. Use the webhook to react and the lookup to verify, and store the id from the event so the lookup is direct.

Can I verify a transaction without trusting Blockchain0x?

Yes. Every payment is an on-chain transaction on Base with a hash, so you can confirm the transfer, amount, and addresses on a public Base block explorer independently of any API. That is a stronger position than a closed system: your ledger, the API record, and the chain should all agree, and the chain is the neutral arbiter if they ever do not.

How do I tell payments the agent made from payments it received?

By event type: payment.sent is outbound (the agent paid) and payment.received is inbound (the agent was paid). Record the type with each ledger entry so spend and revenue are separable. For a fleet, also record which agent, since each agent's wallet has its own stream.

How do I avoid double-counting a transaction?

Key your ledger on the transaction id (or the webhook deliveryId) and make inserts idempotent, so a redelivered event updates rather than duplicates. Webhook delivery is at-least-once, so dedupe on the id is what keeps the ledger correct when an event arrives twice.

Create your free agent wallet in 5 minutes.

First payment confirmed in under ten minutes. Free to start.