Skip to content

Docs

House strategy#

The house runner follows a house strategy's signals for your mandate, so you run no bot. Testnet only.

What the runner does#

A worker pass runs about every two minutes (a timer with up to 30 seconds of jitter). For each mandate that hired a house strategy, and each new signal of the followed vault:

  1. It picks signals newer than both the hire and the mandate's signing. History is never replayed. At most 20 signals per mandate per pass.
  2. It checks first, before it asks for a plan: the HL leg is on for the host, your mandate's Hyperliquid account is bound, and the runner has its key. If one fails, it records the reason and does nothing else.
  3. It asks for a plan inside your mandate, the same plan as POST /forge/signals/{id}/plan with your mandate_id (Follow a signal). The plan is sized to your mandate and checked against its caps.
  4. It acts on the verdict:
    • refused: records refused:<rule> (for example refused:over_per_tx_cap). No order.
    • needs_owner_approval: above your approval amount. The runner sends the order to Torii's order route, which holds it as one approval item in the owner's Approvals (see the next line); a dry run only records it and creates no item.
    • If Torii's order route answers that the order is waiting for the owner's approval (HTTP 202, 409 when one is already waiting, or the owner already has the maximum open approval items), the runner records awaiting_approval and keeps the row. A later pass asks again: once approved the order is placed (placed); if the owner declined it, approval_declined.
    • ok: places one marketable IOC order through your mandate's HL leg, then reports the fill.
  5. It never places the same signal twice for a mandate. A row is reserved before the order goes out, so a rerun or a crash never doubles an order.

It acts only inside your mandate: your caps, your pause, your stop. Pausing or stopping the mandate stops the runner for it. It uses your own Hyperliquid account through the mandate's trade-only key. It never uses the house's shared account and never falls back to the house relay, because that order could not be traced to your mandate.

Skipped reasons#

A skipped signal is recorded with one of these words, not silently dropped:

Recorded asWhy
skipped_flag_offThe HL leg is switched off on the host
skipped_leg_unboundYour Hyperliquid account is not bound to the mandate
skipped_no_runner_keyThe runner has no key configured
refused:<rule>The plan refused it; <rule> is the mandate rule
needs_owner_approvalAbove your approval amount; not placed
awaiting_approvalThe order route holds it for the owner's approval; checked again on the next pass
approval_declinedThe owner declined it; not placed
order_<status>Hyperliquid did not accept the order
errorA call failed; the error text is stored

A worker that is in dry-run records dry_ plus one of the words above and places nothing. A live pass takes a dry row over, so a dry run never uses up a signal. Check with the host operator whether the runner is live or dry on the deployment you use: the shipped unit is a dry run until an operator turns it live.

Hire it#

  1. Pick a house strategy: GET /torii/gallery?type=strategy_template or ?type=signal_subscription (MCP torii_gallery_list). House listings carry operator kind house.
  2. Adopt: POST /torii/gallery/{id}/adopt with no agent_id. When the host has a house runner configured, the draft names it as the mandate's agent ("agent": {"kind": "house_runner", "agent_id": "<runner id>"}). Without one, the answer says agent_id: null and a note, and you assign your own bot. Each listing says who runs it (runner_agent_id, set for house listings only; null means the agent you name runs it) and where (markets). The adopt answer carries strategy and its draft carries listing_id: send the draft as it is to POST /torii/mandates and the mandate keeps the strategy name as a description (not a signed field).
  3. The owner creates, signs and funds the mandate and binds the Hyperliquid account (Follow a signal).
  4. Hire: POST /torii/gallery/{id}/hire with {"mandate_id": "m_..."} (MCP torii_gallery_hire). Before the account is bound it answers pending_leg and writes nothing; bind, then call again. Hired answers executor.kind: house_runner and follow_link_created: true.

One vault per hired mandate. A second hire to a different vault is 409 wrong_status.

To stop: stop or pause the mandate, or DELETE /forge/vaults/{vault_id}/mirrors.

What is not available#

  • A house strategy trading real money.
  • A push or an approval link when a signal needs your approval (none is sent; the approval item waits in the owner's Approvals).
  • The vault funding the leg. Torii's money-path v2 (the vault funds the leg, with a Base-only experience) is being built and is not live yet; today the owner funds the Hyperliquid account.
  • Choosing the runner's size: sizes come from your mandate.
  • A runner you can run yourself. The runner is the house's, not an SDK.

Next#

Follow a signal, Refusals.