Help center

Add a pre-sign evidence check to your agent

Wire the check_swap preflight into your agent — one REST or MCP call before signing returns an advisory verdict, machine-readable reason codes, registry recognition, and pre-written caveats to relay verbatim, with a methodology version on every response.

Your agent plans a swap. Before it signs, one API call returns an evidence object: an advisory verdict (clear | caution | unsupported), machine-readable reason codes, token registry recognition, a route quality state, and the caveats your user should read — with a methodology version on every response.

Routescore is one composable element of an agentic stack — the evidence / attestation element — alongside your planner, executor, and wallet. It never signs, executes, routes funds, or advises. The composition looks like this:

plan → preflight (Routescore) → execute (venue/agent) → record (Routescore)

Think of it like a home inspection report for an onchain action: it documents what was observed, what was modeled, what was not evaluated, and when — you (or your agent's policy) still decide.


1. What one check_swap call answers

POST /api/public/v1/check/swap composes, in a single round-trip:

FieldWhat it tells your agent
verdictclear | caution | unsupported — an advisory pre-sign verdict, never an instruction to execute
reasons[]Stable machine codes, e.g. token_unverified, sequencer_ordering_uncalibrated, route_chain_mismatch, slippage_exceeds_allowance
chain{ chainId, name, supportLevel }supportLevel is live | modeled | recognized
routeModeled route quality: grade (A–F), qualityScore (0–100), modeledRouteLeakBps, publicMempoolMevBps (null when not observable), modeledSlippageBps, orderFlow, confidenceLabel
token_safetyRegistry recognition read: state is recognized | unverified | not_evaluated, plus flags[] and caveats[]. Recognition is a registry match only — not a safety, sellability, liquidity, rights, redemption, or investment-quality verification
caveats[]Pre-written honest sentences meant to reach your end user
score_statevalid | partial | unsupported — whether anything modeled is incomplete
source_freshnessPer-source freshness states (fresh | partial | stale | unsupported | unavailable | unknown — the full published enum in the OpenAPI spec; check_swap today emits fresh | partial | unsupported), with checked_at
methodology_versionCurrently routescore.public_api.v1 — pin it, diff on change
commercial_disclosurepaid_placement: false, score_influenced_by_partner: false — no pay-to-rank, ever
record_id · evidence_bundle_id · record_output_hashAdditive evidence-record linkage: every keyed call persists a durable, hash-verifiable preflight record. Retrieval + offline re-verification: Verifiable pre-sign evidence records

Everything modeled is labeled modeled and point-in-time. Gaps are stated as unsupported or not_evaluated, never approximated away.


2. curl: a Robinhood Chain pre-sign check

Robinhood Chain is chain_id: 4663. This example checks a USDG → tokenized AAPL swap on the day-one Uniswap route, passing the Routescore registry contract address for the output token (for tokenized stock/ETF assets, symbol-only input is downgraded to unverified by design — a symbol match cannot rule out fake-contract impersonation):

curl -X POST https://www.routescore.io/api/public/v1/check/swap \
  -H "Authorization: Bearer rs_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "notional_usd": 10000,
    "chain_id": 4663,
    "route": "uniswap-v3-rho",
    "token_in": "USDG",
    "token_out": "0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9",
    "slippage_allowance_bps": 75
  }'

The honest answer today is caution, not clear — Robinhood Chain support is modeled and realized outcomes there are still uncalibrated. Response (HTTP 200; timestamps illustrative):

