Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

FAQ

The questions people actually ask about oculr - pricing, supported chains, confidence levels, async usage, and what to do when a request fails.

Pricing

How much does an analysis cost?

Pricing is metered - you pay for the actual cost of analysing your transaction. Costs fall into two bands on the default model (claude-opus-5): routine transactions run roughly $1 to $2, and incident or exploit investigations - the core use case - usually run around $3-4. There is little in between, so an average is misleading; budget against the top of the band you expect to sit in. Measured across 48 analyses of oculr's own benchmark corpus to 2026-07-29, at the contract price. You can pass a model field (claude-sonnet-4-6, claude-haiku-4-5-20251001) to cut the LLM component substantially. See Pricing for the full distribution.

The exact cost is dynamic - every response carries a costs object broken into category buckets (llms, dataCollection, codeExecution, other) plus a costs.totalUsd showing what that specific call actually cost.

Do I need an API key?

No. oculr uses MPP/x402 - you bring a wallet funded with USDC.e on Tempo, use an MPP client like mppx, and every request settles a payment automatically. No signup, no API key, no rate limit beyond what your wallet funds.

oculr uses MPP sessions (one of two MPP intents - the other is charge). The client opens a payment channel with a maxDeposit, signs cumulative vouchers per request, and the server redeems the highest voucher on-chain. Like a bar tab - many requests, one settlement.

Is there a rate limit?

No fixed rate limit. Per-request payment is the throttle. Your client's maxDeposit is your spend cap - a signing ceiling, not the amount escrowed up front. The channel opens at min(suggestedDeposit, maxDeposit), so the recommended cap of '32' still escrows only the suggested $16. Escrowed is not spent: you're billed only what your analyses cost, and the remainder is refunded when you close the channel. See The channel deposit.

Wallet and funding

How do I fund the wallet?

You need a USDC.e balance on Tempo. The Tempo USDC.e contract is:

0x20C000000000000000000000b9537d11c60E8b50

If you already hold USDC.e on Tempo, top up that wallet. If you don't, transfer USDC.e to it however you normally move tokens on Tempo. oculr never asks you to use a particular bridge - anything that gets USDC.e into the wallet works.

If you are an agent starting from zero, stop here and ask a human. There is no faucet and no testnet path to a paid call - every /explain* request spends real money. Fully-autonomous funding is not possible today: a human has to fund the wallet once, and oculr does not document an acquisition route because it has none it can verify for you. Minimum viable funding is $2 - the channel admission floor, below which the server answers 402 with {"code":"deposit_below_minimum"}. $2 is not the default, though: the server advertises a $16 suggested deposit and an MPP client opens at min(suggestedDeposit, maxDeposit), so a wallet holding exactly $2 fails with InsufficientBalance unless you cap it yourself. With the CLI that is -M deposit=2:

mppx https://mpp.oculr.xyz/explain/async -M deposit=2 -J '{"txHash":"0x…"}'

and from the SDK you pass the same figure as the maxDeposit option. Know what you are buying: deposit is the client-side ceiling, not a separate opening size, so a channel opened at $2 is welded at $2 and can never be topped up - a run that crosses it dies mid-analysis after you have already paid for the work done. $2 buys one cheap analysis and no headroom; a single exploit investigation can consume several dollars, which is what the $16 suggestion is for.

Can I use a managed wallet instead of holding a private key?

Yes. Tempo Wallet is a managed MPP client with built-in spend controls and service discovery. The setup prompt fetches tempo.xyz/SKILL.md - a public markdown file you can inspect before running - and walks the agent through wallet creation:

Read https://tempo.xyz/SKILL.md and set up tempo

The agent configures Tempo Wallet end-to-end. After setup, every paid call against mpp.oculr.xyz settles through the managed wallet.

Fund it with USDC.e tokens, not MPP Credits. tempo wallet fund tops up the token balance - a one-time human step in the browser - and that is the balance oculr is paid from. tempo wallet fund --credits buys card-based MPP Credits, which are a different rail: tempo.xyz/SKILL.md states that "MPP Credits currently support one-time charges, not sessions" and directs session-based services to token funding. oculr is session-based (intent="session"), so a credits balance will not pay for a single analysis no matter how large it is.

Chains

oculr auto-detects the chain from the transaction hash - you don't pass a chain in the request. It covers 50+ EVM mainnets. Analysis is richest on the chains below, which have full enrichment: address labels, USD values, and risk flags.

