Docs

Logitra, end to end.

An OpenAI-compatible chat API your agent pays for with a signed running tab. Base URL:

Why use this

Logitra is the first model router with its money on-chain. Every other router is a company holding a prepaid balance and an API key for you; the only record of what you were charged is their dashboard. With Logitra the deposit sits in a contract on Robinhood Chain that you can read and withdraw from, each request is a signature your agent makes, and settlement is a transaction anyone can verify.

What that gives you, concretely:

  • A hard cap on what can be taken. The contract pays out only the difference since the last settlement, and never more than the total your agent signed. An operator cannot overcharge, double-charge or invent usage.
  • No key to leak. Paid calls are signed by the agent's wallet. Nothing to paste, rotate or lose. Holder access is checked against a coin balance on the chain, not a list.
  • No subscription, no minimum. Deposit any amount. Unspent deposit is withdrawable after a two-day notice, so tabs you already signed settle first.
  • Every model, one endpoint. One OpenAI-compatible URL for the whole catalogue, with new models added within ten minutes of appearing in the listing.
  • A stamped answer, every time. The reply carries the id of the model that answered. Auto routing adds which lane it chose and why, so a routing decision is never a black box.
  • Builders are paid by the contract. 20% of every settled call with your app id, credited at settlement and claimable any time.
  • Nothing stored. Prompts and answers pass through; only success, tokens and timing are recorded.

What Logitra runs itself is the routing, and it shows its work on every reply. Everything to do with money is on the chain, where you can check it without asking anyone.

Routing

Logitra is one endpoint, POST /api/v1/chat, in front of every model in the catalogue (GET /api/v1/models). The catalogue refreshes from the model listing every ten minutes, so new models appear without a release. The model field decides what happens.

modelWhat happens
logitra/autoDefault. Logitra reads your last message: code, math, multi-step reasoning, structured output or long context go to the deep model with a larger budget and a reasoning pass; everything else goes to the fast model. Base price.
logitra/freeThe same routing over free models only. $0: no tab, no x402, no header, up to 200 requests a day per IP.
lab/modelStraight relay to that model, exactly as sent: nothing swapped, no hidden prompt. Priced from the model's list price.

Every reply names the model that answered, in model and in Logitra-Model. Auto replies add Logitra-Route (fast or deep), Logitra-Route-Reason (the signals it saw) and Logitra-Route-Fallback: 1 when the deep model failed and the fast one answered. The JSON body carries the same in route.

Failover

Add "fallbacks": ["lab/model-b", "lab/model-c"] (up to three) and if a model errors, the next one answers, in order. The reply carries Logitra-Route-Fallback: 1, Logitra-Failed-Over-From and route.failed_over_from, so you always know which model spoke. Fallbacks must cost no more than the first model, because the price is fixed before the request runs. If every model in the chain fails, you get a 502 listing what was tried, and nothing is charged.

Timing

Every reply measures itself. Logitra-Overhead-Ms is the time Logitra spent (parsing, payment checks, routing), Logitra-Upstream-Ms is the time the model took, and the JSON body carries both in timing. On a stream, the overhead is the time before the model was asked.

Pricing

A request is priced before it runs, because your agent signs the price in advance: 2,000 input tokens plus 1,024 output tokens at the model's list price, plus 10%, rounded up to 0.001 USDG and never below the base price ( USDG). Output is capped at 1,024 tokens. logitra/auto is always the base price. Models at the base price work on the free allowance and x402; larger ones run on a tab.

Try it free

Every IP gets one free request a day, with no wallet and no header, on logitra/free, logitra/auto, the $0 models and every base-price model. Coin holders get more; see The coin.

terminal
curl /api/v1/chat \
  -H 'content-type: application/json' \
  -d '{"model":"logitra/auto","messages":[{"role":"user","content":"hi"}]}'

Pay with a tab

A tab is a running total that your agent owes on one app. You deposit USDG into the tab contract once. Each request carries a signature for the new total, which must be exactly the last total plus that request's price (the model's price; see Pricing). The server checks the signature, that the total advances by exactly one price, and that your unspent deposit covers it, then answers.

Nothing touches the chain per request. Logitra submits the latest signed total for every open tab in one batch. The contract pays out only the difference since the last settlement, so it can never collect more than you signed, and never twice.

  • Deposit: one transaction, from any wallet, for any payer address.
  • Withdraw: request it, then take it out after a two-day notice, so tabs you already signed can settle first.
  • Failed requests are not charged: if the router cannot answer, your tab rolls back.

The SDK

sdk/logitra.ts is a small wrapper around fetch. It reads your tab, prices the request from the model in the body, signs the next total, sends it, and re-syncs once if another client moved the same tab. Its fetch drops into any OpenAI-compatible client: new OpenAI({ baseURL, apiKey: 'tab', fetch: tab.fetch }).

