Skip to content
AGENTEX on XEnter App

Reports and receipts

Read a run's report JSON (findings, sections, evidence and sources), use evidenceFor in the SDK, download the JSON export and read the settlement receipt.

When a run ends, its report is in the run and its charge is in the receipt. This page explains the report JSON your code receives, how findings point to evidence, how the SDK normalises every report kind, the JSON export and the settlement receipt. It is for developers who process AGENTEX results in their own systems. For what the report means to a reader, see How reports work and Evidence.

Where the report is#

GET /v1/runs/{id} returns { run, events }. Once the run has a report, run.output holds it; before that it is null. A succeeded or partial run has a report. A failed run may have one that records its errors, or none, so check run.output before reading it.

In the SDK, getReport(runId) reads the run and returns the typed report; it throws conflict / report_unavailable if there is no report yet.

The report JSON#

Every report names its format in schemaVersion:

schemaVersionProduced by
agentex.workflow.v1Research workflows (most catalog agents)
agentex.token-research.v1Token Researcher
agentex.transaction-inspection.v1Transaction Inspector
agentex.solana-transaction-inspection.v1Solana Transaction Inspector
agentex.deployer-investigation.v1Deployer Investigator
agentex.wallet-analysis.v1Wallet Analyst
agentex.watchtower-window.v1Watchtower monitor windows

Fields common to every kind:

FieldMeaning
statuscomplete, partial or failed. This is the report's own status, separate from the run status.
generatedAt, agentVersion, manifestHashWhen the report was produced, and the exact agent version that produced it.
inputThe input the run was accepted with.
evidenceEvery recorded read, with its source and the block or slot it was read at.
limitationsWhat this agent does not cover, as plain sentences.
errorsWhat went wrong, if anything, each with a message.
usageReads used against the version's limit, elapsed time and model usage.

Research workflow reports put their findings in sections. Each section has id, title, status (complete, partial, skipped or failed), reason and findings. Each finding has a code, a label, a status and evidenceIds:

  • observed: a value read from the cited evidence;
  • from-input: a value taken from your input, with no evidence;
  • unknown or not-run: no value, with a reason.

Workflow reports also carry requiredSections, the executed steps, and a presentation with the report's archetype and headline, plus signals, datasets and coverage where the agent declares them.

