Skip to content

Developer docs / API v1

Keep the request.
Gain the proof.

Call hundreds of models with one key and one USDG balance, choose how strictly each provider must be verified, and check every receipt yourself.
API design · previewThis page documents the Verify Route API as designed. The live model catalog, wallet sign-in and USDG balance reads work on this site today; keys, billing, bonds, canaries and receipts go live in stages (see the roadmap). The base URL will be https://verifyroute.tech/api/v1.

Two lines to switch.

Verify Route speaks the chat-completions request shape that most AI SDKs already send. Point the client at the Verify Route base URL, use a vr-live-… key, and the rest of your code keeps working: messages, streaming, tools, JSON output and usage fields.

Your wallet is your account. Connect it on the dashboard, fund one USDG balance on Robinhood Chain, and create as many keys as you need. No email and no password.

Example request · curl
curl https://verifyroute.tech/api/v1/chat/completions \
  -H "Authorization: Bearer $VERIFYROUTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/llama-3.3-70b-instruct",
    "messages": [{ "role": "user", "content": "Name three prime numbers." }]
  }'
Node · OpenAI SDK
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://verifyroute.tech/api/v1",
  apiKey: process.env.VERIFYROUTE_API_KEY, // "vr-live-…"
});

const res = await client.chat.completions.create({
  model: "qwen/qwen3-32b",
  messages: [{ role: "user", content: "Summarize this in one line." }],
});

console.log(res.choices[0].message.content);
console.log(res.usage);   // tokens and cost in USDG
console.log(res.receipt); // signed record of the call

Tell the router what matters.

Without preferences, the router sends a call to the healthiest verified provider for that model at the best price. The provider object lets you narrow or reorder that choice:

  • order tries named providers first, in your order.
  • sort ranks the pool by price, latency or throughput.
  • allow_fallbacks lets the next qualifying provider answer if the first one fails.
  • data_collection: "deny" removes providers that declare they keep or train on prompts.
  • max_price caps the USD per million tokens you accept, per direction.
Routing preferences
{
  "model": "deepseek/deepseek-r1",
  "messages": [{ "role": "user", "content": "…" }],
  "provider": {
    "order": ["quarry-compute", "tidewater-labs"],
    "sort": "price",
    "allow_fallbacks": true,
    "data_collection": "deny",
    "max_price": { "prompt": 1.0, "completion": 2.0 }
  }
}

Decide how much proof a call needs.

Verification is the part of routing that most gateways leave out. Every provider on Verify Route is measured on three things, and a request can demand a minimum for each:

  • Bond. A provider locks 10,000 USDG on Robinhood Chain before it serves live traffic. A proven failure can be slashed after a 72-hour dispute window.
  • Canaries. Automated test prompts run against every served model around the clock. They check the answers, the weights fingerprint, the quantization and the empty-reply rate.
  • Receipts. The provider's answer is only accepted if the router can sign a receipt for it.

Set a floor with verify in the body or the X-VR-Verify header. If no provider meets it, the request is refused with a clear error instead of being served by a weaker one, and nothing is charged.

Verified-only request
{
  "model": "meta-llama/llama-3.3-70b-instruct",
  "messages": [{ "role": "user", "content": "…" }],
  "verify": {
    "bond_min": 10000,
    "canary_min": 0.99,
    "require_receipt": true
  }
}

Three lanes, one floor each.

A lane sets the minimum privacy a request accepts. The router never serves a request below the lane it asked for.

LaneWho can serve itWhat you get
standardAny bonded providerTLS to the router and on to the provider, under the provider's declared data policy.
attestedHosts with a fresh TEE quoteThe prompt is only processed inside an enclave whose quote the router verified minutes ago. Quote hash in the receipt.
blindAttested hosts, paid with blind creditsPayment cannot be tied back to a wallet. Designed in VEIL; not served yet.

Pick a lane with a model suffix (qwen/qwen3-32b:attested), the X-VR-Lane header, or as a default on the key. The full privacy design is in VEIL.

A receipt for every answer.

Each completed call returns a receipt: which model and provider answered, on which lane, the token counts, the cost in USDG, SHA-256 hashes of the request and the response, and the attestation hash when there is one. The router signs it with Ed25519, and every hour it anchors a Merkle root of the receipts it issued on Robinhood Chain.

A receipt holds hashes, never text. Anyone holding the original request can confirm it matches; anyone else learns nothing about its content. Fetch a receipt later with GET /api/v1/receipts/{id}, and check it in your browser on the verify page.

Receipt · example
{
  "id": "rcpt_01J9Q4X2M8",
  "version": 1,
  "generation": "gen-2027114",
  "model": "meta-llama/llama-3.3-70b-instruct",
  "provider": "quarry-compute",
  "lane": "attested",
  "usage": { "prompt_tokens": 142, "completion_tokens": 88 },
  "cost_usdg": "0.00004112",
  "request_sha256": "9f2c…41ab",
  "response_sha256": "0d7e…c3f9",
  "attestation_sha256": "4be0…9d7f",
  "bond": { "amount_usdg": 10000, "status": "active" },
  "canary": { "pass_rate_24h": 1.0 },
  "issued_at": "2026-09-30T09:00:31Z",
  "key_id": "7f21ac03",
  "sig": "ed25519:9Qx4b…Tz0="
}