SlugNetwork
ethereum-mainnetEthereum
base-mainnetBase
arbitrum-mainnetArbitrum
optimism-mainnetOptimism
matic-mainnetPolygon
bsc-mainnetBNB Chain
avalanche-mainnetAvalanche
linea-mainnetLinea
zksync-mainnetzkSync Era
scroll-mainnetScroll
blast-mainnetBlast
xdai-mainnetGnosis
abstract-mainnetAbstract
bera-mainnetBerachain
celo-mainnetCelo
fantom-mainnetFantom
fraxtal-mainnetFraxtal
hype-mainnetHyperliquid EVM
kaia-mainnetKaia
mantle-mainnetMantle
mode-mainnetMode
nova-mainnetArbitrum Nova
soneium-mainnetSoneium
sonic-mainnetSonic
story-mainnetStory
unichain-mainnetUnichain
worldchain-mainnetWorld Chain
zkevm-mainnetPolygon zkEVM
sei-pacificSei

The remaining mainnets are auto-detected with trace decoding - and USD values where price data exists - including Monad, Flare, Ink, Lisk, Morph, X Layer, Sophon, Plasma, Vana, and others.

The response includes chain (slug) and chainName (display name) so you know which one matched. If the transaction hash isn't found on any supported chain, you'll get an error - see troubleshooting.

Transactions

What about reverted transactions?

oculr analyses reverted transactions just like successful ones. The status field comes back as "reverted" and the summary explains why - slippage exceeded, out of gas, custom revert, etc.

The analysis came back with confidence: 'low' - what does that mean?

The agent couldn't fully identify the protocol or all the major actors. Common causes: unverified contracts, a brand-new protocol no labeller has tagged yet, or a sparse trace. Treat the summary as a hint and cross-check the risks array.

When should I use POST /explain/async?

Three cases:

  • Your HTTP client has a short timeout.
  • You're calling from inside a parent agent's tool-use loop and don't want each turn to block.
  • You're processing many transactions concurrently.

The async endpoint returns a jobId immediately - poll GET /result/:jobId every 5-15 seconds with an mppx client. Each poll collects what the analysis has accrued since your previous one and the first poll after it finishes charges the true-up, so the total price matches the sync stream exactly. Keep polling until the job is finished: 90 seconds with nothing collected aborts the run and leaves a partial result.

Can I stream progress to a UI?

Yes - SSE is how sync POST /explain works. Set Accept: text/event-stream (via tempo.session.manager().sse(), which carries the metered payment) and you'll get incremental events (preflight_status, iteration, agent_text, tool_call, tool_result, tokens, then result). Prefer plain fetch without a stream? Use POST /explain/async + polling.

Agents

Should my agent fetch SKILL.md or tool-spec.json?

Both work for different shapes of agent.

  • /SKILL.md is prose - best for interactive CLIs (Claude Code, Amp, Codex CLI) where a human asks an agent to look at a transaction. The agent reads the file once, learns the call shape, and dispatches with an MPP client.
  • /tool-spec.json is typed Anthropic + OpenAI tool-use schemas - best for sub-agents inside a parent agent's tool-use loop. Drop the array straight into client.messages.create({ tools: ... }) and you're done. Eliminates the "model parses markdown" class of integration bugs.

See Use as an agent for both setups end-to-end.

Does oculr produce a Mermaid diagram?

Yes, when the transaction has a clear call flow. The result includes a mermaidDiagram field. The hosted web app renders it under the Flow tab.

Troubleshooting

I'm seeing HTTP 402 - what do I do?

Check the body first. If it carries code: 'use_metered_sse', you sent a plain JSON POST /explain - sync analysis is a metered SSE stream, so switch to tempo.session.manager().sse(), or use POST /explain/async for plain fetch. A 402 from GET /result/:jobId is accrued metered cost coming due - every poll collects what the analysis has spent since your last one, and an MPP client pays it automatically; bare curl cannot. Otherwise it's the standard MPP payment challenge: your fetch() wasn't intercepted by an MPP client. Install mppx and call Mppx.create({ methods: [tempo({ account, maxDeposit: '32' })] }) once at startup. See Call the oculr MPP for both setups.

mppx is throwing InsufficientBalance.

Your wallet doesn't hold enough USDC.e on Tempo to open a payment channel. Top up the wallet at the USDC.e address listed in Wallet and funding. What the balance has to cover is the opening deposit, not the cap: the channel opens at min(suggestedDeposit, maxDeposit), so at the recommended '32' you need $16 to open. You only need the rest of the cap in the wallet if you later top the channel up.

The summary starts with "Partial result".

The upstream stack (RPC, the model provider, etc.) had a transient issue mid-analysis, and oculr returned a partial result (confidence: 'low') rather than failing the request. The summary tells you which phase struggled. A failed trace fetch is usually safe to retry after 30 seconds; a failed agent loop is safe to retry once.

My transaction hash returns "not found on any supported chain".

The chain probably isn't one oculr supports yet. oculr checks every supported mainnet (50+) in parallel, so if none of them returned a hit, the chain you're on isn't covered. Verify the hash on the source chain's block explorer.

Related