{
  "verdict": "caution",
  "chain": { "chainId": 4663, "name": "Robinhood Chain", "supportLevel": "modeled" },
  "route": {
    "id": "uniswap-v3-rho",
    "name": "Uniswap · Robinhood Chain",
    "protocol": "uniswap",
    "chainId": 4663,
    "grade": "A",
    "qualityScore": 97,
    "modeledRouteLeakBps": 0.8,
    "publicMempoolMevBps": null,
    "modeledSlippageBps": 25.5,
    "expectedTotalLossUsd": 26.26,
    "orderFlow": "sequencer_ordered",
    "confidenceLabel": "low"
  },
  "token_safety": {
    "state": "recognized",
    "recognized": true,
    "flags": ["tokenized_asset_registry_only"],
    "caveats": [
      "AAPL matches Routescore's recognized token registry address for this chain.",
      "Recognition is not a safety, liquidity, sellability, transferability, routing, redemption, custody, or investment-quality verification.",
      "Tokenized-stock/ETF recognition is based on the Routescore registry entry; it does not verify issuer attestation, shareholder rights, beneficial ownership, dividends, corporate actions, jurisdiction eligibility, insolvency treatment, redemption, or can-sell status."
    ]
  },
  "reasons": ["sequencer_ordering_uncalibrated"],
  "score_state": "partial",
  "source_freshness": {
    "state": "partial",
    "checked_at": "2026-07-09T00:00:00.000Z",
    "max_age_seconds": null,
    "sources": [
      { "name": "routescore_route_model", "freshness_state": "partial", "as_of": "2026-07-09T00:00:00.000Z", "age_seconds": 0 },
      { "name": "token_registry_recognition_only", "freshness_state": "partial", "as_of": "2026-07-09T00:00:00.000Z", "age_seconds": null }
    ]
  },
  "methodology_version": "routescore.public_api.v1",
  "confidence_band": { "low": null, "high": null, "unit": "bps", "label": "modeled_preflight" },
  "caveats": [
    "Pre-trade decision support only. Routescore does not execute trades, route funds, or promise an outcome.",
    "Route and execution-risk values are modeled, point-in-time. Token-safety is registry recognition vs unverified status, not a live honeypot, can-sell, rights, redemption, or liquidity audit.",
    "Route uses sequencer-ordered L2 settlement; Ethereum public-mempool sandwich assumptions are not applied, and realized RHC liquidity/slippage/oracle/finality outcomes remain uncalibrated.",
    "AAPL matches Routescore's recognized token registry address for this chain.",
    "Recognition is not a safety, liquidity, sellability, transferability, routing, redemption, custody, or investment-quality verification.",
    "Tokenized-stock/ETF recognition is based on the Routescore registry entry; it does not verify issuer attestation, shareholder rights, beneficial ownership, dividends, corporate actions, jurisdiction eligibility, insolvency treatment, redemption, or can-sell status."
  ],
  "commercial_disclosure": {
    "paid_placement": false,
    "score_influenced_by_partner": false,
    "message": "Routescore does not sell paid placement or pay-to-rank treatment in score methodology."
  },
  "trust": { "…": "the same envelope fields nested in full, plus generated_at and decision_support_only: true" }
}

Reading this response honestly:

  • publicMempoolMevBps is null because Robinhood Chain is a sequencer-ordered (FCFS) Arbitrum-stack L2 — there is no Ethereum public mempool there, so public-mempool sandwich framing is not applied and not claimed. What is observed instead is the caveat: ordering assumptions are different and realized outcomes are uncalibrated.
  • recognized means the address matched Routescore's registry entry for this chain — observed on-chain 2026-07-07 — and nothing more. The tokenized_asset_registry_only flag exists precisely so an agent cannot read a registry match as sellability or rights.
  • score_state: partial tells you something modeled is incomplete. A partial is information, not decoration — surface it.

Robinhood Chain context your user deserves relayed: per issuer disclosures, Robinhood's tokenized stock/ETF assets ("Stock Tokens") are debt securities issued by Robinhood Assets (Jersey) Ltd; they carry no shareholder rights, and are not offered in the US, CA, UK, CH, or UAE. Routescore reports this as registry and rights context — it does not evaluate eligibility for any specific user or jurisdiction. The full evidence checklist behind this call lives in the companion guide, What to check before an AI agent touches a tokenized asset.


3. MCP setup: give the same check to Claude Code or Cursor

The check_swap tool ships in @routescore/mcp (published version 0.2.1 at the time of writing), a thin stateless wrapper over the same keyed REST gateway.

Claude Code:

claude mcp add routescore --env ROUTESCORE_API_KEY=rs_live_... -- npx -y @routescore/mcp

Cursor (.cursor/mcp.json) / Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "routescore": {
      "command": "npx",
      "args": ["-y", "@routescore/mcp"],
      "env": { "ROUTESCORE_API_KEY": "rs_live_..." }
    }
  }
}