One key per workload.

Keys are created by a connected wallet. Each carries its own policy: a spend limit and reset period, rate limits, an allowlist of models, a minimum verification level and a default lane. The key is shown once; the router only stores its hash.

Create a key
curl https://verifyroute.tech/api/v1/keys \
  -H "Authorization: Bearer $VERIFYROUTE_SESSION" \
  -d '{
    "name": "research-agent",
    "limit": 300,
    "limit_reset": "monthly",
    "allowed_models": ["qwen/qwen3-32b", "deepseek/deepseek-r1"],
    "verify": { "bond_min": 10000 },
    "lane": "standard"
  }'

One USDG balance.

Every key draws on the balance of the wallet that owns it. Deposits are USDG on Robinhood Chain (0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168, 6 decimals) and are credited once the transfer is final. Prices are quoted per million tokens and charged per call, with no subscription.

Unused balance can be withdrawn back to the same wallet. Your current on-chain USDG shows in the wallet menu as soon as you connect.

Pay per call, no account.

An agent does not need a key. A request without one receives 402 Payment Required with a price in USDG, a pay-to address and an expiry. The agent pays from its own wallet and retries with the proof. The receipt then names the payment transaction.

HTTP 402 flow
# 1. Call without a key: the router answers with a price.
POST /api/v1/chat/completions            -> 402 Payment Required
{ "amount_usdg": "0.00021", "pay_to": "0x…", "chain_id": 4663, "expires_in": 120 }

# 2. Pay that amount in USDG from any wallet on Robinhood Chain.

# 3. Retry the same request with the proof.
POST /api/v1/chat/completions
X-Payment: <tx hash or signed authorization>  -> 200 OK + receipt

What comes back.

HeaderMeaning
X-VR-Receipt-IdId of the signed receipt for this call.
X-VR-ProviderProvider that served the call.
X-VR-LaneLane the call was served on.
X-VR-VerifyChecks that passed: bond, canary, attestation.
X-VR-CostCost of the call in USDG.

On a stream the same fields arrive in the final event, together with the receipt, so a client never has to make a second request to see what it paid.

SDKs you already have.

Any OpenAI-compatible client works unchanged. A dedicated @verifyroute/client package is in design: it will verify receipts locally and refuse to send a request if a provider's attestation does not check out.

Python · OpenAI SDK
from openai import OpenAI

client = OpenAI(
    base_url="https://verifyroute.tech/api/v1",
    api_key=os.environ["VERIFYROUTE_API_KEY"],
)

res = client.chat.completions.create(
    model="mistralai/mistral-small",
    messages=[{"role": "user", "content": "Hello"}],
)

Show your verification.

Providers and model builders can embed a badge that reads the public registry from the visitor's browser. It shows Verified only while the checks pass, and falls back to a plain status when they do not.

Planned

The badge script and image are part of the registry stage and are not served yet.
Badge · HTML
<script src="https://verifyroute.tech/badge.js"
        data-endpoint="<provider id or model id>"
        data-theme="light" async></script>

<!-- No scripts allowed? Use the image variant. -->
<img src="https://verifyroute.tech/badge/<provider id>.svg" alt="Verification status" />

Errors that explain themselves.

StatusCodeWhen
400invalid_requestThe body is not a valid chat request.
401invalid_keyMissing, unknown or revoked key.
402payment_requiredNo key and no payment proof; the body carries a price.
402insufficient_balanceThe wallet's USDG balance does not cover the call.
403model_not_allowedThe key's allowlist excludes this model.
409verification_unmetNo provider meets the requested bond or canary floor.
429rate_limitedThe key's rpm or tpm limit was reached.
503no_attested_endpointThe attested lane has no host with a fresh quote right now.

A refused request is never charged, and it is never quietly sent to a provider below the level you asked for.

Endpoint map.

EndpointPurpose
POST /chat/completionsChat and completion calls, streaming or not.
GET /modelsCatalog with prices, context and supported features.
POST /keysCreate a key with its policy.
GET /keysList keys for the connected wallet.
GET /receipts/{id}Fetch a signed receipt.
GET /providers/{id}Bond, canary and attestation record for a provider.
GET /.well-known/vr-receipt-keys.jsonPublic keys used to sign receipts.

The machine-readable description is at /openapi.json.

Limits and honest caveats.

  • An attestation shows what code is running in an enclave. It does not prove what a provider does outside it.
  • Canaries catch swapped or degraded models statistically; they are evidence, not a guarantee for each single call.
  • A bond limits what a provider can lose, not what a user can lose. Disputes are decided on recorded evidence.
  • Receipts prove what the router saw and signed. Their anchors on Robinhood Chain prove when.

Questions or corrections: @verifyroute on X.