agent.ts
import { privateKeyToAccount } from 'viem/accounts';
import { logitra } from './logitra';

const tab = logitra({ account: privateKeyToAccount(process.env.AGENT_KEY), baseUrl: '', app: 7 });
const r = await tab.fetch('/api/v1/chat', { method: 'POST', body: JSON.stringify({ model: 'logitra/auto', messages }) });
const j = await r.json();
console.log(j.model, j.choices[0].message.content, tab.status().headroom);

The header

Without the SDK, send Logitra-Tab: base64 of JSON {payer, app, cumulative, sig}. The signature is EIP-712 typed data, Tab(address payer,uint256 app,uint256 cumulative), domain name "Logitra", version "1", the chain id and the tab contract address. GET /api/v1/tab/{payer}?app= returns the exact domain, types and the total to sign next.

Response headerMeaning
Logitra-Tab-CumulativeThe total you just signed, now accepted.
Logitra-Tab-HeadroomUnspent deposit left after this request, in 6-decimal units.
Logitra-Tab-ExpectedOn a 409: the total to sign instead.
Logitra-CostWhat this request cost, in 6-decimal units.

Endpoints

RouteWhat it does
POST /api/v1/chatOpenAI-compatible chat completion (alias /api/v1/chat/completions). Streaming with stream: true.
GET /api/v1/tab/{payer}Deposit, pending withdrawal, settled and accepted totals, headroom, and the signing domain.
GET /api/v1/modelsThe catalogue: logitra/auto and every model, with list price and Logitra price per request.
GET /api/v1/openapi.jsonOpenAPI 3.1 description of the API.
GET /healthRPC reachability and latest block.

Errors

ErrorMeaning and fix
409 tab_out_of_syncThe total is not last + price (a replay, a skip, or a parallel client). Sign Logitra-Tab-Expected.
402 tab_insufficient_depositUnspent deposit is below the price. Deposit more, or wait for a pending withdrawal to clear.
401 bad_signatureThe tab was not signed by the payer it names.
402 model_needs_tabThat model costs more than the base price, so it is not on the free allowance or x402. Pay with a tab.
400 malformed_tabThe header is not base64 JSON with payer, app, cumulative and a 65-byte signature.
503 tabs_unavailableThe contracts are not deployed on this deployment yet.
429 rate_limitedMore than 120 requests a minute from one IP on one endpoint.

Developers

Register an app in the console (one transaction, registerApp(name)). Put its id in your agent's tab. When a tab with your id settles, 20% of it is credited to you in the contract; claim it any time with claimDev(). App 0 means no app: that share goes to the treasury.

The coin

Logitra's official coin is launched on Pons, on Robinhood Chain. It is a plain Pons launch: no staking, no emissions, no extra tokenomics. Its contract address is published on the home page and nowhere else; treat any other address as fake.

Coming soon: holders will be able to use the API with a key, on set terms published before keys open. Until then, holders test free with a signed pass (Logitra-Holder), and the API is paid with a tab.

What comes next

Where Logitra is going, in the order it is being built. Only the first column is live. Nothing here is a promise of returns, dates or prices; terms for anything that pays holders will be published on this page before it opens.

The last column is deliberately out of focus: it is direction, not a commitment.

Contracts

LogitraTab

deposit / depositForAdd USDG to a payer's tab balance.
requestWithdraw / withdrawTwo-day notice, then withdraw what is left after settlements.
settle / settleManySubmit a signed total; pays the difference since the last settlement: the developer share to the app, the rest to the treasury. Batches skip bad vouchers.
registerApp / setAppOwner / claimDevDeveloper apps and their earnings.
setSplitOwner only; the developer share can never exceed 50%.

Signatures are plain EOA ECDSA; smart-contract wallets (EIP-1271) are not supported as payers yet.

x402 per request

No deposit? Any x402 v2 client can still pay per request: call without a tab, get a 402 with the price, sign one payment, retry. Logitra's own facilitator settles it. Tabs are cheaper for anything beyond a handful of calls, because x402 settles every single request on-chain.

Self-hosting

terminal
npm install
npm run build:contracts   # compile contracts/Logitra.sol
npm test                  # contracts + end-to-end on a local chain
DEPLOYER_PRIVATE_KEY=0x… npm run deploy:contracts
# then set TAB_ADDRESS, CRON_SECRET and a Redis store (KV_REST_API_*)

Settlement runs from /api/cron/settle (bearer CRON_SECRET) on a schedule, and early for any payer whose unsettled total passes TAB_SETTLE_THRESHOLD. The relayer key pays settlement gas in ETH.