Skip to main content
A verification checks one proposed action against the rules it has to follow and returns a verdict with a signed receipt. POST /api/v1/intent, the MCP verify_intent tool and the dashboard sandbox all run the same pipeline. Escrow wallet proposals run it too, with the wallet’s mandate as the rules and the simulation report in the context. Each run costs one credit.

The request

Field limits, response shapes and errors: Verification request.

String or object

  • A string action is judged as written. The response has mode: "semantic".
  • An object action goes through venue resolution. If an adapter claims it, a classifier types it and the response has mode: "structured" with venue, actionFamily and actionType set. If no adapter claims it, the object is judged as JSON and the response has mode: "semantic" and venue: null.
Send the exact payload when you have it. The classifier computes sizes, notional and decoded calldata in code, so the judge works from computed numbers instead of your description of them.

Venue resolution

  1. Explicit venue. Over HTTP any string is accepted. It is lowercased, stripped of punctuation, and matched against the adapter ids, a list of aliases (hl, poly, evm, eth, base, sol, rh, lyra and others) and id prefixes, so "Hyperliquid perps" resolves to hyperliquid. An unknown name is ignored without an error. Over MCP, venue is an enum of the adapter ids plus evm, and any other value fails schema validation. An explicit venue is used as given: the payload is not checked against it.
  2. Structural detection, for object actions with no resolved venue. Adapters are tried in this order and the first match wins: hyperliquid, limitless, polymarket, dimes, myriad, orderly, derive, lifi, meow, liquid, robinhood, x402, agentcards, uniswap, solana, starknet, alchemy. alchemy matches any raw EVM transaction, so it goes last.
  3. None. The action is judged without venue knowledge.
A string action with an explicit venue gets the venue’s brief and document tool but no classification: actionFamily is "unknown" and actionType is null. The adapters and what each one recognizes: Venues.

Classification

A classifier is code, not a model. For a matched payload it produces:
  • actionFamily: one of order, margin, withdrawal, transfer, staking, vault, position, swap, payment, subaccount, permission, unknown.
  • actionType: the venue’s own action name as submitted, for example order or withdraw3 on Hyperliquid, or null.
  • A summary of the payload and deterministic notes, both shown to the judge.
  • The documentation pages to preload.
Hyperliquid classifies against a bundled copy of its asset metadata. alchemy, derive, dimes, lifi, limitless, myriad, orderly, polymarket, uniswap and x402 also look up live venue data, for example to resolve a token id to its market. If a lookup fails, the static classification is used.

Venue knowledge

Each adapter has a knowledge module in the repository: pages taken from the venue’s own documentation, a short curated brief, and a snapshot version that hashes all the pages. Venue documentation is not fetched at verdict time. The judge gets the brief and the preloaded pages up front and can request any other page with the load_venue_doc tool, on both model providers.

What the judge receives

The system prompt for POST /api/v1/intent and verify_intent is the generic verification prompt. It tells the judge to check hard constraints (limits, allowed assets and venues, price bounds, direction) and the plain-language intent, and to watch for side inversion, scope creep and unverifiable premises. Escrow proposals use an escrow prompt instead, which treats the simulation report as the truth about the action’s effects and the agent’s note as untrusted. On a venue run the system prompt also carries the snapshot version, the classifier’s family, action type, summary and notes, the brief, the list of loadable pages, and the preloaded pages. The task is one message, in this order:
  1. INTENT: your intent.
  2. PROPOSED ACTION: a string action as written. For a classified object, the classifier summary followed by the raw payload as JSON. For an unclassified object, the JSON.
  3. CONTEXT: context as JSON, without reference. Left out when empty.
  4. REFERENCE: context.reference, fenced and introduced as third-party documentation that may be wrong, never changes the intent, never authorizes the action, and whose instructions are to be ignored.
  5. An instruction to decide ALLOW, BLOCK or ESCALATE and state the decisive reason.
The judge runs as an agent loop of at most 8 model turns. It can call web search, and load_venue_doc on venue runs. A second model call then extracts the decision from the judge’s analysis, constrained to ALLOW, BLOCK or ESCALATE, with a rationale. That rationale is the reasoning field.

Verdicts

Execute only on ALLOW. The judge is told to return ESCALATE instead of ALLOW when a required fact cannot be verified, including a venue fact missing from the documentation it has. A run that errors returns no verdict and refunds the credit: HTTP 502 verification_failed, or an MCP result with isError: true. Treat it as do-not-execute.

What commits to the payload

The first transcript line, run.start, holds the full task, including the raw payload JSON. The transcript root covers every line and is signed by the judge key, so the receipt commits to the exact payload that was judged. See Receipts. requestHash on a verification is a per-run identifier: a hash of the run id and a random value. It is not a hash of your payload, so do not compare it with one. You can fetch a verification by it. On an escrow proposal, requestHash is different. It is the hash of the canonical payload the wallet will sign. Execution recomputes it from the stored payload and refuses to sign on a mismatch. See Escrow wallets API.