Folio/Docs

The whole migration is two lines.

Change the base URL and the key. Model names, streaming, tool calls, and vision work exactly as they do on OpenRouter, because the request is relayed to OpenRouter as you sent it, with one addition: routing is pinned to zero-retention endpoints.

Base URL
https://tryfolio.cloud/api/v1
Endpoints: /chat/completions, /completions, /embeddings, /messages, /models
# before, OpenRouter
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_API_KEY=sk-or-v1-...

# after, Folio. Same two variables.
OPENAI_BASE_URL=https://tryfolio.cloud/api/v1
OPENAI_API_KEY=sk-folio-...

Try any request in the Playground before you change your base URL.

Every reply carries x-folio-cost, micro-dollars or pending until the cost is reconciled, and x-folio-balance, what is free after this request's hold.

Every reply also carries x-folio-attestation, the id of the reserve check in force when the call ran.

Proof of credit

Fetch the check named on a reply, recover the signer, and compare it with the address on the proof page. Then compare the digest with the Anchored event on ReserveAnchor.

curl https://tryfolio.cloud/api/proof/SNAPSHOT_ID
import { hashTypedData, verifyTypedData } from "viem";
const types = { ReserveAttestation: ["snapshotId:string","upstreamMicro:uint256","owedMicro:uint256","unclaimedMicro:uint256","headroomMicro:int256","priceBps:uint16","takenAt:uint64","source:string"].map((s) => ({ name: s.split(":")[0], type: s.split(":")[1] })) };
const p = await fetch("https://tryfolio.cloud/api/proof/SNAPSHOT_ID").then((r) => r.json());
const message = { ...p.attestation };
for (const k of ["upstreamMicro", "owedMicro", "unclaimedMicro", "headroomMicro", "takenAt"]) message[k] = BigInt(message[k]);
const ok = await verifyTypedData({ address: p.signer, domain: p.domain, types, primaryType: "ReserveAttestation", message, signature: p.signature });
const digest = hashTypedData({ domain: p.domain, types, primaryType: "ReserveAttestation", message });

ok is true when the recovered signer is the address published on /proof. digest is the hash the keeper writes on chain once an hour.

Ask

/ask reads a Robinhood Chain wallet and answers in plain words. Sign in with the wallet. No key. Each question spends credit the same way a key does, and the line under the answer is the cost.

Three questions a day are paid by the desk. A holder over 10,000 FOLIO pays from perk credit first. Past that, buy credit, or hold FOLIO and the perk pays for the question.

The tools are read-only. Nothing here can move a token.

From the Robinhood app

Install Robinhood Wallet. Open the Web3 tab. Enter tryfolio.cloud. Connect, sign in, and ask.

There is no Robinhood brokerage login and no brokerage data. The answer reads only what the chain shows.

Let your agent run the desk

Price, stats, and models answer anyone who connects. Balance, usage, hold, awards, and claim answer a key. Claiming writes credit only onto the wallet that key already spends from. A leaked key cannot move the credit anywhere else.

What you are buying

A fixed amount of API credit in dollars. $100 of credit is $100 of model usage at OpenRouter's listed prices, which are the providers' own prices. You pay in USDG on Robinhood Chain. With no subsidy you pay what the credit costs to buy; with subsidy your price drops, capped at 20% under face.

Am I getting the real model

Yes. Responses carry the provider's own model name and id. Nothing is swapped or downgraded.

Do you store prompts

The gateway keeps billing metadata: model, token counts, cost, and timing. Prompts and completions on /api/v1 pass through and are not written. A question on /ask is stored with its answer so you can share it and so the three free questions a day are counted. Every request carries provider.zdr = true so it only reaches zero-retention endpoints.

Where the discount comes from

25% of the 2% creator tax on FOLIO trades goes to a discount vault. When that vault has cash, it covers the gap between what you pay and what OpenRouter charges for the credit. When it has none, you pay cost. Your payment buys your credit; none of it is margin.

Holding and staking

FOLIO you hold counts once toward the daily perk, FOLIO you stake counts twice, and requesting an unstake drops it back to once for a 7 day wait.

Why the desk might pause

Every 5 minutes the sum of every balance, yours included, is compared with the OpenRouter account balance. If balances would exceed it, buying and new awards pause and your key answers 402 until a top-up lands. What you already hold can still be spent down to what upstream will serve. Before a request is forwarded, its worst case is set aside from your balance. The real cost replaces that hold when the reply lands. A request the free balance cannot cover is refused before it is made.

Refunds

Credit is a grant of product access, not cash. If your USDG sits in SaleEscrow for 24 hours without being filled, call refund(quoteId) on the contract yourself and it returns to your wallet.