Other report kinds have a top-level findings list, each with code, message and evidenceIds, alongside their own typed sections (for example Token Researcher's metadata, contract and controls observations). Agents with an AI-assisted summary add analysis: when its status is completed, analysis.findings holds claims with claim, evidenceIds and confidence (supported or uncertain).

This is part of a real research workflow report (Solana Token Safety Check, from its public saved example), abridged:

run.output (abridged)
{
  "schemaVersion": "agentex.workflow.v1",
  "status": "complete",
  "sections": [
    {
      "id": "authorities",
      "title": "Authorities and extensions",
      "status": "complete",
      "reason": null,
      "findings": [
        {
          "code": "mint-authority",
          "label": "Mint authority",
          "status": "observed",
          "value": "8Jornc27vtAYPkwDzsZVgLQchAYyC8nD7aCNPCDV8Qk2",
          "evidenceIds": ["ev-799328de2dbe4e9047e43171557b60fd", "ev-eedd7cd0fbcd7097e3c0079c6bbfd23b", "ev-eb5de04e0fa0b3c8ce12e3af5f901aaa"]
        }
      ]
    }
  ],
  "evidence": [
    {
      "id": "ev-eb5de04e0fa0b3c8ce12e3af5f901aaa",
      "tool": "solana.token-safety@0.1.0",
      "source": { "kind": "rpc", "provider": "solana-configured-rpc", "method": "getMultipleAccounts", "documentationUrl": "https://solana.com/docs/rpc" },
      "chain": "solana",
      "snapshot": { "kind": "solana-slot", "slot": "450789376", "commitment": "confirmed", "exactness": "lower-bound" },
      "finality": "confirmed-lower-bound",
      "completeness": "complete-for-request",
      "request": ["..."],
      "result": { "...": "..." },
      "contentHash": "..."
    }
  ]
}

Evidence items#

FieldMeaning
idev- followed by 32 hex characters, derived from the item's content. Findings cite these ids.
tool, capabilityThe tool and capability that made the read.
sourcekind (rpc, http or offline), provider, method and documentationUrl.
chain, scopeThe chain read and the subjects (addresses, mints) the read was about.
snapshotWhere the read is pinned: an EVM block (blockNumber, blockHash), a Solana slot (slot, commitment), a web retrieval time, or null for reads with no position, such as a genesis hash.
finality, canonicalityHow settled that position was, and whether it was rechecked at completion.
completenesscomplete-for-request, truncated, empty-result, unavailable or error.
request, resultThe raw request and response.
contentHashA hash of result, so you can check the stored response has not changed.
trust, privacyWhether the data is chain state, a provider's assertion or untrusted third-party web content.

Read reports with the SDK#

getReport returns a ResearchReport that has the same shape for every kind: all findings in one findings list (workflow section findings included, deterministic findings first, AI-assisted claims last with origin: 'model'), evidence with block and slot flattened from the snapshot, and sources grouping evidence by provider.

Findings with their evidence, then the sources
import { ASSETS, createBuyerClient, evidenceFor } from 'agentex-creator-sdk/buyer';

const agentex = createBuyerClient({ apiKey: process.env.AGENTEX_API_KEY!, assetId: ASSETS.SOL });
const report = await agentex.getReport('<runId>');

console.log(report.kind, report.status, report.headline);
for (const finding of report.findings) {
  const label = finding.origin === 'model' ? `${finding.text} [AI-assisted, ${finding.confidence}]` : finding.text;
  console.log(`${finding.section ?? '-'}: ${label}`);
  for (const item of evidenceFor(report, finding)) {
    console.log(`  ${item.id} ${item.source.provider} ${item.source.method} at ${item.slot ?? item.block ?? 'no pinned position'} (${item.completeness})`);
  }
}
for (const source of report.sources) console.log(`${source.provider}: ${source.methods.join(', ')}`);
for (const limitation of report.limitations) console.log(`Limitation: ${limitation}`);
  • evidenceFor(report, finding) returns the evidence items the finding cites, in citation order. It also accepts a plain list of evidence ids.
  • finding.status is observed, from-input, unknown or not-run for workflow findings, rule for deterministic findings of other kinds, and model for AI-assisted claims.
  • report.raw is the report exactly as stored, for kind-specific fields.
  • readReport(output) from agentex-creator-sdk/report does the same normalisation on any stored report, with no network access.

The JSON export#

GET /v1/runs/{id}/export (scope runs:read) returns the canonical export of a run that has a report:

Shell
curl -s -H "Authorization: Bearer $AGENTEX_API_KEY" https://agentex.sh/v1/runs/<runId>/export -o agentex-run.json
  • The body is { "run": { ... }, "version": { ... }, "events": [ ... ] }: the run with its report, the immutable agent version it ran (manifest and hash), and the run's events.
  • The X-Agentex-Artifact-Id header names the stored copy. AGENTEX keeps it privately for 30 days; after that a new request generates it again.
  • Before the run has a report the call returns 409 "This run does not have a report to export yet."
  • In the SDK: getResult(runId) returns { artifactId, run, version, events }. In the CLI: agentex-buyer result --run <runId> --out result.json.

CSV, Markdown and the readable HTML report, and public share links, are created from the run's page on the website while signed in. API keys cannot create them.

The settlement receipt#

GET /v1/runs/{id}/receipt (scope billing:read) returns the receipt of one of your paid runs, as a JSON download (agentex-receipt-<runId>.json).

FieldContents
schemaagentex.settlement-receipt.v1
runId, environment, issuedAtThe run, the environment and when this receipt was issued
quoteid, contractHash, expiresAt, resultPolicy, resultContract, priceRevision
listinglistingId, agentVersionId, agentVersionHash
inputThe accepted input
paymentassetId, currencyLabel, decimals, and chainId for ETH
feeSplitgrossCreatorFeeAtomic, feeBps, platformFeeAtomic, creatorCreditAtomic, maxExecutionChargeAtomic, maximumBuyerDebitAtomic
billingstatus, settlement (with outcome and chargedAtomic), read counts and pendingReason
modelCostThe AI analysis cost line, or null for agents without one
buyerYour account's wallet address

A run with no paid quote returns 404 "This run has no settlement receipt."

In the SDK, getReceipt(runId, { quote, waitForSettlement: true }) gives a smaller receipt built from billing, with the charge already formatted:

TypeScript
const receipt = await agentex.getReceipt(runId, { quote, waitForSettlement: { timeoutMs: 120_000 } });
console.log(receipt.status, receipt.outcome, receipt.charged, receipt.payment.label); // 'settled' 'succeeded' '0.0021 SOL' 'SOL on Solana'
console.log(receipt.fees);   // { creatorFeeAtomic, platformFeeAtomic, executionChargeAtomic }

Passing the quote lets the receipt name the payment asset without an extra request and report the quote maximum as maximumDebitAtomic.