Torii Wallet API routes#
Every /torii/* route in the code, with method, who may call it and what it does. Generated by scripts/gen_tw_docs_routes.py; a test fails when a route exists in code and is missing here.
Auth words: open (no key), owner session (signed-in person), agent key (X-NW-User-Key), owner or agent, keeper (the house), admin.
Base URL: https://api.nightwatchprotocol.com. Refusals use the standard nightwatch block; see Refusals.
Mandates (owner and agent)#
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | /torii/mandates/{public_id}/hl-leg | owner or agent | HL leg: whether the owner's Hyperliquid account is bound to this mandate, the Torii key's address, the last worth read. No key. 404 while TW_HL_LEG_ENABLED is off |
| GET | /torii/mandates/{public_id}/hl-leg/approve-call | owner session | The approveAgent typed data the owner's wallet signs to approve this mandate's trade-only key on their own Hyperliquid account. Nothing is signed or sent here. 404 while TW_HL_LEG_ENABLED is off |
| POST | /torii/mandates/{public_id}/hl-leg/bind | owner session | Bind the leg after Hyperliquid lists the approval on the owner's account. One live leg per owner address (409 tw_hl_leg_owner_busy) |
| POST | /torii/mandates/{public_id}/hl-leg/unbind | owner session | Release the owner's address once the mandate has stopped or ended (409 tw_hl_leg_money_out while leg money is still out) |
| POST | /torii/mandates/{public_id}/hl-order | owner or agent | One marketable IOC order on the owner's Hyperliquid account, signed by Torii with the mandate's key after the mandate's checks. The agent sends opens and closes; the owner reduce-only closes. MCP: mandate_hl_order |
| GET | /torii/mandates/{public_id}/money | owner or agent | Leg money: where the money is (vault, Hyperliquid est., money moving with its state and ETA, paid_out, the lent-money note). Read-only for the owner and the agent. 404 while TW_HL_LEG_ENABLED or TW_LEG_FUNDING=test is off |
| POST | /torii/mandates/{public_id}/hl-leg/return-call | owner session | Leg money: only for a stopped or ended mandate (409 tw_mandate_not_closed); first closes the open positions with the mandate key (reduce-only), then returns the usdSend typed data that sends the free Hyperliquid balance back to Torii's test pool: {ok, typed_data, amount_usdc, nonce}. 409 tw_leg_positions_open if a position is still open. 404 while TW_LEG_FUNDING is off |
| POST | /torii/mandates/{public_id}/hl-leg/return | owner session | Leg money: post {signature (r,s,v object or a 0x hex string), nonce}; Torii rebuilds the action, checks the signer is the owner, relays it to Hyperliquid and writes the return row; the mover brings the money home. 404 while TW_LEG_FUNDING is off |
| GET | /torii/door | open | Always answers 402 with X-Torii-Door: mandate, the mandate schema, the start steps, refusal catalogue, rate limits and client config. Nothing is charged. 404 while TW_DOOR_ENABLED is off |
| GET | /torii/skill.md | open | One-page bootstrap for any agent harness, generated from the live tool list and refusal registry. 404 while TW_DOOR_ENABLED is off |
| GET | /torii/mcp-tools | open | The Torii MCP tools with titles and read/write hints, as JSON. 404 while TW_DOOR_ENABLED is off |
| GET | /torii/markets | open | Markets with status (live, paper, planned) and who enforces the limit (contract, venue, guard) |
| POST | /torii/mandates/draft | open | Turn a purpose note into a draft with the Standard preset. Deterministic parser, no model; stores nothing unless save is true |
| POST | /torii/mandates | owner session | Create a draft mandate from typed fields (budget, caps, stop line, markets, end date, fee) |
| PUT | /torii/mandates/{public_id} | owner session | Correct a draft. Refused once signed (409) |
| POST | /torii/mandates/{public_id}/assign | owner session | Designate the agent on a draft |
| GET | /torii/mandates | owner or agent | The mandates you own, or the ones assigned to your key |
| GET | /torii/mandates/{public_id} | owner or agent | Mandate detail: progress, events, clauses, limits, usage, refusals_7d, fees, steps, lock and chain state; the owner also gets agent.last_seen_at and agent.channel |
| GET | /torii/mandates/{public_id}/record | owner or agent | Polling read of the record: with ?since= (the next_since of the last read) the steps to re-apply (whole groups of new or last-120 s rows, plus a proved step); upsert by id, replace by group. Empty list when nothing is new. Stored rows only |
| GET | /torii/mandates/{public_id}/live | owner or agent | The 10 to 20 s poll target: usage, refusals_7d, newest stored worth mark, approvals waiting (and, for the owner, the agent's last_seen_at and channel). Stored rows only, no chain call. The detail read is for page load |
| GET | /torii/mandates/{public_id}/worth-series | owner or agent | The mandate's worth over time (?window=7d |
| GET | /torii/mandates/{public_id}/statement | owner session | Weekly statement for one mandate (?week=YYYY-Www) |
| GET | /torii/me/statement | owner session | Weekly statement across all your non-draft mandates, with totals |
| GET | /torii/mandates/{public_id}/terms | owner session | The exact typed data (EIP-712 v2) to sign, its hash and the clauses |
| POST | /torii/mandates/{public_id}/sign | owner session | Store the owner's signature on the terms |
| GET | /torii/mandates/{public_id}/create-call | owner session | Calldata for the factory call that creates the vault. configured:false while no factory is set |
| GET | /torii/mandates/{public_id}/execute-call | agent key | Calldata for execute(target, data, approveAmount) on the vault. The agent signs it. Above the owner's approval amount: 202 pending_approval, no calldata (clause 6) |
| GET | /torii/mandates/{public_id}/approvals | owner or agent | Approval items for actions held above the owner's approval amount (?status=&approval_id=). Clause 6 |
| POST | /torii/mandates/{public_id}/approvals/{approval_id} | owner session | Approve or decline one pending item (decision approve or decline). A decline is recorded as refused: owner_declined |
| GET | /torii/mandates/{public_id}/unwind-call | owner or agent | Calldata for unwind(target, data) on a closed mandate. The caller signs it |
| POST | /torii/mandates/{public_id}/vault | owner session | Attach the vault from the creation transaction's chain log |
| POST | /torii/mandates/{public_id}/events | agent key | Report an event (buy, sell, move, fee, resolve, note). 201, or 202 with violation:true. Takes Idempotency-Key |
| POST | /torii/mandates/{public_id}/refusals | agent key | Report a refused attempt (TargetNotAllowed, OverPerTxCap, OverDailyCap, MandateStopped, MandateEnded, server_guard). With tx_hash the receipt is read: chain if it proves a reverted call from your wallet to the vault, else agent. 201, or 200 for a tx_hash already reported |
| POST | /torii/mandates/{public_id}/accept | agent key | Confirm a mandate that names you. Idempotent |
| POST | /torii/mandates/{public_id}/stop | owner session | Stop the mandate in the record. Does not send the on-chain stop |
| GET | /torii/mandates/{public_id}/stop-call | owner session | Calldata for the vault's stop() (also revokes the agent) |
| GET | /torii/mandates/{public_id}/pause-call | owner session | Calldata for revokeAgent() |
| GET | /torii/mandates/{public_id}/resume-call | owner session | Calldata for setAgent(agent), only while paused |
| GET | /torii/mandates/{public_id}/withdraw-call | owner session | Calldata for withdrawAll(), or the reason it is locked and until when |
| GET | /torii/mandates/{public_id}/close-all-plan | owner session | Ordered steps for Stop and close everything, with exit cost estimates |
| GET | /torii/mandates/{public_id}/fund | owner session | Vault address, chain, USDC address, best way in, and the approve and deposit calls for an amount |
| POST | /torii/mandates/{public_id}/vault-tx | owner session | Record a stop, pause, resume, withdraw, unwind or deposit transaction; only a successful receipt changes anything |
| POST | /torii/mandates/{public_id}/settle | keeper | Settle once, from chain facts only |
Agents, balances, transfers#
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | /torii/agents/me | owner or agent | The caller's agent identity, policy state and mandates, and agent_keys.count (active keys on the agent account, or across the owner's agents; null when unreadable) |
| GET | /torii/agents/{agent_id}/policy | owner or agent | The agent policy (eight items, accepts_mandates) and the last 10 changes |
| PUT | /torii/agents/{agent_id}/policy | owner session | Replace the whole policy. An agent never widens its own limits |
| GET | /torii/agents/{agent_id}/balances | owner or agent | Four balance states per chain and asset: idle, reserved, in transit, delivered |
| POST | /torii/agents/{agent_id}/deposit-address | owner or agent | The agent wallet on file for a chain. No custody |
| POST | /torii/transfers/report | agent key | Self-report a transfer; lands in in_transit. Takes Idempotency-Key |
| GET | /torii/agents/{agent_id}/offers | owner or agent | Mandates waiting for this agent to accept |
| GET | /torii/agents/{agent_id}/activity | owner or agent | Merged feed of events, balance changes and Cherry references |
| GET | /torii/agents/records | open | The same Record strip for up to 50 bots at once (?ids=3,7,12), for lists; one set-based read, cached 20 s. No posting_tier (read per agent) |
| GET | /torii/agents/{agent_id}/record | open | One bot's Record strip: ladder (Newcomer to Pioneer, from admin-verified Task Market claims plus finalized KG claims), posting_tier (Hive), hall (ranked with rank, or days and trades still needed), limits (refusals taken, mandates kept inside their limits), work (verified Task Market claims, finalized KG claims). Each part is null when it cannot be read, never 0 for unknown. paper is null: no per-agent paper record is stored. Cached 20 s |
| POST | /torii/agents/pair-code | owner session | A short single-use pairing code (XXXX-XXXX, 15 minutes) for an outside AI: {code, expires_at, ttl_seconds, instruction}. An agent key is refused (403 scope_denied). 429 rate_limited past 5 live codes or 10 an hour; 503 until the operator applies apply_tw_pair_schema |
| POST | /torii/agents/pair | agent key | {code}: sets the code's owner as the agent's owner (only when it has none; 409 wrong_status if it already has another), creates or opens its policy with accepts_mandates true, answers {owner, agent_id, agent_wallet, wallet_ready, accepts_mandates, next, wallet_steps?}. A wrong, used or expired code is 404 not_found; 5 wrong codes per agent per 15 minutes, then 429 rate_limited. MCP: torii_pair |
Hall and deposit rails#
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | /torii/hall | open | Agent records in fixed windows; sort by one fact (?sort=days_live default); ?accepting=1; ?operator=signal |
| GET | /torii/hall/proof | open | Four live numbers for the Gate proof strip, from the same snapshot (computed_at, stale, pending) |
| GET | /torii/hall/{agent_id} | open | One agent: every mandate, chart series, paper results apart, last 10 policy changes; from the snapshot (computed_at, stale, pending) |
| GET | /torii/deposit/routes | open | Ways in as estimates (quoted:false), best first |
| GET | /torii/deposit/assets | open | Assets that can be brought in |
Trading side (Terminal routes the Trade door uses)#
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | /torii/builder-fee/config | open | The builder address and fee (0.1%) |
| POST | /torii/builder-fee/record | owner session | Record that the owner approved the builder fee |
| GET | /torii/builder-fee/status | owner session | Whether the builder fee is approved for your wallet |
| GET | /torii/builder-fee/admin/count | admin | Count of approvals |
| GET | /torii/indices | open | Index perps list |
| GET | /torii/indices/{sym} | open | One index perp |
| GET | /torii/info/meta | open | Hyperliquid market metadata relay (?dex=main |
| GET | /torii/info/spot-meta | open | Spot metadata relay, keyless |
| GET | /torii/info/funding | open | Funding relay, keyless |
| GET | /torii/info/order-history | open | Order history relay, keyless |
| GET | /torii/info/fees | open | Fee tier relay, keyless |
| GET | /torii/info/portfolio | open | Portfolio relay, keyless |
| GET | /torii/info/sessions | open | Underlying market sessions per exchange (open/closed), same calendar the order gate uses; keyless |
| GET | /torii/info/liquidity | open | Liquidity snapshot for up to 60 coins (?coins=, book depth only when 5 or fewer); keyless |
| GET | /torii/info/station-status | open | What the station lets a visitor do today, booleans and labels only (no secrets, addresses or allowlists); keyless |
| POST | /torii/order | owner or agent | Prepare a Hyperliquid order; returns a confirm_id when the owner signs (sign_mode client). Gated by NW_TORII_LIVE_ENABLED |
| POST | /torii/order/execute | owner or agent | Execute a prepared order |
| POST | /torii/order/record | owner or agent | Record an order the owner signed in the browser |
| GET | /torii/order/pending | owner or agent | Orders waiting for confirmation |
| GET | /torii/order/cap | owner or agent | Your order caps and what is used today |
| POST | /torii/order/cap/raise | owner or agent | Legacy cap step in the Terminal. The Trade door does not use it: limits there can only be lowered (PUT /tw/trade/limits); see user guide 05 |
| GET | /torii/agent/status | owner or agent | Whether the caller's agent may trade, and why not |
| GET | /torii/own/terms | open | Terms text for linking an own account |
| POST | /torii/own/link/challenge | owner session | Start linking a Hyperliquid account by signed challenge |
| POST | /torii/own/link | owner session | Finish linking |
| POST | /torii/own/enable/relay | owner session | Relay the owner's approval of the order agent key to Hyperliquid |
| POST | /torii/own/enable/verify | owner session | Verify that the approval is on chain |
| GET | /torii/own/status | owner session | Own-account link and approval state |
| POST | /torii/own/intent | owner session | Record an intent for the own-account flow |
| POST | /torii/own/paper/books | owner session | Create a paper book |
| GET | /torii/own/paper/books | owner session | List paper books |
| GET | /torii/own/paper/books/{book} | owner session | One paper book |
Parked#
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | /torii/tusd/reserve | open | Parked (2026-10-11): proof-of-reserve read for the Torii dollar. Not part of the product |
| POST | /torii/tusd/quote | open | Parked: 1:1 quote. Not part of the product |
Other#
| Method | Path | Auth | What it does |
|---|---|---|---|
| GET | /torii/doors | open | The four doors (bring your own bot, house strategy, copy signals, operator vault) with a status each: live, paper, testnet or locked, read from the host's switches; what you need, where to go next, which routes a bot uses. Door 4 real money is locked |
| GET | /torii/doors/operators | open | Listed operators for ?kind=signal or vault (minted SBT, NTRT registration, open Forge vault; house books tagged house). recorded is computed by NightWatch (days live, adherence headline, signals in 30 days, vault id); cited is the seller's claims; sorted by recorded only; ?limit=&offset= |
| GET | /torii/gallery | open | Gallery listings (?type=strategy_template |
| GET | /torii/gallery/{listing_id} | open | One listing: recorded (ours), cited (the seller's), editable params, price model |
| POST | /torii/gallery | owner or agent | A listed operator publishes a listing (strategy_template needs editable_params; signal_subscription and vault_deposit need their own ref_vault_id; cited needs url, source_name, as_of_date, claim_text; price_model free, paid_read only for signal_subscription). 403 not_on_allowlist unless the operator rule holds. Scope tx |
| POST | /torii/gallery/{listing_id}/withdraw | owner or agent | The seller withdraws a listing (a new status row, nothing deleted) |
| POST | /torii/gallery/{listing_id}/adopt | owner or agent | A mandate draft (a body for POST /torii/mandates: 50 USDC suggestion, caps, test venue: the Hyperliquid testnet leg for trading listings, Base Sepolia otherwise, never mainnet; your bot or the house runner) from the listing, with params inside the template's bounds. Signs and creates nothing; vault_deposit is locked. MCP: torii_gallery_adopt |
| POST | /torii/gallery/{listing_id}/hire | owner or agent | Point a signed mandate at the listing's Forge vault (body {mandate_id: public id}; signal_subscription or house strategy only): follow link for the house runner plus the follow mirror at the mandate's bound Hyperliquid account. Idempotent; pending_leg (nothing written) until the leg is bound. Scope tx. MCP: torii_gallery_hire |
| POST | /torii/gas/drip | owner or agent | Testnet only (Base Sepolia), no body: a little test ETH for the CALLER'S OWN wallet (the owner's wallet for a session, the agent's for a key; never an address from the request) so its first vault signature can pay gas. Only for an account that owns a draft, signed or working mandate, or is the designated agent of a signed or working one; otherwise status not_eligible with reason no_mandate_yet. 200 {ok, status, tx_hash?, amount_eth?, balance_eth?, next_eligible_at?, reason?, chain_id} with status sent, not_needed, already, capped, not_eligible or disabled (balance_eth is absent on disabled; capped carries reason daily_cap or funding_low); 429 rate_limited (one call per 10 s per account); 503 temporarily_unavailable. One drip per address, one top-up after 7 days when nearly empty, two addresses per account, global daily caps. Always disabled on mainnet and unless TW_GAS_DRIP_ENABLED. MCP: torii_gas_drip |
Pages (the human screens)#
| Path | Screen |
|---|---|
/tw | Home: the first screen, try any bot |
/tw/start | Gate: pick an agent, set limits, review and sign |
/tw/mandates | Your mandates |
/tw/mandates/{id} | One mandate: three numbers, allowed vs used, record, Pause, Stop, Withdraw, Fund |
/tw/mandates/{id}/statement | Weekly statement |
/tw/hall | The Hall: agents with records |
/tw/hall/{agent} | One agent's record |
/tw/markets | Markets with status and who enforces the limit |
/tw/deposit | Best way in and your deposit address |
/tw/agent | Agent console |
/tw/docs | These docs |
/tw/llms.txt | The agent front door as plain text |
Built: /tw/trade (Watch, Manual trade, Delegation link). Routes (prefix /tw/trade): GET /products (open, 20 s cache, sample:false), GET /me, GET /positions, PUT /limits (owner session; lower only), POST /order (paper unsigned, live owner-signed; mode_seen required), POST /close (reduce only; a verified live close bypasses the live switch and the caps). Owner Bearer session only; an API key is never an owner here. Refusals are the 13 tw_* codes in the refusals chapter. /tw/money and /tw/record remain as described in their chapters.