Give Gemini the ability to run a pre-sign evidence check before it proposes
or executes an onchain swap. It calls POST /api/public/v1/check/swap and gets
back a modeled route-quality read, modeled MEV/execution exposure where
observable, a token registry recognition read, and a
clear | caution | unsupported verdict with caveats to relay verbatim.
Routescore is one composable element of an agentic stack — the evidence/attestation element alongside your planner, executor, and wallet. It is read-only: it never signs, executes, routes funds, custodies assets, or gives advice.
plan → preflight (Routescore) → execute (venue/agent) → record (Routescore)Everything returned is modeled, point-in-time decision support. Nothing holds a
key, moves funds, or promises an outcome. The pre-sign check_swap endpoint is
on the free agent tier — any signed-in tier can mint an rs_live_… key and
call it (free 100/day, Pro 1,000, Power 10,000, per account); the modeled-quote
and scenario endpoints require Power. Send the key as a bearer token —
generate one at Account → Developer → API & MCP access.
1. Declare the function
Gemini uses a FunctionDeclaration with an OpenAPI-subset schema. This is the
REST/JSON shape the Gemini API accepts directly (uppercase type values);
pass it in tools[].functionDeclarations. In the Google GenAI SDKs the same
type values are the Type enum members (Type.OBJECT, Type.STRING, …), not
these raw strings. Your code executes the HTTP call when Gemini returns a
functionCall.
{
"name": "check_swap",
"description": "Pre-sign evidence check to run BEFORE signing an onchain swap. Returns a read-only, modeled route-quality grade, modeled slippage estimate, modeled MEV/execution exposure where observable, a token registry recognition read (recognized vs unverified), and a clear | caution | unsupported verdict with reasons and caveats. Decision support only: it does not execute, route funds, sign, or promise an outcome.",
"parameters": {
"type": "OBJECT",
"properties": {
"notional_usd": { "type": "NUMBER", "description": "Trade size in USD (> 0, <= 1e12)." },
"chain_id": { "type": "INTEGER", "description": "Chain ID, positive integer. 1 = Ethereum (default), 4663 = Robinhood Chain." },
"route": { "type": "STRING", "description": "Route id to score, e.g. 'uniswap-v3-rho'. Omit to score the chain's default public route." },
"token_out": { "type": "STRING", "description": "Token being received (address or symbol), checked against the recognized-token registry. For tokenized stocks/ETFs pass the registry contract address; a bare symbol is downgraded to unverified." },
"token_in": { "type": "STRING", "description": "Token being sold (address or symbol)." },
"slippage_allowance_bps": { "type": "NUMBER", "description": "Slippage allowance in bps, 0–10000. Default 50." }
},
"required": ["notional_usd"]
}
}2. Execute the call
When Gemini returns a functionCall for check_swap, run the request with your
key and return the JSON as a functionResponse part in the next turn — echo the
same function name (and the id field from the functionCall if the model
provided one) so the model can match the response to its call:
curl -X POST https://www.routescore.io/api/public/v1/check/swap \
-H "Authorization: Bearer rs_live_your_key_here" \
-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
}'Abbreviated response (HTTP 200; timestamps illustrative):
{
"verdict": "caution",
"chain": { "chainId": 4663, "name": "Robinhood Chain", "supportLevel": "modeled" },
"route": { "grade": "A", "qualityScore": 97, "modeledSlippageBps": 25.5, "orderFlow": "sequencer_ordered" },
"token_safety": { "state": "recognized", "recognized": true, "flags": ["tokenized_asset_registry_only"] },
"reasons": ["sequencer_ordering_uncalibrated"],
"score_state": "partial",
"methodology_version": "routescore.public_api.v1",
"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."
]
}What the response means
verdict—clear | caution | unsupported. Advisory, never an instruction to execute.clearreports the absence of caution-level findings within the stated coverage andscore_state.token_safety.state—recognizedis a registry match only; it is not a safety, sellability, liquidity, rights, redemption, or investment-quality verification.unverifiedmeans Routescore has not confirmed the token and downgrades the verdict tocaution.unsupported— a valid-but-unsupported request returns an evaluatedunsupportedverdict as HTTP 422 with a full body, meaning not evaluated; Gemini must not guess or substitute another chain's model. Malformed input (non-positivenotional_usd, non-integerchain_id, out-of-range slippage) is rejected earlier with HTTP 400.- trust envelope —
score_state,source_freshness,methodology_version,caveats, andcommercial_disclosure(paid_placement: false) ride on every response. Pin themethodology_versionand relaycaveats[]verbatim.
Every keyed call also attempts to persist an owner-scoped, hash-verifiable
evidence record and returns its record_id —
re-verifiable offline. The full
machine-readable schema is at
/api/public/v1/openapi.json
(public, no auth) — point Gemini's OpenAPI tooling at it.
Where the proof lives
- /calibration — how modeled figures reconcile against realized outcomes, per source (honest-but-empty where a cohort is too small).
- /methodology — how the scores are computed.
- /limitations — what Routescore does not know or do.
Routescore returns modeled, point-in-time decision support with a
methodology_version — not investment, legal, or tax advice, and not an
execution service. Robinhood Chain figures are additionally uncalibrated
today. Gemini, its policy, and your user decide what to do with the evidence.