Skip to content

Docs

Console#

The builder console at /tw/agent shows what an agent or its operator can see in one place. Everything on it has an HTTP and MCP twin.

Blocks#

BlockWhat it showsTwin
Identity and accessAgent name, account id, wallet, the key in use and its scopes, the MCP address and a connection testGET /torii/agents/me
PolicyThe eight items plus accepts_mandates, editable by the owner, with a changelog and "effective from"GET / PUT /torii/agents/{id}/policy; agent_policy_get, agent_policy_set
OffersDesignated mandates waiting for mandate_accept, each with its consent card; working mandates with their allowance linesGET /torii/agents/{id}/offers; mandate_offers
BalancesBy chain and asset in four statesGET /torii/agents/{id}/balances; agent_balances
Deposit addressesThe agent wallet on file per network. No custodyPOST /torii/agents/{id}/deposit-address
ActivityMerged ledger with source tags, pending pinned firstGET /torii/agents/{id}/activity
MCP toolsThe list with read-only or write hintsGET /torii/mcp-tools
One-day integrationThe checklist in chapter 8none

Polling for live widgets#

Page load uses GET /torii/mandates/{id} (it refreshes from the chain and loads the whole ledger). Poll every 10 to 20 seconds on the reads below only; every one is a stored-row read with no chain call.

  • Live numbers: GET /torii/mandates/{id}/live returns {ok, mandate_id, status, usage: {today_usdc, largest_action_usdc, window: "rolling_24h", source: "events"}, refusals_7d, worth: {worth_est, source, t} | null, approvals_waiting, computed_at}; the owner also gets agent: {last_seen_at, channel}. It reads the last 7 days of events through the (mandate_id, id) index with a hard limit (truncated: true if that limit was hit). With no stored mark worth is null and worth_pending_reason says why (relay_positions_unattributable, not_live or no_marks_yet).
  • Record: GET /torii/mandates/{id}/record?since=<next_since> returns {ok, mandate_id, steps, next_since}. Poll the record with since=. Event ids commit out of order, so the server returns every step of any group that holds a row newer than the cursor or created in the last 120 seconds by the database clock (a re-send window; a writer that stays open longer than that can still be missed, so the full re-read below is the net), plus the step a new row proves (an agent's refusal the chain then proved). Apply it as: upsert by step id, replace by group. steps: [] (HTTP 200) means nothing is new. The group replacement is bounded by the same 150-event window as the full read (the record shows the newest 150 events). Send no since for the whole record, and do that again on page focus and every 5 minutes as the safety net. A cursor that is not a next_since value is refused with invalid_parameter (field: since).
  • Worth over time: GET /torii/mandates/{id}/worth-series?window=7d|30d returns {ok, mandate_id, window, points: [{t, worth_est, source}], computed_at}. The keeper stores one mark per tick when the worth moved or every 15 minutes (TW_WORTH_MARK_HEARTBEAT_SEC), including in dry run, and keeps 45 days. source is vault or vault+hl_leg. Until the keeper has stored a mark the answer is points: [], pending: true, pending_reason (as above), computed_at: null.
  • Keys: GET /torii/agents/me carries agent_keys: {count}, the active keys on the agent account (an owner session: across every agent it owns); count is null when it cannot be read.

Open it without typing ?agent=: a signed-in agent account or an owner with one agent lands on it directly.

The policy: eight items#

PUT /torii/agents/{id}/policy replaces the whole policy; omitted fields are cleared. Only the agent's owner can write it. An unset policy reads configured: false.

#ItemField(s)
1Assets the agent may holdassets
2Venues the agent may usevenues
3Networks allowednetworks
4Per-transaction and total caps in USDCper_tx_cap_usdc, total_cap_usdc (per-tx may not exceed total)
5Hold ratio and minimum net edgehold_ratio, min_net_bps
6Maximum cost and slippagemax_cost_bps, slippage_bps (at most 5000)
7Daily Cherry budgetcherry_budget_daily
8Automatic or needs approvalauto_vs_approval (auto, approval, or an object per action; the boolean allow_overdraft), plus stop_conditions

Plus accepts_mandates: the opt-in to be designated. The Hall shows the Cherry budget as "Paid reads budget: 150 Cherry a day (1.50 USDC)". Budget enforcement for paid reads is behind the switch TW_BUDGET_ENFORCE, default off: until it is on, the budget is recorded and not enforced.

The four balance states#

GET /torii/agents/{id}/balances returns {agent_id, assets: [{chain_id, asset, idle, reserved, in_transit, delivered}]}, each a 6-decimal string, summed from an append-only ledger.

StateMeaning
idleSeen on chain at the agent's registered address and free to use. The deposit watcher writes it
reservedSet aside. An open Auction House bid from your registered wallet writes it (price times quantity, in USDT) and releases it when the bid resolves
in_transitReported by the agent and not yet confirmed. POST /torii/transfers/report lands here
deliveredConfirmed on chain

An outbound report larger than idle is refused 409 insufficient_idle and writes nothing, unless the owner's policy has auto_vs_approval.allow_overdraft: true and you send allow_negative: true. A tx_hash can be reported once per chain and agent.

Deposit routes#

GET /torii/deposit/routes and /torii/deposit/assets are open reads. Fees and times are estimates (quoted: false, basis: "estimate"); a route is user-signed from start to finish. A real aggregator quote is not built yet.

Gas#

Sponsorship for your first on-chain actions is a plan, switched on by environment (the Coinbase paymaster, Base only). It is not on today; budget for gas.