Run whoami first to confirm the key and its plan tier. Optional: ROUTESCORE_API_URL overrides the API base (default https://www.routescore.io).

How your agent should relay the result

The response is built for what Routescore's agent-first design rules call schema-enforced honesty — structured fields the model cannot paraphrase away: the verdict enum, caveats[], score_state, and methodology_version. (The full rule also specifies per-caveat severity and a relay_to_user field; those are roadmap, not shipped — see below.) The companion rule is safe defaults: "Unknown token → caution. Missing data → unsupported. Never a guess."

For agent builders that means one instruction:

Relay verdict, reasons[], and caveats[] to your user verbatim. Do not summarize a caveat into something softer, drop the partial score state, or convert "uncalibrated" into confidence. The caveat sentences are pre-written so they survive the trip from API to end user intact.

If your agent shows one line, show this shape:

Preflight (Routescore, modeled, routescore.public_api.v1): CAUTION —
sequencer ordering uncalibrated on Robinhood Chain; token recognized in
registry (registry match is not sellability or rights). Full caveats relayed
below.

4. Handling each verdict state

VerdictHTTPWhat it meansWhat your agent should do
clear200No modeled downgrade triggered on the surfaces that were evaluatedNot a recommendation and not an execution instruction. Proceed only per your own policy; still relay caveats[], and check score_state — anything not evaluated stays not evaluated
caution200At least one honest gap or modeled threshold downgraded the verdict (see reasons[])Relay reasons + caveats verbatim; let the user or a declared policy decide. Gate programmatically on stable codes (e.g. block on token_unverified, require confirmation on sequencer_ordering_uncalibrated)
unsupported422Routescore cannot model this input (e.g. unknown/unsupported chain)Do not guess. Do not substitute another chain's model, retry with fudged inputs, or infer a score. Tell the user: "not evaluated by Routescore" — and treat that as the answer

One more case your agent must handle separately: schema-invalid inputs never reach a verdict. A missing or invalid notional_usd, a chain_id that is not a positive integer, or an out-of-range slippage_allowance_bps returns HTTP 400 with an { "error": { "code": "invalid_input" } } envelope — no verdict, no reasons[], no trust envelope. Treat a 400 as a bug in the request your agent built, not as an unsupported evaluation.

Two invariants worth encoding in your agent policy:

  1. clear never upgrades an unknown. An unverified token or unknown order flow downgrades the verdict; nothing in the response marks anything "safe" — there is no such flag, by design.
  2. Absence of a warning is not evidence of absence of risk. Check source_freshness for stale/unknown sources and score_state for partial before weighing the verdict at all.

After execution, close the loop: record what was checked and what was decided. Every keyed check_swap call already persists a durable, hash-verifiable evidence record and returns its record_id, evidence_bundle_id, and record_output_hash — retrieval and offline re-verification are covered in Verifiable pre-sign evidence records. The app additionally provides a decision journal and exportable evidence bundles.


5. Access, tiers, and rate limits (the honest version)

  • The keyed REST API and @routescore/mcp are bundled with the Power tier. Generate a key at Account → Developer → API & MCP (/account); keys look like rs_live_… and are shown once. There is no free anonymous API tier today — if that changes it will be announced, not implied. Key setup is walked through step by step in API & MCP access.
  • Rate limits are per key. Read X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset on every response; a 429 carries Retry-After. Build backoff against the headers, not against an assumed number.
  • Tier is read live on each request — a downgraded or canceled plan returns 403 rather than silently degrading results.
  • No key needed for the browser and read-only surfaces: /route-check?chain=4663 (chain-aware route check), /swap-slippage-checker, /benchmark, /reports/robinhood-chain-risk-map, and the public snapshot endpoints listed at /developers.

Known limitations are published at /limitations; the scoring methodology at /methodology; calibration evidence publishes at /calibration as label cohorts clear the publication bar (Robinhood Chain realized outcomes are not yet calibrated — the response says so instead of hiding it).


Roadmap (clearly labeled: not available today)

These are in design/build and may change. Nothing below is callable now, and nothing above depends on it:

  • preflight_action — a generalized one-call preflight (beyond swaps) returning verdict + policy violations + caveats, including a relay_to_user field: a pre-written one-sentence caveat the agent quotes verbatim. (The evidence-record half already ships for check_swap — see Verifiable pre-sign evidence records.)
  • Tokenized asset passports — structured rights-granted / rights-not-granted fields per tokenized asset.
  • Basis monitor — observed token-vs-reference price basis with freshness states.
  • Can-sell probes — a live token-security source; until it lands, neither recognized nor unverified may be read as "can sell".
  • Agent-relay eval harness — automated tests that caveats and verdicts survive into real agents' final user-facing answers.

Routescore is read-only decision support: it never signs, executes, routes funds, custodies assets, or gives investment advice. All figures are modeled, point-in-time, and carry methodology_version routescore.public_api.v1. No paid placement; see /neutrality.