Start here

↑ ↓ to choose · Enter to open · Esc to close

DATA INVENTORY · GENERATED FROM THE SCHEMA

What we keep.

Every table and column the router stores, the Redis keys and log lines around them, and every place a request’s text or a caller’s address is read. It is written next to the code, checked against the schema by automated checks, and built into this page from the schema when the site is built.

The short version.

Some tables hold request or answer text: schedule_runs.reply_enc, agreement_evidence.content, agreement_jury.statement, kv.value, and schedules.prompt_enc.

  • Every one of the 115 tables and 1,230 columns in the database schema is described on this page, and the build fails if a table or column is added without one.
  • No table has a column for a network address, and no line the code writes to its log records one. Calls without an API key are rate-limited by the caller's address, which appears only inside a Redis key that expires between 61 seconds and 3,601 seconds after the counting window begins. Over Tor no address is used at all.

Where something is kept, exactly

Retry without paying twice keeps a reply when you ask

Opt-in retry protection for API-key inference calls with Idempotency-Key. The key hashes account id, API key hash and the caller's idempotency key. AES-256-GCM ciphertext under APP_SECRET and this scope contains a canonical request-body and endpoint hash, an ownership marker, and the final status, reply and receipt headers. The request body and raw idempotency key are not stored. Replies can echo request text. Stream replies are not retained; a completed marker keeps status and receipt headers instead. An unfinished call or failed retention leaves an in-progress marker; retries never run inference again while it remains. Redis failure refuses a new protected call before billing. No new database row or log field is added. 86,400 seconds (24 hours) from the first request; completion does not extend it. Redis deletes the entry at expiry. After expiry the same key starts a new billable call. Without Redis, entries live in one router process only and are lost at restart. The router still reads request and reply text in memory.

The response cache keeps answers when you ask it to

A request that turns the response cache on has its answer kept, sealed with AES-256-GCM, in Redis and in the router's memory. It is kept for the time-to-live the request asked for in cache.ttl: at most CACHE_TTL_S, which is 3,600 seconds unless the operator changed it, and also the default when the request names none. Requests that do not ask for caching leave nothing here, and a call paid with a blind token, a call on the attested lane or with any disclosure ceiling, a restricted model variant and a streamed answer are never cached. A semantic cache also keeps a 1,024-number hashed word vector of the prompt in memory.

A call paid with x402 keeps its answer for 24 hours, so a lost answer is never paid for twice

Where x402 is switched on, the answer to a call paid with x402 is kept, sealed with AES-256-GCM, in Redis (or the router's memory without Redis), never in the database, so the payer can have it sent again with PAYMENT-RECOVERY if it was lost on the way. 86,400 seconds (24 hours) from the answer, set when it is written; the x402-recovery-expire job also deletes it with its row. Calls not paid with x402 leave nothing here. For that time the database keeps only the payer, the authorization nonce, two hashes and the name of the Redis key.

The Batch API keeps a batch's requests and answers until its results expire

A batch sent to POST /api/v1/batches has its requests and answers kept, sealed with AES-256-GCM, in Redis (or the router's memory without Redis), never in the database. The sealed requests are deleted when the batch finishes; the sealed answers BATCH_RESULTS_TTL after that (86,400 seconds, 24 hours, unless the operator changed it). A batch that never finishes ends when its 24-hour completion window closes, so nothing outlives the window plus that time. Calls that are not part of a batch leave nothing here.

A failed provider attempt can keep a short piece of the provider's own error message

generations.attempts: up to 200 characters of the message a provider sent back when an attempt failed, with URLs, keys, emails and long hex removed. The text is the provider's, not ours; a provider could quote part of a rejected request in it.

Two request headers are kept as you wrote them

apps.url and apps.title: the HTTP-Referer and X-Title headers of a chat call, cut to 500 and 200 characters, so apps can be ranked. Leave the headers out and nothing is kept. They are not recorded on the unlinkable lane.

Settings you type are stored as you typed them

agent_approvals.intent, agent_policies.spec, agent_policy_events.intent, agent_profiles.settings, agent_sessions.metadata, keys.routing, keys.guardrails, keys.tracing, keys.topup, playbook_changes.spec, playbooks.spec, policy_versions.spec, team_audit.detail, characters.card, facilitator_sellers.result_schema, model_watches.state, preset_versions.config, saved_routes.description, saved_routes.config, skills.description, status_incidents.title, status_incidents.updates, tool_listings.canary, and webhook_destinations.events hold configuration you write: descriptions, routing and guardrail settings, the system prompts and tool definitions of your presets, the character cards you publish, session labels. The API checks their shape and size, but it cannot know what you choose to write in a description or a label.

Character memory is kept only as ciphertext, with a vector if you opt in

Memories you keep for a character are sealed on your device under a key the router never receives; the database holds the ciphertext. If you opt in to memory search, it also holds a vector your client computed from each memory, which cannot be turned back into the text but can reveal what it is about.

This page is about what is kept. It is not a claim that nobody can read a request while it is in flight: on ordinary chat routes on every lane the router reads the text of a request in memory, and the provider reads it too under its own policy. The dedicated, off-by-default E2EE adapter forwards encrypted content without decryption; the gateway enclave restores it. Clear routing and billing metadata remains visible.

Which version this is.

This page and /keep/inventory.json are generated from the same source, so they always agree. The hash is the SHA-256 of the exact bytes of that file.

Built from commit
3a3d3849689035578e2d54588c29225e63f27c85
Inventory SHA-256
b00d8286cd165487b542d8d234479c8279a156409aed2914ce8998d22b610c86
Size
115 tables, 1,230 columns, 126 columns that looked like request content or an address and carry a written review
Check it yourself
curl -s https://<this site>/keep/inventory.json | sha256sum prints the hash above. The file is canonical JSON: keys sorted, no whitespace.
Transparency logGET /api/v1/tlog/proof?kind=data_inventory

Asking the router’s log about this hash…

The hash is appended to the router’s public transparency log as a data_inventory entry when a router with a new inventory starts, where the operator has switched that on. Anyone can look it up by hash at /api/v1/tlog/lookup, and, where the log is anchored in Rekor, follow the link above to that entry.

Where a request’s text and a caller’s address are read.

An automated check scans the router’s source for every route that reads a request body and every piece of code that reads a caller’s address, and fails until each one is described here. The rows below say what is read, what happens to it and what is kept.

Request text

WhereWhat is read, and what happensWhat is kept
src/telegram/photos.tsWith TELEGRAM_PHOTOS_ENABLED, the bot reads photo size identifiers and the optional caption from a private Telegram message, calls getFile and downloads the largest photo that fits 8 MB. The downloaded JPEG and caption are readable in router memory for this request. An in-memory JPEG segment filter copies the image data unchanged and drops EXIF and other application metadata, comments and trailing bytes. Malformed or oversized images are refused. The caption, or a fixed question, and an inline JPEG go through the same API-key chat route, billing, limits, private-mode lane guard and signed receipts as text. Telegram and the chosen model provider can read the image and caption and apply their own retention policies.No photo bytes, caption, file id, download path or image URL are saved in Postgres, Redis, logs, filesystem or a bot history. The request's digest and ordinary billing and receipt metadata are retained by the chat path. The bot never opts into response caching. Existing sealed key, model, private-mode setting, polling offset and Telegram-user rate counter retention are unchanged. Disabled by default; no download while off.
src/idempotency/middleware.tsAPI-key request JSON only when Idempotency-Key is present on a supported inference endpoint. Authenticates the current key and role, hashes the canonical body and endpoint in memory, and claims a scoped retry guard before approval consumption or billing. Ordinary router paths still read request text in memory on every lane; encryption at rest does not hide replies from the router.Only a request hash plus an encrypted final reply, status and selected response headers for 24 hours, in Redis or memory. Streaming keeps no answer text. The same key with a different request gets 422; an unfinished call gets 409. Unsupported credential types cannot opt in.
src/api/schedules.tsOwner-chosen name, prompt, model, paying key hash, recurrence, UTC time, cost ceiling and pause state. Requires an active owner or management key, excludes inference and session keys, verifies ownership of the paying key, and encrypts the prompt before saving it.Prompt ciphertext and schedule metadata in schedules; last ten encrypted replies and bounded failure reasons in schedule_runs. Deleted with the schedule. Ordinary chat still reads text in memory and retains billing metadata.
src/model-alternatives/suggest.tsResolved request messages, content-part types, tool declarations, output modalities and token bounds in router memory, plus model metadata, current provider health and routing preferences. Checks the abilities needed by the request and ranks up to three currently eligible alternatives by estimated request cost. Reads message text to estimate token counts. Never forwards a suggestion request to a provider, switches a model or charges for suggestions.No new database table or column, Redis family, log field or server-side store. Suggestions are unsigned error response metadata. Existing batch error outputs may retain them until their ordinary expiry. Chat keeps suggestions with the failed reply in active-tab memory only; its existing history snapshots omit failed replies and their suggestions from storage and exports; clicking a suggestion resends the same conversation through ordinary authorization, policy, lane and billing checks.
src/hardening/body.tsRequest bytes before route dispatch, including ordinary plaintext inference, files and encrypted envelopes. Reads the declared Content-Length and streams up to each route's wire cap; an over-cap chunk is discarded. Rejects excess bytes with 413 before route side effects; passes a bounded replacement request to existing handlers, preserving the gateway origin record.Bounded bytes in request memory only. This guard does not hide plaintext prompts from the router. No new database columns or body logging.
src/hardening/middleware.tsThe bounded MCP JSON message or batch, including tool arguments and any prompt. Rejects batches over 20 messages and charges each message against the anonymous minute limit. Existing MCP tool and rulebook guards still apply.Parsed message in request memory only; count in the anonymous limiter. No tool arguments or prompts in the counter or logs.
src/tools/routes.tsA paid tool call: the tool's address, method, a JSON body of at most 64 KiB for the tool, max_price and optionally a model and prompt to hand the answer to. A tool listing: name, summary, address and a canary probe. Sends the body to the tool through the egress guard and reads its answer (2 MB at most, JSON or plain text only) in memory, returning it to the caller marked untrusted. Only when the rulebook sets tools.pass_to_models and the call asks for it is the answer sent to a model through the ordinary chat route.tool_calls keeps hashes of the request and answer, amounts, the address without its query and the signed receipt; tool_listings keeps the listing. The body, the query string and the answer are not stored or logged. No new Redis family beyond the two rate limits, no caller-address reader.
src/structured-output/chat.tsResolved chat messages and response_format schema, the final answer, and the opt-in anyroute.json_check setting when STRUCTURED_OUTPUT_CHECK_ENABLED is enabled. Reads request and answer text in router memory to check JSON and supported schema assertions. Repair may send the same provider and model one extra request containing the conversation, original answer, schema and validation errors. Each call passes the ordinary authorization, lane, agent and billing checks. Streams validate only.No new database column, Redis family or log field. Both calls keep ordinary generation hashes, token counts, costs and signed receipts. Validation errors, JSON Pointer paths, combined charges and nested call receipts are unsigned response metadata, not written to generation receipts or returned by receipt lookup. Existing batch outputs can retain that metadata with the answer. Preset json_check settings live in the existing preset_versions.config JSON. Existing optional cache and batch retention rules still apply; non-streaming repair bypasses the response cache.
src/pay/recovery.tsThe body of a paid x402 call on the chat, completions, embeddings, rerank and character chat routes, and of a recovery request; and the answer's bytes once the call is answered. Hashes the request (the receipt's request_sha256) to bind the answer to it, or to compare a recovery request with it. Seals the answer's bytes with AES-256-GCM. A recovery checks the payer's EIP-191 signature first and never relays the payment again.The two SHA-256 hashes, the payer, the nonce and the Redis key name in x402_paid_results, and the sealed answer in Redis (or the router's memory without Redis), each for 24 hours. The request text is not kept. No log field, no caller-address reader.
src/agreements/internal-transport.tsDecrypted party evidence bundle and structured provider verdict text in router memory. Fixed rubric sent through attested-lane selection with fresh non-development attestation, stored provider credentials and quote-pinned TLS where configured. Gateway receipts must verify upstream attestation and exchange digests. No customer account or billing rows.Existing agreement_jury.statement stores model reasons (which may quote evidence), signed operational receipt with request/response hashes, provider attestation and checked gateway receipt references, usage and provider-list-price operator cost estimates. Canaries have no separate operational-cost ledger. Failed calls may incur unmeasured cost. No evidence text in logs; no new Redis keys or caller-address readers. Same resolution-based jury retention applies.
src/agreements/routes.tsBounded party evidence text or JSON, or a strict create-agreement preparation with payee wallet, milestone USDG amounts, terms hash and future deadline. Requires an authenticated wallet-linked account matching the indexed payer/payee. Caps streams without trusting Content-Length. Preparation checks inherited rulebooks and returns unsigned calldata; jury calls use the attested chat path with a configured API key, or the optional internal provider transport.Evidence hash and APP_SECRET-encrypted content in agreement_evidence, up to 32 items per party. Jury statement stores per-model answer reasons, receipt references and a signed ruling; reasons can quote evidence. Router reads evidence in memory. Parties can read both parties evidence through the API. Resolution plus 30 days by default permits deletion; a fresh-index retention job removes evidence and jury rows. No new Redis family, log field or caller-address reader.
src/api/e2ee.tsA bounded encrypted JSON envelope and encrypted SSE or JSON response; model, roles, lengths, public keys, timestamp, nonce and clear usage remain visible. A caller must actually encrypt content; framing checks cannot prove encryption. Validates a strict text envelope, forwards the original bytes without decryption, hashes wire bytes, observes usage and completion for billing. No tools, files, search, cache, alias or content transformations.Only hashes, counts or reservation bounds, charge and timing in generations and the ledger. The signed receipt adds end_to_end_encrypted, e2ee version/suite/gateway_attested/complete/billing_basis/input_byte_bound/max_tokens/request_bytes/response_bytes and gateway_receipt (id, keyset digest, response-hash/request-hash/upstream check states and upstream session id and GPU claim). Existing retention and deletion apply. No envelope, response ciphertext, public key, replay nonce, timestamp or credential is persisted; no new log fields or Redis families.
src/api/chat.tsThe whole JSON body of a chat or text completion: the messages, the model and the parameters (readJson). Read in memory to route the call on every lane: validated, checked against guardrails, priced, then sent to the provider chosen. The request is hashed (request_sha256) and the answer is hashed (response_sha256). Streaming answers are passed through chunk by chunk.Not stored. Kept in memory for the length of the call. The opt-in response cache and batch content are kept sealed outside the database (see the Redis section), and a failed provider attempt can keep up to 200 characters of that provider's own error message.
src/api/batches.tsThe JSON body of a batch: up to BATCH_MAX_LINES chat or embeddings requests (requests or input_jsonl). Checked line by line, then sealed at once and kept in Redis (or memory) for the worker, which runs each line through the chat or embeddings handler as the key that sent the batch.Not in the database: the database gets counts, statuses, costs and generation ids. The sealed requests are deleted when the batch finishes and the sealed answers when its results expire (see the Redis section).
src/api/embeddings.tsThe JSON body of an embeddings call: the input text. Sent to the provider chosen and the vectors returned.Not stored; a generation row and receipt with hashes and counts are written.
src/api/rerank.tsThe JSON body of a rerank call: the query and the documents. Sent to the provider chosen; its scores are checked and returned, with the documents' own text when asked.Not stored; a generation row and receipt with hashes and counts are written.
src/api/anthropic.tsThe JSON body of an Anthropic-format messages call and free onion count requests. The router reads code, prompts and tools in memory. Converted to a chat request and sent through the router's own chat route, so it is handled and kept exactly as a chat call is.Nothing beyond what src/api/chat.ts keeps; token counts alone create no payment or request record.
src/api/responses.tsThe JSON body of a Responses-format call. Converted to a chat request and sent through the router's own chat route.Nothing beyond what src/api/chat.ts keeps.
src/ollama/routes.tsThe JSON body of an Ollama-format chat, generate or embed call. Converted to a chat or embeddings request and sent through the router's own route, so it is handled and kept exactly as that call is.Nothing beyond what src/api/chat.ts and src/api/embeddings.ts keep.
src/api/mcp.tsThe JSON-RPC body of a tool call for the MCP endpoint, which can include a prompt. Chat is forwarded to the router's own chat route. Rulebook tools forward caller authentication and prompt-free intent identifiers to the existing agents routes; token estimates use catalog prices. Reading and checking rules does not create policy events.Nothing beyond what src/api/chat.ts and its existing policy enforcement keep. Rulebook reads and dry runs add no stored data.
src/api/rag.tsThe documents and the question of a retrieval call. Cut into chunks and embedded through the router's own embeddings route, ranked in memory, and the best chunks sent to the router's chat route.Nothing of the documents, question or answer is kept; the chunks and vectors are dropped when the request ends. The response cache is never used.
src/ohttp/gateway.tsAn encapsulated request (Oblivious HTTP). The gateway opens it with its own private key, in memory. Dispatched to the router's own routes as an ordinary request without a client address.Nothing beyond what the route it reaches keeps. The private key for an epoch is destroyed when its window ends.
src/services/telegram.tsA Telegram message a user sent to the bot (fetched from Telegram by long polling). Sent to the router's own chat route with the user's own API key, so limits, billing and receipts apply.The message text is not stored or logged; only the user's sealed key and chosen model are (kv table).
src/gateway/cache.tsThe request and the answer, only when the caller opted in. Encrypted and stored with a time-to-live (memory and, when configured, Redis). A hit is served without asking a provider.The sealed answer, for the time-to-live the caller asked for (at most CACHE_TTL_S). A semantic cache also keeps, in memory only, a 1,024-number hashed word vector of the prompt so near-duplicates can match.
src/api/characters.tsA character card (JSON or PNG) or, for a private card, only its ciphertext and hash; and on POST /api/v1/characters/:id/chat a chat request with the conversation, the memory the client decrypted and, for a private card, the decrypted card. A public or unlisted card is normalized and stored. A chat is assembled into a prompt in memory and sent through the chat route (src/api/chat.ts), like any other call; a private card sent with it is checked against its stored hash and used for that call only.Public and unlisted cards in characters; for a private card only the ciphertext and hash. Nothing of a chat, its memory or a decrypted private card; public characters add one to a daily call and cost counter (character_usage).
57 routes that read a body but carry no prompt (settings, payments, public data)
WhereCarriesWhat is read, and what happensWhat is kept
src/api/business-details.tsSettingsOptional user-entered business name (160 characters), multi-line postal address (1000), tax ID (120, free text) and reference (240, no email addresses). Unknown fields and control characters are rejected. With STATEMENTS_ENABLED, requires an active account management key to replace or clear the details, excluding sessions, team-only owner/admin keys and read-only keys. Other keys that can read statements can read this account's details; the existing read-only route guard still blocks the new settings route, so those keys use the opt-in statement response instead.business-details:<account id> in the existing Postgres kv table stores the four fields in plain JSON with an update timestamp, until replaced or deleted. No inference text, new Redis key family, network address reader or log field is added.
src/key-rotation/routes.tsSettingsOne strict grace choice: 1h, 24h or 7d. Uses the existing key-edit owner/admin authentication, refuses restricted callers and agent sessions, checks the Credits deposited total directly on chain and account ownership and copies eligible account-backed keys in one transaction. Returns the new secret once with no-store; the router handles it in memory.The old and new key hashes, rotation time, old-key grace deadline and original rulebook history link in key-rotation:<key hash> rows in kv. Key settings and saved rulebook revisions are copied to existing tables; new usage starts at zero. No secret is stored.
src/agent-duplicate/routes.tsSettingsAn optional new agent name, trimmed to 1–100 characters. The source key hash is read from the route. Requires account management or same-team owner/admin authentication, rejects restricted and session callers, rechecks authority inside the locked account transaction, and enforces team budgets and no permission escalation. Returns the fresh secret once with no-store; the router handles it in memory.A new keys row, a fresh team_members API-key membership without a principal binding, current agent_policies rules detached from any playbook, one policy_versions save, and a new hash-chained agent_policy_events duplicated entry whose reasons hold Copied from plus the original readable name. Existing agent-approvers and quiet-agent-alert kv settings are copied, with quiet delivery history reset. No secret is stored.
src/model-watch/routes.tsSettingsA strict object containing a public catalogue model id for watch or unwatch. Requires a current management owner key, excludes session, team and read-only keys; serializes watch cap changes under an account row lock and revalidates current authority in the transaction.Account id, model id, creation time and worker availability state in model_watches. No prompt, answer, credential, caller address or new log field. Browser memory holds the watch list and a short shared read promise; no new browser storage.
src/api/agent-approvers.tsSettingsStrict per-agent approval mode and bounded unique IDs selected from the agent's active team members. Requires management or owner/admin account/team access outside agent sessions, then rechecks access and member choices in a transaction serialized with approval decisions.Mode and selected principal IDs or key hashes in existing kv, plus existing security notice metadata when enabled. No prompt, answer, secret or caller address is read or retained.
src/api/quiet-agent-alerts.tsSettingsA strict JSON object with hours null or one of 1, 3, 6, 12, 24, 72; no other field is accepted. Requires the existing agent owner/admin principal and same account/team ownership, explicitly refuses inference keys, and writes settings outside the rulebook under the account lock. Disabled endpoints return 404 before reading a body.quiet-agent-alert:<key hash>: per-agent hours (null means off), enable timestamp, last claimed quiet-period activity timestamp, and newest 100 notices with random id, timestamp, readable agent-name title, hour window and last charged-call/Guard-decision time. Settings and the dedupe anchor persist until operator deletion. Enabled runs and changed settings prune notices older than 90 days; disabled cleanup pauses, while inbox reads hide expired notices. Deleted keys leave inaccessible settings until operator deletion. No rulebook field, table, column, Redis family, address reader or log field is added.
src/security-alerts/routes.tsSettingsAn account management key's strict enabled boolean for security alerts. Requires the existing owner/admin principal guard plus management rights; session keys and team administrators cannot change account-wide preferences. Returns no-store. SECURITY_ALERTS_ENABLED defaults to false, returning 404 while off.The boolean under security-alerts:preference:<account id> in existing kv until changed or account data is removed. No request text or caller network address.
src/notifications/routes.tsSettingsA strict complete set of Inbox and Telegram booleans for supported notice types, including opt-in status_incidents, plus nullable daily UTC quiet-hour clocks. Requires an active management owner principal, excludes session and team keys, revalidates authority under the Telegram link lock and returns no-store.notification-prefs:<account id> in kv stores channel choices and UTC quiet hours. Weekly Telegram reuses weekly_summary_opted_in on existing links; security switches extend the existing security-alerts:preference row. No credentials or network address.
src/api/weekly-summary.tsSettingsAn authenticated owner/admin's strict opted_in boolean for this key's Telegram link. Rechecks current link authority under the same lock as unlink and delivery. Writes the preference only for the caller's link.Only the nullable weekly_summary_opted_in flag in kv; the worker keeps last_sent_week on the existing account. No prompt or answer text, new address reader or new tracking.
src/api/account-runway.tsSettingsOne nullable numeric low_balance_usd threshold between zero and one million dollars. Authenticates an active owner key, excludes session and inference-only keys, and accepts edits only when LOW_BALANCE_ALERTS_ENABLED is on.Threshold in accounts.low_balance_pico and the crossing claim in accounts.low_balance_alerted. Each observed crossing keeps balance and threshold snapshots in low_balance_alerts. No prompt, answer or caller network address is read.
src/api/project-budgets.tsSettingsA numeric budget_usd setting, zero to one million USD, and a validated project name in the route. Requires an active account management owner key, excludes sessions, and serializes changes with ledger reservations using the account lock.The cap in project_budgets; saving below current spend may also create the month's deduplicated project_budget_notices row. No prompt, answer or network address is read.
src/api/guard.tsSettingsA strict bounded action name, optional target label and order digest, decimal amount and approval identifier, or a reported outcome. Authenticates the deciding key and serializes checks and reports with the account lock. Action and target are readable caller-chosen labels; targets can name a wallet or host. No full order details are accepted. When DECISION_TAGS_ENABLED is on and an order digest is given, the decision also reads the same agent's calls from the preceding 24 hours whose stored receipt carries that digest as decision_tag and returns their ids, model, provider and time as informed_by; GET /api/v1/guard/decisions reads decisions by digest or receipt id within the Activity scope. Neither stores anything new.Decision metadata and reported outcomes in agent_action_decisions, with action decisions and outcomes on agent_policy_events and action approval projections in agent_approvals. Reported amounts are not verified execution.
src/api/deposits.tsSettingsA strict transaction hash and deposit lane only. Form amounts and sender addresses are not accepted. Authenticates the key, excludes session and agent-only roles, scopes reads and submitted hashes to its account. Chain logs determine observed amounts, senders and credit values; submission never credits funds.deposit-watch rows in kv keep account id, lane, hash and submission time across reloads. At most 20 submitted hashes per account; removed after indexed credit, otherwise retained until operator deletion. No new Redis keys, caller-address readers or log fields.
src/api/agent-pay.tsSettingsA recipient (public profile id or 0x wallet), a decimal USD amount, an optional memo digest and approval id; or a transaction hash to confirm. Authenticates the agent key, decides with its rulebook through Agent Guard (action pay.agent), and returns unsigned USDG transfer instructions for the payer's own wallet. A confirmation reads that transaction's receipt, Transfer logs and block hash from Robinhood Chain and signs a receipt. The router never signs or sends the payment.agent_payments and the existing Agent Guard decision, outcome and decision-chain records. One new rate-limit family; no caller-address reader or log field.
src/api/linked-wallets.tsSettingsA secondary wallet address, or a one-time nonce and personal signature, or explicit unlink confirmation. Requires an account owner key. Verifies the configured origin, chain id, five-minute expiry and secondary wallet signature; consumes the nonce once. Refuses existing wallet accounts, other secondary links and verified owner wallets of organisations owned by other accounts. Unlink affects later first deposit credits and agent payment eligibility; earlier credits remain assigned.The link address, account id and linked date in account_linked_wallets; challenge metadata in kv; no signature, prompt, answer, caller network address or new log field.
src/api/agent-approve-and-allow.tsSettingsA strict confirmation body containing only the 64-character SHA-256 of the rulebook reviewed by the principal. Checks approval owner/admin scope, original amount-only decision reasons, current rulebook hash and pending status. Approves once and raises only that agent's ask-first amount in one account-locked transaction; playbook followers are refused.The updated rulebook, its schema version, digest, principal key hash and update time in existing agent_policies; policy_set and approval_approved events in existing agent_policy_events; decision status, actor and time in existing agent_approvals, plus the existing approval webhook when configured. No new Redis families, log fields or address readers. The confirmation hash is checked in memory and is not separately persisted. Ordinary request text remains readable by the router in memory. D144: Each rulebook save or playbook copy also retains its full readable rules, digest, date, saving key hash and source in policy_versions, in the same transaction. These revisions remain until operator deletion, including after the current rulebook is removed.
src/api/agent-policy-history.tsSettingsA strict object containing only a 64-character rulebook SHA-256 to restore from the target key's history. Requires the same owner/admin, management, account and team permissions as PUT policy. Validates saved rules and digest, refuses following playbook keys, and atomically appends a revision and a policy_set event while keeping Stop state.Full readable saved rules, digest, time, saving key hash and change source in policy_versions. The current rulebook in agent_policies and its digest in the existing event chain. No new Redis families, log fields or address readers. Ordinary request text remains readable by the router in memory.
src/provisioning/scope.tsSettingsA strict scope setting: inference or account. Authorization and x-api-key credentials are hashed in memory for route restrictions; receipt identifiers are checked against generation ownership. Requires a management key for account defaults; refuses inference-only keys on every route outside the model-call and own-generation/receipt allow-list. Newly minted child keys inherit the default, including sessions and team sign-ins.A boolean in accounts.inference_keys_default; keys.scope stores the issued scope and keys.include_byok_in_limit stores the compatibility selection. Existing rows retain their access. No new request text, address readers, Redis families or log fields. Model calls still pass through existing routing and billing.
src/provisioning/inference.tsSettingsOnly model and fallback-model identifiers from the already parsed inference request, after per-key aliases resolve. No prompt or answer text is inspected by this check. Refuses @ references for inference-only keys before chat reads account routes, presets or character records. Catalog model calls continue through unchanged billing.Nothing additional: no model identifier, body, Redis family, log field or address is stored by this scope check.
src/webhooks/routes.tsSettingsBounded JSON containing an HTTPS destination URL and selected fixed event types. Requires an authenticated owner/admin outside agent sessions. New account-wide destinations require a management key; non-management callers see and control only destinations scoped to their own key.URL and generated signing key are encrypted under APP_SECRET. Selected event identifiers are retained. Subsequent responses redact the path/query and omit credentials. No new Redis family, log field, prompt/answer reader or caller-address reader.
src/facilitator/routes.tsPayments or signaturesx402 verify and settle bodies (a payer's signed USDG authorization and the seller's payment requirements), signed seller listings, and gas float top-ups, each at most 64 KB. Checks signatures, amounts, time windows and nonces, relays a valid authorization from the payer straight to payTo with the relay key, and screens a listed payTo against the sanctions list.Settled and failed attempts in facilitator_settlements, signed listings in facilitator_sellers and float balances in seller_gas_floats. Request bodies are not stored and carry no prompts.
src/api/agent-profiles.tsSettingsOwner-written public profile fields (including an optional HTTPS agent endpoint and payout wallet), explicit rulebook category selections and bounded certificate claim identifiers. Authenticates the owner or authorised account administrator, checks key ownership, validates selected record claims, strips control and Unicode format characters from bounded owner text, and publishes the card at an independent random slug. Public reads sanitize existing owner text again and project only opted fields and verify certificate signatures and expiry.Public settings, latest selected certificate and a private key-hash association in agent_profiles until unpublish. No new address reader, Redis family or log fields. Existing receipt signing key entries are published when certificates are requested.
src/identity/routes.tsSettingsOwner identity choices (two booleans), a registration transaction hash, a publish flag for a track record; a reviewer's receipt id, receipt kind, 0 to 100 score and two short tags; or a track-record certificate to verify. Owner routes require an owner or administrator key of the same account, not a session key. Feedback is accepted only when the router's own receipt names the reviewer's account as payer and the agent as payee or the agent served, and never from the agent's own account. Free text is refused.Choices and registration progress in agent_identities, entries in agent_feedback, issued certificates in agent_track_records. Verification keeps nothing. One new account rate-limit family (agent-feedback). No prompt, answer, caller address or log field.
src/api/agent-sealed.tsSettingsStrict registration settings: HTTPS /attest URL without query, image digest and measured compose hash. Requires principal ownership of the active non-management key, obtains fresh quote evidence through guarded public-only pinned TLS and verifies key fingerprint and measured deployment.Registration settings, random revision, fixed result codes, verifier names, TLS key hash and check time in the sealed-agent kv family; never inference bodies or API credentials. No new Redis family or log field.
src/telegram/delivery.tsSettingsPrivate Telegram /link and /unlink commands and approval callbacks fetched by the existing bot poller. Link codes and callback identifiers are read in memory. The link is role-checked and recorded without a key secret. Callbacks run the same approval decision as the dashboard; inference consumption is unchanged. Telegram receives approval intent metadata and alerts, plus current rulebook amount caps and ask-first thresholds when AGENT_RULEBOOK_WORDS_ENABLED is enabled.Only the link identifiers, code hash, expiry and delivery markers described under kv. No Telegram message text or inference text is copied. No new request-body or network-address reader.
src/telegram/balance-spend.tsSettingsPrivate Telegram /balance and /spend commands, Telegram user and chat identifiers, the existing account link and its current key authority. Reads existing settled account balance, charged ledger entries and visible key names to answer the command. Reuses account runway and agent spend reads. Balance and rolling seven-day pace are account-wide as on Home; spend uses UTC days and Monday-start weeks with the linked key's team visibility. Revalidates the link and authority before sending. Telegram receives readable amounts, estimated days, visible key names and, for /spend top agents, Activity links containing their key hashes and the exact UTC settlement range (J182) and applies its own retention policies.No new table, column, Redis counter, log field or saved reply. The existing link, ledger and keys are read without changing them. No API key secret or inference text is needed for these commands; existing Telegram chat keys remain separate.
src/telegram/agent-stop.tsSettingsPrivate Telegram /agents, /stop and /start commands, user/chat identifiers, and inline callback action, complete key digest and link generation. Reads the existing link, current key role/team/scope and expiry, visible key names and Stop state, including inherited session policies for list status. Rechecks current linked owner/admin authority and account/team ownership under the existing link lock. Read-only, inference-only and session authority is refused. Uses the same changeKill operation and security context as web Stop/Resume, under the existing account lock. Telegram receives short agent names, current status, UTC deadlines, confirmation text and digest/generation callback identifiers. Commands and replies are readable by Telegram and subject to its retention policies.No new table, column, Redis family, log field or button-state record. Uses the existing telegram-link callback limiter counter (20 commands or button presses per minute per Telegram user). Stop changes existing agent_policies killed/kill_until/killed_at/killed_reason/updated_at/updated_by fields, and appends existing hash-chained agent_policy_events and existing alert/security records with their existing retention and notification preferences. Raw command text is not copied to storage. No inference prompt, API key secret or wallet address is read by these commands.
src/api/agent-certificates.tsSettingsBounded record claim identifiers for issuance; a signed certificate supplied by body or query for public verification. Checks retained generation counts and rulebook events, signs true claims with a fresh random pseudonym, or checks certificate signature and expiry. The router knows the authenticated issuing key.No certificate, pseudonym, claims, query or body is persisted. Only an account issuance limiter counter and the reused public receipt signing key log entry are kept; no prompt fields are accepted.
src/api/playbooks.tsSettingsA playbook name of at most 100 characters with a strict bounded rulebook and an optional team id, or a playbook id (or null) for a key to follow. Requires the same owner/admin permissions as editing a key's rulebook; account-wide playbooks change only with a management key. A rules change is copied to every following key under the account lock.The playbook in playbooks, each change with its digest and rules in playbook_changes, the following keys' copies in agent_policies with policy_set events in agent_policy_events, and team audit entries. No prompt or answer fields are accepted. D144: Each rulebook save or playbook copy also retains its full readable rules, digest, date, saving key hash and source in policy_versions, in the same transaction. These revisions remain until operator deletion, including after the current rulebook is removed.
src/api/agents.tsSettingsA strict bounded rulebook, a kill reason, a metadata-only Intent for a dry run, or a draft rulebook and a number of days (1 to 7) to replay. Requires the same owner/admin permissions as editing the target key. Evaluates dry runs deterministically without event writes or kill changes. A replay reads that key's recorded calls (model, lane, cost, tokens and time from generations, plus the linked rulebook events) and its Agent Guard checks in a read-only transaction, and evaluates the draft against them.Current rulebooks and optional principal-written kill reasons in agent_policies; decision metadata and changes in agent_policy_events. Dry runs and replays keep nothing. No prompt or answer fields are accepted. D144: Each rulebook save or playbook copy also retains its full readable rules, digest, date, saving key hash and source in policy_versions, in the same transaction. These revisions remain until operator deletion, including after the current rulebook is removed.
src/agents/enforce.tsSettingsDeclared tool and function names from the inference body already parsed by the router. Projects only identifiers into the rulebook Intent, alongside the resolved model, lane, token bound and cost reservation.Only Intent metadata and fixed decision reasons in agent_policy_events. Never arguments, descriptions, prompt or answer text; no new Redis key family or log field.
src/api/network-hosts.tsSettingsUp to 8 KiB of host signup JSON or an operator-generated sidecar credential, with an existing wallet signature over the canonical JSON hash. Strictly validates signup fields, verifies the wallet and performs attestation, policy and sanctions checks. Credentials are accepted only for the recovered operator wallet.Provider name, endpoint, operator and payout wallets, requested model IDs, optional contact, status and refusal reasons. Credential stored only in existing AES-GCM api_key_enc. The router sees it in memory. No whole-body log or signature column.
src/network/waitlist.tsSettingsAt most 4 KiB of JSON: waitlist fields or a deletion code. Validated strictly; a filled honeypot is discarded. The deletion code is hashed for an atomic delete.Only sign-up fields, optional contact, id, deletion digest and time in network_waitlist. No raw deletion code, body log, IP or user agent. Free text is readable by the owner; public stats return counts only.
src/admin/trpc.tsSettingsFor network.publishPolicy, the operator's policy document decoded by the tRPC transport and validated by hostPolicySchema. No prompt fields are accepted. Checked for consecutive version and issue time, canonically encoded, signed with the log key, and committed with its transparency-log entry and checkpoint.The public canonical policy, hash, signature, public verifier key, version and timestamps in host_policies, and a host_policy hash entry in tlog_entries. No caller address, operator token or request headers are retained by this publication path.
src/api/common.tsSettingsThe shared JSON body reader used by the routes below: it reads the text, checks its size (16 MB at most) and parses it. Returned to the route.Nothing.
src/api/keys.tsSettingsKey settings (name, budget, limits, allowed models, tracing destination, scope, include_byok_in_limit and the auto top-up amounts), amounts, BYOK provider keys, team roles and wallet sign-in challenges. Validated and written to the keys, byok_keys, teams and kv tables as described above.The settings and, for a BYOK key or a tracing destination, the key or the destination URL and credentials encrypted under APP_SECRET.
src/api/saved-routes.tsSettingsA saved route: fallback models, provider preferences and sampling controls. Validated against a strict schema with no field for message text, then stored.The route in saved_routes.
src/api/skills.tsPublic dataA skill to publish: a repository URL, ref and folder, or an uploaded .tar.gz, .tar or .zip of a skill folder (SKILL.md, scripts and resources), and an optional price; an author's new price; an operator's revocation reason. The archive is read in memory under size, file-count and path limits (nothing is extracted to disk), normalised into one canonical tar, hashed and scanned; a repository is fetched at depth 1 and its tree read without a checkout.The published skill, its hash and scan report in skills; installs in skill_installs.
src/api/presets.tsSettingsA preset: fallback models, provider preferences, sampling controls and the owner's own system prompt, response_format and tool definitions. Validated against a strict schema with size caps, then stored as a new version.The preset's versions in preset_versions.
src/api/memory.tsSettingsA memory blob the client sealed (ciphertext), its opaque scope, kind and key fingerprint, and an embedding vector only when the client opts in. Checked to be in sealed form (plaintext is refused), then stored.The ciphertext and its labels in character_memory, and the vector when the client opted in.
src/api/teams.tsPayments or signaturesTeam settings (a name, an org budget, a role), invites, and the proofs members sign in with: a passkey registration or assertion (WebAuthn clientDataJSON, authenticator data, signature) or a wallet signature over a one-time message. Settings are validated and stored; passkey and wallet proofs are verified and only the passkey's public key or the wallet address is kept. Each change is appended to the team's audit log.The team, team_members, team_principals and team_audit tables; nothing of the proofs themselves.
src/api/spend.tsSettingsA spend alert rule. Validated and stored.The rule in spend_alerts.
src/api/agent-sessions.tsSettingsAn agent session: name, budget, lifetime and labels. Validated and stored.The session in agent_sessions.
src/api/lane.tsSettingsAn operator's description of a model for the model lane: variant, status, licence and weights source. Checked for an operator token, validated and stored.models_lane.
src/api/status.tsSettingsAn operator's incident notice for the status page: title, affected lanes and surfaces, impact, status and update text. Checked for an operator token, validated against a strict schema with size caps and stored.status_incidents.
src/api/disclosure.tsSettingsA provider disclosure profile written by an operator. Validated and stored.provider_disclosure.
src/api/dayzero.tsSettingsAn operator's request to evaluate or approve a day-zero candidate. Validated and stored.The lane tables.
src/api/creator-claims.tsSettingsA creator claim: model, wallet address and Hugging Face handle. Validated and stored.lane_claims.
src/api/host-anchor.tsPublic dataA request for an inclusion proof: a receipt envelope from an attested host (hashes and counts, no text) or a leaf hash. Looked up in host_anchor_leaves and answered.Nothing.
src/api/ipx.tsSettingsAn operator's switch that halts or resumes the index-price oracle. Checked for an operator token and stored.The halt flag in the kv table.
src/api/paymaster.tsPayments or signaturesA paymaster (gas sponsorship) request. Checked and answered.Nothing beyond the Redis rate-limit key.
src/api/public.tsPayments or signaturesReceipt verification requests, pay-with authorisations, provider applications and creator claim challenges. Verified and, for a provider application or a pay-with authorisation, stored.The provider and pay-with tables described above.
src/blind/routes.tsPayments or signaturesA blinded token request. Signed by the issuer.Nothing that links the buyer to the token.
src/tlog/routes.tsPublic dataA signed checkpoint note from a witness (16 KB at most). Verified and stored as a cosignature.tlog_cosignatures.
src/api/agent-stop-all.tsSettingsOptional Stop reason and absolute until time for bulk Stop. Authenticated owner/admin/management authority and current account/team rulebooks. Rechecks current role, scope, expiry and session authority within the account-locked transaction; changes only permitted agents through the existing per-agent changeKill operation. Returns the number changed.Uses existing agent_policies Stop fields, updated time and actor, hash-chained agent_policy_events, and existing alert/security records and notification preferences. Reason is stored in killed_reason as on individual Stop. No new table, column, Redis family or log field; no inference prompt or answer reader.
src/telegram/agent-stop-all.tsSettingsPrivate human Telegram /stopall and /startall text and user/chat identifiers. Current linked account/key authority, role/team/scope and expiry; optional duration preset. Rechecks authority under the existing link and account locks. Telegram receives changed-agent counts, confirmations and UTC tomorrow deadlines; Telegram can read them and applies its retention policies.Raw command text is not copied to storage. Reuses the telegram-link callback limiter family and existing link records, policy Stop fields, policy events and alert/security records with existing retention and notification preferences. No new table, column, Redis family, log field or button state; no API secret, wallet address or inference prompt reader.
src/telegram/menu.tsSettingsPrivate human /menu messages, Telegram user/chat identifiers and callback action plus link generation. Reads the existing link and current principal authority. Delegates to existing balance, spend, agent list, Stop all and approval readers with their existing permissions. Sends readable command replies and inline buttons to Telegram, which can read them and applies its retention policies. Inbox and Settings buttons open the configured site URL at the existing dashboard sections and carry no credential. Approval-only teammates may open the menu but retain their existing approval-only permissions. Each delegated command checks the generation at its authoritative link read. Waiting approvals reuses delivery.ts, current approver visibility, the approvals Telegram switch and deferTelegram; approvals retain the existing immediate-delivery exception to quiet hours.No new table, column, Redis family, log field or durable menu state. Process-local WeakMap metadata binds a delegated update to its generation only while the update is reachable. Reuses the existing telegram-link callback limiter. Explicit approval listing sends up to ten oldest pending, unexpired approvals, including previously delivered ones, and refreshes their existing telegram-approval message_id and status markers. Successful refresh replaces the old message and reminder bindings; failure preserves existing markers. Existing marker expiry, unlink deletion and atomic single-use decision rules apply. No raw menu or reply text is persisted. No API key secret, wallet address or inference prompt is read by the menu; ordinary inference paths still read request text in router memory.

A caller’s network address

WhereWhat is read, and what happensWhat is kept
src/key-ip/allowlist.tsThe existing trusted client-IP helper for API keys with owner-set IP restrictions and for the authenticated current-IP helper. Both Bearer and x-api-key credentials are checked. No address is read on onion or Oblivious HTTP ingress. In-process adapters retain the verified originating address for the same key in asynchronous request-scoped memory, rechecking its current allowlist at every hop. Compares IPv4, IPv6 and CIDR ranges in request memory and refuses a mismatch before routing or charging. The current-IP endpoint echoes the selected address once with Cache-Control: no-store. Unknown addresses fail closed. Scheduled and batch inference has no verifiable originating client IP and is refused for restricted keys.The observed caller address is never stored or logged by this feature. Only the owner-supplied allowlist is retained in keys.allowed_ips under existing key retention. The browser editor holds entered addresses and a requested current-IP response in component memory until the dialog closes; saving stores the selected list as owner settings. Existing ingress limiter retention remains unchanged. No new Redis key family or log field.
src/hardening/client.tsThe socket address, trusted X-Forwarded-For hop selected from the right by TRUST_PROXY_HOPS, and CF-Connecting-IP only when the enabled origin lock secret matches. The socket is also read to exempt direct private-network callers without forwarding headers from ingress guards. Validates IP syntax, selects the trusted client address for existing limiters, and rejects public forwarding traffic from private-socket exemptions. No caller address is read for authenticated Tor ingress.Address held in request memory and anonymous Redis counter keys for 61 seconds. Existing limit families retain their lifetimes. No database or log address field.
src/hardening/middleware.tsExisting per-address bucket for anonymous public API reads and MCP messages; all Tor callers use onion. Counts against anon with the configured minute limit. Keyed requests, health and readiness, and internal callers are exempt. Redis failure permits the call and logs a fixed warning.Counter only; 61 seconds in Redis or until the memory limiter sweep. Never a prompt, key, header, secret or address in logs.
src/facilitator/routes.tsThe caller address bucket on every /facilitator route; over Tor the shared onion bucket. Counts requests in the facilitator's own per-address limiter; trusted proxy and onion rules apply.Raw address in the limiter key for 61 seconds in Redis, or until the memory limiter sweeps; never in a settlement, listing, receipt or log line.
src/api/network-hosts.tsThe caller address bucket on host signup and credential writes. Counts attempts through the existing per-address limiter; trusted proxy and onion rules apply.Raw address in the limiter key for 61 seconds in Redis, or until the memory limiter sweeps; never in the host row or application log.
src/network/waitlist.tsAddress bucket for a waitlist POST or DELETE; onion requests use the shared onion bucket. A secret-keyed HMAC of the address and current minute is passed to the existing limiter; onion stays the word onion.Only a minute-specific keyed digest and counter: 61 seconds in Redis, or up to six minutes without Redis until the memory limiter sweeps old windows. No raw IP or user agent, and no address-derived value in the waitlist table.
src/api/e2ee.tsThe address only for encrypted calls without a key outside the Oblivious HTTP gateway; over Tor the fixed onion bucket is used. Uses the existing blind-ip rate-limit family.Only the counter key, for 61 seconds; no address in a generation, receipt or log.
src/api/common.tsThe selected client address from the shared ingress helper: socket by default, the trusted hop counted from the right when TRUST_PROXY is on, or CF-Connecting-IP when the enabled origin lock secret is valid. Returned to a caller as the key of a per-address rate limit. Requests that arrived over Tor get the fixed word onion instead of an address (addressBucket).Not written to Postgres and not logged. It exists in Redis only as part of the rate-limit keys listed above, for at most an hour.
src/api/chat.tsThe caller's address, only for a call that carries no API key and did not arrive through the Oblivious HTTP gateway. Counted against ip:<address> (or blind-ip:<address> for a blind token).Only as the Redis rate-limit key.
src/api/embeddings.tsThe caller's address, only for a call without an API key. Counted against ip:<address> or blind-ip:<address>.Only as the Redis rate-limit key.
src/api/rerank.tsThe caller's address, only for a call without an API key. Counted against ip:<address> or blind-ip:<address>.Only as the Redis rate-limit key.
src/api/keys.tsThe caller's address when a key is created and when a wallet sign-in challenge is requested. Counted against newkey:<address> and wallet-login:<address>.Only as the Redis rate-limit keys.
src/api/teams.tsThe caller's address when joining a team or signing in to one with a passkey or wallet (no API key yet). Counted against team-auth:<address>.Only as the Redis rate-limit key.
src/api/paymaster.tsThe caller's address on a paymaster request. Counted against pm:<address>.Only as the Redis rate-limit key.
src/ohttp/gateway.tsThe caller's address, only for a request that did not come through an authenticated relay. A request through a relay is counted by the relay's key id instead. Counted against ohttp-gw:ip:<address>.Only as the Redis rate-limit key.
src/tlog/routes.tsThe submitter's address when a witness posts a cosignature. Counted against tlog-cosign:<address>.Only as the Redis rate-limit key.
src/api/creator-claims.tsThe caller's address when a creator claim is issued or verified. Handed to services/creators.ts as an address bucket.Only as the Redis rate-limit keys.
src/services/creators.tsThe address bucket it was given. Counted against claim-issue-ip:<address> and claim-verify-ip:<address>.Only as the Redis rate-limit keys.
src/api/responses.tsThe caller's address, so the internal chat call it makes on the caller's behalf is limited exactly as the caller's own call would be. Passed to the chat route as an in-process value (requestIP) and then handled as in src/api/chat.ts.Nothing beyond what src/api/chat.ts keeps.
src/ollama/routes.tsThe caller's address, so the internal chat or embeddings call it makes on the caller's behalf is limited exactly as the caller's own call would be. Passed to the chat or embeddings route as an in-process value (requestIP) and then handled as in src/api/chat.ts.Nothing beyond what src/api/chat.ts keeps.
src/onion/ingress.tsNothing. It deletes every header that names a client address (X-Forwarded-For, X-Real-IP, CF-Connecting-IP and others) from requests that arrived over Tor, before any route runs. Requests over Tor therefore carry no client address for a route, a limiter or a log line to use.Not applicable.
relay/src/relay.tsThe separate Oblivious HTTP relay (run by relay operators, not by the router) forwards a request's body to a gateway without any header, address or cookie of the client. The forwarded request is built from configuration and the body only. The relay's automated checks fail if its source logs a request or reads a client address.The relay keeps counters only: totals and fixed reason labels.
sidecar/src/headers.tsThe model-server sidecar inside a provider's enclave forwards only allow-listed headers, so a proxy header cannot carry a client address to the model server. Forwarded by allow-list, not deny-list; a header that names a network address is refused even in configuration.Not applicable.

Redis.

Redis holds rate-limit counters, the opt-in response cache, the sealed answers of x402 calls kept 24 hours for payment recovery, replay markers and the job queue. It is optional in development and required in production. Every key expires; the rate-limit keys below are the only place a caller's network address is used, and only for calls without an API key.

KeyWhat it is forPart of the keyLives for
idempotency:<sha256>src/idempotency/store.tsOpt-in retry protection for API-key inference calls with Idempotency-Key. The key hashes account id, API key hash and the caller's idempotency key. AES-256-GCM ciphertext under APP_SECRET and this scope contains a canonical request-body and endpoint hash, an ownership marker, and the final status, reply and receipt headers. The request body and raw idempotency key are not stored. Replies can echo request text. Stream replies are not retained; a completed marker keeps status and receipt headers instead. An unfinished call or failed retention leaves an in-progress marker; retries never run inference again while it remains. Redis failure refuses a new protected call before billing. No new database row or log field is added.A SHA-256 digest86,400 seconds (24 hours) from the first request; completion does not extend it. Redis deletes the entry at expiry. After expiry the same key starts a new billable call.
rl:anon:<caller address or onion>:<window start>src/hardening/middleware.tsAnonymous public API reads and MCP messages share one per-client minute counter. Valid API keys retain their existing limits. Tor shares a separate onion counter with ONION_POOL_MULTIPLIER times the limit. Authenticated in-process dispatch and direct private-network traffic without forwarding headers are exempt.The caller's network address61 seconds (the 60-second window plus one second)
rl:tools-call:<key hash>:<window start>src/tools/call.tsPaid tool calls per minute for one API key (60).A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:tools-list:<account id>:<window start>src/tools/routes.tsTool listings per hour for one account (20); each listing asks the tool for its quote.An account id3,601 seconds (the 3,600-second window plus one second)
rl:agent-pay:<key hash>:<window start>src/api/agent-pay.tsPayment confirmations and reads per minute for one agent key (60); each can read the chain.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:wallet-link:<account id>:<window start>src/api/linked-wallets.tsLimits wallet link challenges to thirty per account per minute.An account id61 seconds (the 60-second window plus one second)
rl:agent-certificate:<account id>:<window start>src/api/agent-certificates.tsRecord-certificate and track-record issuance attempts: five per minute per account, shared across standalone, profile and track-record issuance, its keys and router replicas. Contains only the account id and a counter; no certificate pseudonym, claims or stats.An account id61 seconds (the 60-second window plus one second)
rl:agent-replay:<caller key hash>:<window start>src/api/agents.tsRulebook replays (POST /api/v1/agents/:key_hash/replay), ten per minute per calling key. Contains only the caller's key hash and a counter; no draft, call or result.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:agent-feedback:<account id>:<window start>src/identity/routes.tsPaid-feedback submissions, thirty per minute per reviewing account. Contains only the account id and a counter.An account id61 seconds (the 60-second window plus one second)
rl:proof-pack:<key hash>:<window start>src/api/proof-pack.tsProof pack downloads, ten per minute per API key. Contains only the key hash and a counter.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:lane-report:<key hash>:<window start>src/api/lane-report.tsLane reports, thirty per minute per API key. Contains only the key hash and a counter.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:telegram-link:<action>:<account or Telegram user id>:<window start>src/telegram/linking.tsAccount link-code issuance (five per minute per account), code consumption (ten per minute per Telegram user) and approval callbacks (twenty per minute per Telegram user). Only identifiers and counters, no code or message text.A Telegram user id61 seconds (the 60-second window plus one second)
rl:facilitator:<caller address or onion>:<window start>src/facilitator/routes.tsFacilitator requests per caller address per minute (FACILITATOR_RPM, 120 by default), a bucket apart from the API's. The raw address is part of the key; over Tor the shared onion bucket is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:facilitator-payer:<payer wallet>:<window start>src/facilitator/routes.tsVerify and settle calls per payer wallet per minute, so one payer cannot drain the relay with tiny payments. Links calls by the public payer wallet.A wallet address61 seconds (the 60-second window plus one second)
rl:facilitator-seller:<payTo wallet>:<window start>src/facilitator/routes.tsVerify and settle calls per seller payTo wallet per minute.A wallet address61 seconds (the 60-second window plus one second)
rl:facilitator-listing:<payTo wallet>:<window start>src/facilitator/routes.tsSigned listing writes per payTo wallet per hour (FACILITATOR_LISTINGS_PER_HOUR).A wallet address3,601 seconds (the 3,600-second window plus one second)
rl:network-host-wallet:<operator wallet>:<window start>src/api/network-hosts.tsWallet-authenticated host signup and credential updates, three per minute per wallet. Links attempts by the public operator wallet.A wallet address61 seconds (the 60-second window plus one second)
rl:network-host-address:<caller address or onion>:<window start>src/api/network-hosts.tsHost signup and credential attempts, ten per minute per network address, with the existing scaled shared onion bucket. The raw address is temporarily part of the Redis key.The caller's network address61 seconds (the 60-second window plus one second)
rl:network-waitlist:<minute-keyed address digest or onion>:<window start>src/network/waitlist.tsWaitlist POST and DELETE requests, ten per minute per address; onion requests share the existing scaled onion bucket. A secret-keyed HMAC rotates every minute; no raw IP or user agent is stored. The digest still links requests within that minute.A SHA-256 digest61 seconds (the 60-second window plus one second)
rl:ip:<caller address>:<window start>src/api/chat.tsRequests per minute for a call that carries no API key. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:blind-ip:<caller address>:<window start>src/api/chat.tsRequests per minute for a call paid with a blind token. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:newkey:<caller address>:<window start>src/api/keys.tsNew API keys per hour. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address3,601 seconds (the 3,600-second window plus one second)
rl:wallet-login:<caller address>:<window start>src/api/keys.tsWallet sign-in challenges per minute. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:team-auth:<caller address>:<window start>src/api/teams.tsTeam join and sign-in attempts per minute (passkey or wallet), which need no API key. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:pm:<caller address>:<window start>src/api/paymaster.tsPaymaster requests per minute. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:ohttp-gw:ip:<caller address>:<window start>src/ohttp/gateway.tsOblivious HTTP gateway requests per minute from a client that did not come through an authenticated relay. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:ohttp-gw:relay:<relay key id>:<window start>src/ohttp/gateway.tsOblivious HTTP gateway requests per minute for one authenticated relay. It names the relay, not the clients behind it.Nothing personal61 seconds (the 60-second window plus one second)
rl:tlog-cosign:<caller address>:<window start>src/tlog/routes.tsTransparency-log cosignature submissions per minute. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address61 seconds (the 60-second window plus one second)
rl:claim-issue-ip:<caller address>:<window start>src/services/creators.tsCreator claim challenges per hour. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address3,601 seconds (the 3,600-second window plus one second)
rl:claim-verify-ip:<caller address>:<window start>src/services/creators.tsCreator claim verifications per hour. The caller's network address is part of the key. Over Tor the address is replaced by the word onion, so no address is used.The caller's network address3,601 seconds (the 3,600-second window plus one second)
rl:k:<key hash>:<window start>src/api/chat.tsRequests per minute for one API key. Keyed by the SHA-256 of the key; no address is read for a call that carries a key.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:kc:<key hash>:<window start>src/api/anthropic.tsRequests per minute for one API key on the Anthropic-compatible endpoint.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:kt:<key hash>:<window start>src/api/chat.tsTokens per minute for one API key: a running count of prompt tokens, not their text.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:skills-import:<key hash>:<window start>src/api/skills.tsSkill imports per hour for one API key (each import may fetch a repository and runs the scanner).A SHA-256 of an API key3,601 seconds (the 3,600-second window plus one second)
rl:blind:buy:<key hash>:<window start>src/blind/purchase.tsBlind-token purchases per minute for one API key.A SHA-256 of an API key61 seconds (the 60-second window plus one second)
rl:provider-applications:<window start>src/providers/application.tsProvider applications per minute, counted across all callers in one key. There is no per-caller part.Nothing personal61 seconds (the 60-second window plus one second)
rl:claim:<model id>:<window start>src/api/public.tsCreator claims per hour for one model.A model id3,601 seconds (the 3,600-second window plus one second)
rl:claim-issue:<model id>:<window start>src/services/creators.tsClaim challenges per hour for one model.A model id3,601 seconds (the 3,600-second window plus one second)
rl:claim-verify:<claim id>:<window start>src/services/creators.tsClaim verifications per hour for one claim.Nothing personal3,601 seconds (the 3,600-second window plus one second)
rl:telegram:<Telegram user id>:<window start>src/services/telegram.tsTelegram bot messages per minute for one Telegram user. The user id is a number Telegram assigns; the message text is not part of the key.A Telegram user id61 seconds (the 60-second window plus one second)
rl:readiness:<window start>src/services/readiness.tsThe readiness probe checks the limiter works by taking zero from a fixed key.Nothing personal61 seconds (the 60-second window plus one second)
cache:<sha256>src/gateway/cache.tsThe opt-in response cache (a request that sends cache.mode or the X-Anyroute-Cache header). It holds the answer to a request, so for as long as it lives this is a place answer text is kept: sealed with AES-256-GCM under a key derived from the router's APP_SECRET and the caller's own scope, so only that caller's identical request can read it back. The Redis key is a SHA-256 of the scope and the request, not the request.A SHA-256 digestIt is kept for the time-to-live the request asked for in cache.ttl: at most CACHE_TTL_S, which is 3,600 seconds unless the operator changed it, and also the default when the request names none.
walletauth:<sha256>src/api/auth.tsReplay protection for wallet-signed requests: a marker that a signature was already used. The key is a SHA-256 of the wallet address, the timestamp and the request's hash.A wallet address600 seconds
batch:<batch id>:in and batch:<batch id>:outsrc/services/batches.tsThe Batch API (POST /api/v1/batches). A batch's requests (:in) and its answers (:out), one field per line, each sealed with AES-256-GCM under a key derived from the router's APP_SECRET, the batch id and the hash of the key that sent it, so only that key's batch can read them back. They are kept here, never in the database, so the worker can run the lines and the key can fetch the results.Nothing personalThe sealed requests are deleted when the batch finishes; the sealed answers BATCH_RESULTS_TTL after that (86,400 seconds, 24 hours, unless the operator changed it). A batch that never finishes ends when its 24-hour completion window closes, so nothing outlives the window plus that time.
bull:anyroute-jobs-<group>:*src/services/jobs.tsThe background job queue (BullMQ) that makes exactly one replica run each recurring job. The job data is empty ({}), so no request or user data is in it; a finished job's result or failure message is kept for the last 100 completed and 100 failed jobs.Nothing personalRecurring job schedules stay while the router runs; only the most recent 100 completed and 100 failed jobs are kept.
x402paid:<sha256>src/pay/recovery.tsx402 payment recovery. The answer to a call paid with x402, kept so the payer can have it sent again, byte for byte, if it was lost on the way (PAYMENT-RECOVERY), instead of paying twice. It is sealed with AES-256-GCM under a key derived from the router's APP_SECRET, the payer, the authorization nonce and the request's hash, so only a recovery of that exact request by that payer can open it. The key is a SHA-256 of the payer and the nonce.A SHA-256 digest86,400 seconds (24 hours) from the answer, set when it is written; the x402-recovery-expire job also deletes it with its row. Calls not paid with x402 leave nothing here.

Without Redis (development): Without Redis (development) the same rate-limit counters live in the router process's memory and are removed once their window started more than five minutes ago (checked every minute). Nothing is written to disk.

Logs.

The router writes one JSON line per event to standard output (standard error for warnings and errors). A line is a time, a level, a fixed message and a few fields chosen at each call site. No call site writes a request or response body, a header, a client address, a query string or a prompt.

What a line can carry

  • A provisional deposit reversal logs its durable chain/lane/transaction/log identifier once when the reversing ledger entry commits. A separate durable check per reversal enters the existing operator alert notifier; notifications require an operator webhook and are at-least-once on delivery failure or a crash.
  • The time, the level and a message written in the code.
  • Anonymous limiter failure: fixed warning that a request was allowed; no exception, address, header, key or body.
  • Host slash dry-run intent: provider id, evidence commitment root, proposeSlash function name, whole-bond USDG amount, numeric contract reason, contract and chain id, bytes32 host id and delist flag. Logged once per evidence root; no signed bytes, key, raw quote or receipt envelope.
  • Sanctions refresh counts (distinct EVM entries, ignored formats and digital currency entries), publication date and source hash; screening skip/refusal reasons and provider ids. Freshness exceptions for previously paid addresses and refresh failures use fixed reason codes. No payout wallet or identity fields are added to these logs.
  • Identifiers and counts: provider ids, model ids, job names, hold and generation ids, epochs, block numbers, transaction hashes, hashed key ids and, on rare settlement and escrow events, an account id.
  • Wallet addresses of payers on pay-per-call and pay-with events (public on chain).
  • For an unhandled error: the path of the request without its query string, the error message and the first five lines of the stack.
  • Error messages from libraries and upstream services, each cut to 200 characters where a call site truncates them. Configured private chain RPC URLs, including paths and queries on the same host, are redacted before log emission; chain transport failures are redacted before callers truncate them.

What the code never passes to the logger

  • Client network addresses. No log call passes one; addresses are used for rate limits and direct private-network ingress checks. src/api/common.ts
  • Request or response bodies and prompts. The unhandled-error line takes the path and the error, not the body. src/app.ts
  • Request headers, cookies and API keys. The Telegram bot states the same rule for its own lines. src/services/telegram.ts
  • Query strings: only the pathname of a failing request is logged. src/app.ts

What this cannot promise

  • The text of an unexpected exception is logged as the library wrote it (src/app.ts unhandled error, src/lib/process-guard.ts uncaught exception, job failures). No code path puts request text into an error message on purpose, but only configured private chain RPC URLs are filtered, and a library error could quote a fragment of what it was parsing.
  • The hosting platform's own network layer sees connection addresses and may keep its own access logs. This inventory covers what the router's code records; it cannot describe the platform's logs.

Retention. The router does not rotate or store its logs: it writes them to standard output and the hosting platform keeps them under its own retention. No log retention is set in this repository. Format. JSON lines: { t, level, msg, ...fields }.

Other places data lives.

Approval context summaries

Help already authorized approvers decide with existing agent metadata.

Holds
No new storage, schema, Redis family, log field, address or request-body reader. Reads existing keys, ledger posted charges, current agent policies and autonomy, agent approvals requested since Monday UTC, retained duplicated events and key-rotation links. Builds optional approval_context lines in response memory for approval lists and inbox items the caller may decide; the same builder supplies linked Telegram approval messages and reminders. Telegram receives spend, caps, estimated spend if used, current work-hour status, weekly counts and duplicate or rotation notes when AGENT_APPROVAL_CONTEXT_ENABLED is enabled (default false), through existing notification preferences, quiet hours and approver guards. No prompts, tool arguments, source names or key hashes are added to the text.
Lives for
The summary is not saved by the router. Telegram retains delivered messages under its own policy. Existing source retention applies, including the 90-day agent-event pruning. Ordinary request text is still read by the router in memory.
src/agents/approval-context.ts

Agent status view

Compose existing agent metadata for the authenticated policy audience.

Holds
No new durable data. Reads current and inherited agent_policies Stop/timed Stop and work_hours, unexpired agent_approvals counts for this key, the existing per-key runway ledger/autonomy readers, and existing quiet-agent-alert kv settings plus the quiet worker’s ledger and Guard activity including session keys. Guard stops are derived only from saved action-restriction reason codes. No new table, column, Redis family, log field, body reader or address reader. Ordinary inference request text is still read in router memory.
Lives for
Response uses no-store. The browser holds the current status in component memory until refreshed, disconnected or unmounted; nothing is written to browser storage. Existing source retention is unchanged.
src/agents/status.ts

Key replacement links

Links retired and replacement account-backed keys while the existing expiry guard ends the old key's access. The account lock serializes rotation. Account-wide notification choices and linked Telegram chats continue on the same account.

Holds
key-rotation:<key hash> in kv stores from and to key hashes, at, grace_ends_at and history_key_hash. The replacement keeps the old key's settings, team membership and principal, current policy and saved policy_versions (including saved-by attribution and dates), agent approvers, quiet-alert hour choice and spend-alert rules including sealed webhook destinations. Usage, delivery history, existing agent approvals and spend records stay with the old key. Quiet-alert delivery state and spend-alert history restart for the replacement. The security-alerts event stores a sanitized Key rotated title and actor under its existing family, and uses the existing security_alerts notification type, preferences and quiet-hour delivery. Browser sign-ins, Telegram link credentials and attestation records are not cloned; there is no new address reader, Redis family or log field.
Lives for
Rotation links remain with key history until account data is removed. Copied settings use the existing tables' retention. The secret exists in router response memory and the browser's reveal state until dismissed; it is never persisted by the rotation interface.
src/key-rotation/store.ts

Independent agent settings copy

An explicit owner action makes a fresh key on the same account balance; it copies configuration, not runtime state.

Holds
Existing keys columns retain the new name, account and creating parent key hashes, scope, management rights, project, team, limits/reset, expiry, allowed models/IPs, rate limits, routing, guardrails, sealed tracing destination and auto top-up. Existing agent_policies and policy_versions keep the current readable rulebook including work_hours and saving caller hash. Existing agent_policy_events retains the readable source-name note. Existing kv agent-approvers:<new key hash> retains approval authority settings, quiet-agent-alert:<new key hash> retains the hour choice and new enable time with empty notices. Team creation audit records use the existing key.create fields. Agent duplicated titles use the existing security-alerts:event family and security_alerts channel preferences and Telegram quiet-hour delivery. No new Redis family, log field, table, column or address reader is added. Spend/history, approvals, disabled/Stop state, rotation links, Telegram credentials, browser sign-ins, principal bindings, public profiles, attestation and per-key spend-alert destinations are not copied. Account notification settings and account-linked Telegram deliveries still apply.
Lives for
Copied configuration follows existing table retention, until operator deletion; the new event log follows its existing 90-day pruning. The source-name note remains on that new event, not on saved revisions. A fresh secret exists in router response memory and browser component state until dismissal, switching agents, disconnecting or navigation; the duplication interface never writes it to browser storage. Ordinary inference request text is still read by the router in memory.
src/agent-duplicate/store.ts

Approval reminder claims

Remind currently authorized decision makers once before a pending agent approval expires; highlight its existing inbox row.

Holds
approval-nudged:<approval id> in kv stores the claim time and approval expiry time. Existing telegram-approval:<approval id>:<Telegram user id>:<link generation> values additionally store reminder_message_id, the reminder's Telegram message identifier; original and reminder buttons use the same single-use approval. notification-prefs:<account id> adds Inbox and Telegram booleans for approval_reminders, both on by default. No new table, column, Redis family, log field, address or body reader. Reminder text uses existing readable approval metadata: agent name, routing or action identifiers, amounts and rulebook summaries, never prompt or answer text. Telegram can read delivered details. The router reads ordinary request text in memory.
Lives for
APPROVAL_NUDGES_ENABLED defaults false. Enabled non-API workers inspect up to 100 eligible approvals each minute. Claims commit before outbound delivery, preventing repeats across concurrent workers. Each current linked recipient is attempted once, with current authority and channel settings checked under the link and account locks. Quiet hours never delay reminders. A crash after claiming, an unavailable destination or a failed send can lose a reminder; it is not retried. Claims are deleted after approval expiry by enabled ticks, and pause while off; decided claims remain until expiry. Existing Telegram notices are pruned by Telegram delivery after expiry or unlinking. Preferences remain until changed or removed. The inbox countdown appears only to current decision makers, only while pending and unexpired, and uses existing approval response fields. No expiry or approval consumption changes.
src/agents/approval-nudges.ts

Signed-in browser labels

Account management keys can list their own active wallet-issued browser keys in Settings. A single sign-out uses the existing key-disable path; signing out all others sends one disable request per listed other browser after one confirmation. The caller's key is excluded from that selection. There is no new worker, flag, table, column, Redis family or log field.

Holds
browser-session:<key hash> in kv keeps only a fixed browser-family and operating-system label derived from User-Agent at wallet sign-in. No full header, version, device model or network address is retained by this feature. Rows remain after sign-out because existing keys are disabled, not deleted; retained until operator deletion. Existing keys.created_at records sign-in, and keys.last_used records the last charged call, not browsing or every API request. Older wallet-issued root management keys have no browser label. Sub-keys, team keys and agent sessions are excluded from the browser list. User-Agent is read in memory during the existing wallet sign-in route. The browser holds session metadata and pending confirmation in component memory; no new browser storage. Existing sign-in and key-disable security alerts still apply.
Lives for
Labels remain until operator deletion. Disabled and expired keys disappear from the list. Signing out this browser clears its saved key after server confirmation. Bulk sign-out can partly succeed; failed rows remain visible for retry. Already-running requests may finish, and an owner can re-enable a disabled key using existing key management.
src/api/keys.ts

Quiet-agent settings, inbox notices and Telegram delivery

With QUIET_AGENT_ALERTS_ENABLED and agent rulebooks on, a five-minute non-API worker reads saved settings, current keys and Stop state, existing charged ledger timestamps (usage/tool_call/data_tool) and Guard decision timestamps, including agent session children in the same account. Disabled, expired and stopped keys are excluded. A keyset scan covers settings in pages of 100. Per-agent claims commit under the account lock before sending. A new activity timestamp re-arms the alert, with no writes on the call path. Free uncharged generations and rulebook previews do not count. The clock begins at the last recorded activity, or enable time when no activity is recorded. Resumed keys become eligible using the existing clock.

Holds
quiet-agent-alert:<key hash>: per-agent hours (null means off), enable timestamp, last claimed quiet-period activity timestamp, and newest 100 notices with random id, timestamp, readable agent-name title, hour window and last charged-call/Guard-decision time. Settings and the dedupe anchor persist until operator deletion. Enabled runs and changed settings prune notices older than 90 days; disabled cleanup pauses, while inbox reads hide expired notices. Deleted keys leave inaccessible settings until operator deletion. No rulebook field, table, column, Redis family, address reader or log field is added. The account inbox exposes these notices only to management keys and team owner/admin principals outside sessions, scoped by current account/team ownership. The browser keeps settings and save status in component memory only. Agent names enter readable notice titles and Telegram messages; user-chosen names can contain personal text. No inference prompt, answer, action target, Guard details, wallet address or API secret is read by this feature.
Lives for
History is bounded to 100 per agent and 90 days when cleanup runs. Settings and notified_for remain even while off. Saving or changing the choice preserves the last claimed activity timestamp; only later activity re-arms a previously reported period. Telegram uses existing linkedAlertTargets/sendLinkedAlert and their current principal checks and unlink lock. One attempt per eligible link after each saved claim; a crash or failed send can lose delivery with no retry. No message id or send-result metadata is added.
src/agents/quiet-alerts.ts

Account security changes and delivery cursor in kv

With SECURITY_ALERTS_ENABLED, existing key rows, agent policy events and team audit writers record security changes, including those made by the signed-in key. A thirty-second worker claims pending events once, adds inbox items and attempts Telegram delivery through the existing linked-alert helper. Management keys see their account; team owners and administrators see only their team; ordinary and session keys see no security items. Account preferences default on while the feature is enabled.

Holds
security-alerts:event:<change id, policy event id, or team id and sequence> holds account id, nullable team id, inbox-arrival timestamp (recording time while pending), readable title and pending/inbox/muted state. Titles contain sanitized key and team names, management status, the kind of change and the acting key name. The request middleware holds only a digest of the presented Bearer key in an asynchronous request scope to correlate the already-authenticated team audit writer with its exact acting key; no credential is retained. Team audit entries authenticated by wallet or passkey name that member type instead of inventing a key. Wallet sign-in reads the already-verified account wallet in memory, keeping only its first six and last four characters in a sign-in title. Full wallet addresses, key secrets, prompt text, policy contents, stop reasons and Telegram messages are not copied. security-alerts:cursor keeps a processed-event count and lock; per-event states are the durable cursor so late commits and equal timestamps remain eligible. security-alerts:preference:<account id> keeps the enabled boolean. Telegram can read the security titles and key names it receives. Unlinked members receive no later alert, including their unlink notice; other eligible links may receive it.
Lives for
Claimed and muted event rows are removed after ninety days by enabled worker runs; pending events remain until claimed. Flag off pauses recording, delivery, inbox projection and cleanup. Events from before recording was enabled are not reconstructed. Preference and cursor rows remain until removed. Claims commit before one send attempt per eligible link: worker crashes, failed and ambiguous sends can leave an inbox item without Telegram delivery; sends are not retried. Key change hooks use the existing write boundaries; changes whose key write commits but notice write fails can miss a notice. Policy, team audit and Telegram notices commit with their source transaction. No new database table/column, Redis family or log field; the settings route is the only new request-body reader.
src/security-alerts/worker.ts

Account notification settings and encrypted quiet-hour queue

One account page controls Inbox and Telegram for approvals, agent alerts, credited deposits, low balance, weekly summaries, security changes, quiet agents, model rate changes, project budgets, scheduled results and approval reminders. Underlying activity and approval records are retained. Feature flags and existing feature choices still apply. Inbox is filtered at read time; weekly Inbox, off by default, projects the latest completed week from existing records for management keys.

Holds
notification-prefs:<account id> stores channel booleans and nullable from_utc/to_utc daily clocks. Weekly Telegram reads and writes only existing telegram-link weekly_summary_opted_in columns, and security Inbox/Telegram use the existing security-alerts:preference value with enabled as their aggregate for recording; the older security switch replaces that value and controls both. notification-quiet:<random id> stores account id, Telegram user id and link generation, source and principal key hashes, team id and management snapshot, notice category, due/creation times, a legacy-link marker and text encrypted under APP_SECRET. Text includes notice names and amounts, and can include scheduled answer previews. The router can decrypt these previews; Telegram can read delivered messages. No inference credential, new Redis key, address reader or log field is added. Browser component memory holds the settings and current local clock conversion; nothing new enters browser storage.
Lives for
Preferences remain until changed or removed. NOTIFICATION_QUIET_HOURS_ENABLED defaults false: only the enabled minute worker queues and flushes delayed Telegram notices. Approvals and approval reminders are never queued. Each tick reads at most 500 queue entries and sends one bounded-excerpt bundle per recipient and generation; larger backlogs can yield later bundles. Successful delivery removes entries; muted, revoked, unlinked or changed-scope entries are discarded. Failed sends remain for a later attempt. Entries older than seven days are discarded by enabled ticks; flag off pauses queue delivery and cleanup. Delivery can repeat after Telegram accepts a message before transaction commit. The worker revalidates current link, role, team, management status, source key ownership and scheduled-result owner rights. A source feature switched off pauses its queued notices until enabled or expired. Existing sender success counters treat skipped channels or durable queue acceptance as acknowledged delivery. Weekly last_sent_week is marked when a summary enters the queue; a later discarded summary is not resent. Daily clocks are saved in UTC using the device's current offset; saving again is needed after clock or time-zone changes. Future Telegram links retain the existing weekly opt-in default.
src/notifications/telegram.ts

Watching settings in browser memory

J180: read-only composition of existing account notification, model watch, agent rulebook, quiet-agent, project budget, balance threshold and schedule GET readers. Each reader keeps its existing authorization and feature guards.

Holds
Existing responses pass through browser memory, including names, public model ids, key hashes, inherited alert rules, monthly budgets, balance thresholds, cadence, maximum run costs and channel preferences. The existing schedules list also returns decrypted prompt text; the composition discards it and retains only active schedules' names, ids, cadence, UTC clock and maximum cost for display. Summary rows and per-reader failure states are held only in React component memory. No new database table or column, Redis key family, application log field, body/address reader, browser storage, outbound notice or server snapshot is added. The router still reads ordinary inference requests in memory.
Lives for
Component state is replaced on refresh and cleared on account change or unmount. In-flight requests are aborted on change or unmount; no durable copy is created by this view. Existing source storage and retention are unchanged.
web/lib/watching.js

Retry protection without Redis

The same opt-in retry guard and encrypted reply as Redis, scoped to this router process only. Up to 5,000 live entries; a full store refuses new protected calls rather than evicting a guard.

Holds
AES-256-GCM sealed request hash, ownership marker, status, reply and receipt headers. No raw key, prompt or address. Replies may contain request text.
Lives for
24 hours from the first request. A timer deletes ciphertext at expiry, and lookups also sweep expired entries. Process restart loses entries. Without Redis, retries routed to another process are not protected.
src/idempotency/store.ts

Scheduled result notifications and browser view

Authorized owners read their saved schedules and results. The existing inbox shows one item per finished retained run. Linked Telegram delivery receives the name, first 300 reply characters or a failure code, and an authenticated result link.

Holds
Decrypted prompt and reply text in router and browser memory, and a reply excerpt in Telegram, which can read and retain it under its own policy. The browser does not persist scheduled prompt or reply text. No new Redis key family or application log field.
Lives for
Router and browser memory lasts for the request or open page. Telegram follows its own retention policy; deleting a schedule does not erase delivered Telegram messages. Saved database content and its inbox item disappear with the schedule; billing records and backups retain their existing policies.
src/schedules/worker.ts

Model price snapshots and account price notices in kv

With PRICE_NOTICES_ENABLED, an hourly worker compares published catalogue input and output token rates with its previous snapshot. Only changes of at least one percent target accounts with an attributed generation for that model in the last thirty days. The first snapshot and models without funded endpoints produce no notice. Snapshot, account inbox items and daily caps commit together under a row lock. GET /api/v1/inbox returns these account-wide items only to management keys, excluding session keys and team administrators.

Holds
kv key price-notices:snapshot holds model ids, public model names and integer pico-USD input/output rates. price-notices:daily:<SHA-256 of account id>:<UTC date> holds account id, date, up to five notice ids, timestamps, model ids, fixed price-change titles and the count of grouped changes. The first four changes are individual items; the fifth groups the rest, including later checks that day. Existing generations account_id, model_id and ts are read; no new usage tracking, prompt, answer, wallet address or request body is added. Authorized management Telegram links receive one send attempt per newly created item through the existing delivery helper. Telegram can read model names and rates. Later grouped-count updates are retained in the inbox without another Telegram send.
Lives for
The latest snapshot is overwritten each run. Daily rows older than thirty UTC days are deleted by enabled runs; while disabled cleanup pauses. Claim-before-send avoids duplicate attempts across retries and workers, but a crash or failed outbound attempt can leave an inbox item without a Telegram message. No Telegram message id or delivery result is stored. No new table, column, Redis key family, body/address reader or log field.
src/catalog/price-notices.ts

Operator capacity and daily counts

The operator-only GET /trpc/rush reads daily aggregate milestones over at most 90 UTC days. New wallet sign-ins mean wallet accounts created with a management key at the same transaction timestamp; an account created earlier by a deposit is excluded. First credited deposits mean the first positive deposit, stock_deposit, anyr_deposit or usdg_deposit ledger row per account. First successful calls mean the first signed generation per account that was not cancelled and did not finish with an error. Earlier retained rows are checked to exclude repeats; deleted historical records cannot be reconstructed. No per-account rows leave these queries.

Holds
Daily counts and dates; latest upstream USD balances, check states and hold expiry times on the operator surface only. In memory the enabled monitor reads the existing encrypted provider credential and configured headers to authenticate a documented balance check; neither credential nor upstream response text is retained in the new state or logs. API replicas refresh balances and temporary holds on health flushes; catalogue requests also refresh them before reading the cache, with starts at least five seconds apart per process. Both catalogue routes share one in-flight refresh promise and its monotonic start time in memory; failed reads preserve the previous availability state. Changed exhausted state invalidates that process’s catalogue cache. The catalogue cache holds up to 64 public catalogue JSON variants and 64 in-flight computations, keyed only by the four supported public catalogue filters. It contains catalogue metadata, prices, capabilities and provider evidence, never inference text or caller addresses. No new table, column or Redis family.
Lives for
Aggregate responses discarded after delivery with no-store. Catalogue JSON expires after 30 seconds, successful catalogue sync or an observed exhausted-state change; process memory disappears on exit. Failure-based routing holds expire after five minutes; exhausted balance readings persist until a reading exceeds the configured threshold. Balance readings and alert delivery times are overwritten in place and remain until operator deletion. Existing source retention applies.
src/rush/funnel.ts

Public tool catalog in the router's memory

When TOOLS_PUBLIC_CATALOG_URL is set, the router fetches that public x402 catalog through the egress guard to answer tool searches.

Holds
Public tool names, summaries, addresses, prices and payTo wallets. No caller data.
Lives for
TOOLS_PUBLIC_CATALOG_TTL_S (900 seconds by default); a failed refresh keeps the previous copy; lost on restart.
src/tools/catalog.ts

Signed account event delivery

When WEBHOOK_SIGNING_ENABLED is enabled, a minute worker reads at most 50 destinations, one 100-row activity page per destination, and sends at most 100 due notices per tick. Activity readers retain account, key, team and wallet-party guards. It delivers metadata references, fixed types/statuses and timestamps; existing Spend Watch and agent delivery retain their original alert fields. Signing covers exact wire JSON bytes plus a timestamp. The signed body binds event_id to the header. Secrets use the existing APP_SECRET encryption helper. Legacy URLs remain unsigned until rotation. Revocation stops future deliveries; an already in-flight request can finish. The disabled flag retains original alert delivery without signing, imports or worker writes.

Holds
Decrypted URLs and signing secrets enter router process memory only for delivery or credential issuance. Account wallet and host operator addresses are read by the status-write hook to match operated hosts. No prompt/answer is added to deliveries, and no arbitrary response or transport error text is logged. The browser holds a newly revealed signing secret in component memory until dismissed, disconnected or navigation; it is not written to browser storage.
Lives for
Activity discovery begins at destination creation, uses five minutes of overlap and durable pagination, and can miss source rows removed before discovery or commits delayed beyond the overlap. Approval requests/decisions and operated host status changes enqueue references in the transaction that records the change, so changes between worker ticks are retained. Approval references are approval ids. Direct database writes outside the router do not generate these notices. Delivery can repeat after a crash before result persistence: receivers must verify exact bytes with a five-minute timestamp tolerance and atomically deduplicate event ids. Delivery metadata is retained for 90 days; the API shows 100 attempts. Three attempts per event, five minutes apart. Owner-requested connectivity notices are limited to one per destination per minute.
src/webhooks/worker.ts

Make-good refund decisions

With MAKEGOOD_ENABLED (off by default), the call finaliser, the all-providers-failed path and the JSON repair check record a pending candidate when a call meets a refund rule; the hourly settlement job issues it as a ledger line linked to the generation, a signed refund receipt naming the original receipt, a refund.issued webhook reference and, for a network host that caused it, review-only host slashing evidence. Calls paid on-chain per call are refunded by the makegood-payouts job from MAKEGOOD_REFUND_PRIVATE_KEY, which refuses to run without that key.

Holds
Rule decisions use token counts, prices, provider ids, error classes, lane and attestation results already in router memory. The JSON rule parses the repair answer in memory only to decide whether it is JSON; the text is not stored. Refund rows keep amounts, fixed codes, ids, transaction hashes and the payer wallet address for on-chain refunds. The treasury key stays in worker memory and is never logged or stored; signed transfers are stored encrypted.
Lives for
Refund rows and transfers are kept with the ledger (no automatic deletion). Webhook references follow the webhook delivery retention. No new Redis family or log field carries request text or a caller address.
src/services/makegood.ts

Liveness probes to listed agent endpoints

When AGENT_IDENTITY_ENABLED is on, the agent-liveness job sends one GET a day to each listed profile's owner-declared HTTPS endpoint, to a public address only (no redirects, a ten-second timeout by default), with a fixed Anyroute-Liveness user agent and no credentials, and does not read the response body.

Holds
The status code, latency and a fixed failure code in agent_liveness with a signed probe receipt. The endpoint's operator sees the router's network address and the request.
Lives for
Each probe replaces the previous result. Nothing is kept in memory between runs.
src/identity/liveness.ts

ERC-8004 registries on Robinhood Chain

An identity registration (owner-sent, or sent by the isolated registrar worker) writes a public, permanent record: the registration file URL, a metadata entry pointing at the router's receipt keys, and the holding wallet. Optional feedback and validation calldata the router prepares is sent only by the reviewer's or validator's own wallet.

Holds
Public chain data: agent ids, registration URLs, wallets, scores, tags and document hashes. No key hash, account id, receipt id or amount is placed in calldata the router prepares.
Lives for
Permanent on chain; opting out stops the router serving the registration file and links, but cannot remove a sent transaction.
src/identity/erc8004.ts

Track-record Merkle trees in memory

Proof requests rebuild a certificate's tree from the router's generation records and keep at most 32 trees in process memory.

Holds
Receipt anchor leaves (hashes) and generation ids of the certified key's counted receipts.
Lives for
Until evicted by newer trees or the process exits.
src/identity/track-record.ts

Account activity response in memory

GET /api/v1/activity merges existing generations, ledger entries, agent approvals, policy events, the retained agent alert feed, spending alert history, escrow deposit statuses, key auto top-up records and wallet-party agreement events. Each source and response is limited to 100 rows. Ordinary and session keys read only their own key records; management and owner/admin keys read account records. Non-management administrators retain the agent routes' team boundary. Key, model, project, lane, missing-metadata and date filters further restrict results. J182: opt-in basis=charges reads negative usage/tool_call/data_tool ledger entries at settlement time with the same account/key/session call visibility, optionally restricted to statement usage or rulebook charge kinds. It joins existing generation ids, key/account stamps and recorded receipt signatures to expose a call receipt only when present; missing models and receipts stay missing. Spending alerts keep their existing management-or-own-key boundary. CSV and JSON contain the same selected page; a cursor continues the filtered range.

Holds
Times, fixed event titles, exact signed USDG amounts, model and provider ids, recorded lanes, key names or existing short labels, receipt references, status and approval limits. It reads account wallet addresses and existing on-chain payer/payee and deposit sender addresses to select matching records, without returning those addresses. Agreement amounts describe wallet escrow movements, not router balance changes. It reads only model and lane from stored approval/policy intents and only lane from receipts; no request body, agreement evidence, delivery targets, key secrets or full key hashes enter the response. Oracle-only events require an indexed ruling linking their key to the agreement; until then they remain in the agreement view.
Lives for
Discarded after the response; cache-control is no-store. No new durable storage, logs or Redis keys. Downloads stay on the caller's device. Existing source retention still applies; the agent alert feed retains at most 100 records for 90 days and spending alerts retain up to 20 firings per rule.
src/activity/trace.ts

Signed monthly statements in memory

With STATEMENTS_ENABLED (off by default), GET /api/v1/statements/:month aggregates the existing ledger in one SQL snapshot and signs canonical JSON with the existing receipt signer. Management and owner/admin keys see account totals; ordinary and session keys see only movements attributed to their key. The account creation month sets the earliest readable month. UTC month bounds exclude the next month; the current month ends at the read time.

Holds
Account creation date, key hashes and existing names or labels, exact pico-USDG ledger totals converted to decimal strings, movement kinds, model ids and lanes from linked generation receipts, call counts and reconciliation results. Reads only lane from receipt JSON, no request text, wallet or network addresses, key secrets, ledger descriptions or receipt content hashes. Unrecorded group values are null. Key-only balances are attributed ledger sums rather than the shared account balance. Separate fee entries are distinguished from fees embedded in usage. Call time and settlement time can differ; external payments are outside the router balance ledger.
Lives for
Discarded after response with cache-control no-store. No new tables, columns, Redis keys or log fields. Signing uses existing receipt key storage and retention. Downloaded JSON and printed statements remain on the caller's device; the signature is the router's statement, not an independent ledger audit.
src/statements/read.ts

Account export on the caller's device

The account shell builds a JSON bundle in the browser by paging existing authenticated read APIs. It includes accessible account and key metadata, rulebooks, policy events, sessions, approvals, activity, signed statements, wallet-party agreements and owned profile settings. A manifest describes included sections, access failures, retention and omitted records; this is not a complete storage dump.

Holds
Existing endpoint response data, including key hashes, wallet metadata or addresses where the endpoints expose them, policies and readable policy-event intents, session metadata, approval intents, activity and agreement projection records, owned profile settings and signed statements. Key secrets and credential-shaped fields are stripped. Chat history, private files, saved content, raw statement ledger, agreement evidence and dispute details are outside this export. Approvals are limited by the existing endpoint to 100 per stored status. Agent events and profiles retain per-agent access errors in the bundle.
Lives for
Kept in browser memory during export, then downloaded as JSON to the caller's device. Cancel stops requests and prevents download. No new server-side bulk endpoint, persistence or logs. Existing endpoint and source retention apply; APIs are read sequentially, not in one database snapshot.
web/lib/account-export.js

User-entered statement business identity in kv

Account management keys optionally save business identity for a Billed to block on statements. Anyroute can read these fields and does not verify them. They are outside the signed statement payload; changing them never changes what is signed.

Holds
business-details:<account id> holds business_name, multi-line address, tax_id and reference in kv.value, linked to the account id in kv.key, plus kv.updated_at. The router reads these optional settings in memory. Statement reads with business_details=true add them beside payload, alg, key_id and sig; default statement responses are unchanged. The browser uses these current fields, including for earlier months, for the unsigned Billed to block, CSV and print/PDF. Signed JSON downloads omit them. There is no billing email field; the reference rejects email addresses, but free-text business identity fields can contain personal information supplied by the owner.
Lives for
Kept until replaced or deleted, without automatic expiry. Delete in Settings > Statements sends PUT with an empty object and removes the kv row; it does not remove earlier backups or exports on the caller's device. Browser memory holds the form and loaded statement details until navigation; no new browser storage. No new table, column, Redis family or log field.
src/statements/business-details.ts

Proof pack in memory

With STATEMENTS_ENABLED (off by default), GET /api/v1/proof-pack?from=&to= builds one JSON file for at most 31 UTC days: the calls Activity lists for the key's scope with their stored signed receipts and Merkle paths, issued refund receipts, the signed monthly statements covering the range, the published receipt keys, a lane report of the listed calls and a manifest signed with the existing receipt signer. Management and owner/admin keys read the account; ordinary and session keys read only their own key. A range with more than 2,000 calls, or calls under more than 200 anchors, is split into parts with a cursor.

Holds
Generation ids, call times, key hashes, model and provider ids, mode, lane, exact charged amounts, the stored signed receipt payloads and COSE claims (request and response hashes, token counts or buckets, amounts, attestation references, and the payer key hash or per-call payer wallet and payment transaction a receipt was signed with), anchor roots, indexes and Merkle paths, refund receipts with their stored evidence and any on-chain refund wallet, signed statements, public receipt keys and the manifest of listed receipt ids and leaves. No request or answer text, key secrets or network addresses; recorded provider attempts are not read.
Lives for
Discarded after the response with cache-control no-store. No new tables, columns or log fields; one rate-limit counter per key. Downloaded files remain on the caller's device. Existing receipt, refund, ledger and anchor retention apply.
src/proof-pack/read.ts

Lane report in memory

With STATEMENTS_ENABLED (off by default), GET /api/v1/lane-report?from=&to= groups the calls Activity lists for the key's scope over at most 31 UTC days by the lane each receipt records, provider and model, and returns calls and charged spend per lane, the share on the attested and unlinkable lanes, and per provider and model rows for those lanes with links to the provider's public attestation record. Management and owner/admin keys read the account; ordinary and session keys read only their own key. The proof pack carries the same summary for the calls in each file.

Holds
Lane names read from receipt JSON, provider and model ids, call counts, exact charged amounts, the range and the key hash for key-scoped reports. No request or answer text, receipt hashes, key secrets or network addresses.
Lives for
Discarded after the response with cache-control no-store. No new tables, columns or log fields; one rate-limit counter per key.
src/lane-report/read.ts

Spend insights response in memory

GET /api/v1/insights aggregates existing call charges and ledger refunds over at most 92 days, with UTC day or Monday-week buckets. It uses Activity's account-or-own-key access, including session restrictions. Each model/key breakdown includes the first 100 by cost or calls; totals include all visible records. Refunds count when posted; linked refunds use their generation's model and lane. Unlinked refunds have unknown model/lane.

Holds
Exact decimal charges, refunds, net spending, call and token counts, model ids, recorded lanes/disclosure classes, existing key names/short labels, and historical hardware-check counts from signed v1 receipts. Missing evidence and cache calls do not count as proven. An average includes its exact numerator/denominator and a decimal truncated to 12 places. It reads key hashes internally for grouping but returns response-local key numbers. Price comparisons read live catalog capabilities, endpoint lane/disclosure availability and token/request prices at the observed input/output mix; estimates exclude royalties, account fees, cache discounts, reasoning/media/search charges and refunds. No request text, wallet addresses, key secrets, new logs, tables, columns or Redis keys are read or written.
Lives for
Discarded after the response; cache-control is no-store. Existing source retention applies. No durable storage added.
src/insights/read.ts

Savings finder response in memory

GET /api/v1/account/savings aggregates only the caller's visible charged generation records over 1 to 30 rolling days. Uses Activity's account-or-own-key access, including sessions, team roles and deleted-key account stamps. No new durable storage.

Holds
Model identifiers, call and input/output token totals, largest recorded context/output counts, actual charged pico amounts, safe billing-mode/cache/reasoning flags, and existing receipt lane/disclosure codes only. Reads current catalogue modalities, endpoint supported parameters, context/output limits, eligibility, health, lanes, disclosure and token/request rates. Historical used abilities are not retained: all declared source abilities, parameters and full context are preserved conservatively; missing metadata and unsafe billing records omit a model. Candidate must be cheaper than both current source rates and actual charges. Estimates exclude refunds, royalties, account fees and extra charges; no equal quality claim. No messages, bodies, addresses, key secrets, new tables, columns, logs or Redis keys are read or written. Ordinary inference still reads request text in router memory.
Lives for
Response discarded after completion, cache-control no-store. Browser state cleared on key change or leaving Insights; no browser persistence. Source retention unchanged.
src/savings/read.ts

Your view of a model response in memory

J178: GET /api/v1/account/models/:id/summary composes existing Insights, reliability, savings and price notice readers. Uses Activity account-or-own-key visibility including sessions and deleted-key account stamps. Insights filters the model before aggregation and group limits. No new storage or background work.

Holds
Public model id; 30-day exact decimal call charges, posted refunds and net spend with call counts; seven-day recorded completion counts and success percentage; existing conservative savings suggestion and current catalogue rates/abilities; latest matching price notice time/title among the existing latest 101 retained notices over 30 days. Notices require a non-session management key and enabled inbox preference and feature switch. The panel reuses existing watch and comparison controls and their guards/storage. No new notices, messages, body or address readers, key secrets, tables, columns, log fields or Redis families. Ordinary inference still reads request text in router memory.
Lives for
No-store HTTP response; browser component memory cleared on key/model change or leaving the page. Signed-out visitors make no summary request and render no panel. Existing source retention unchanged.
src/account/model-summary.ts

Account reliability response in memory

GET /api/v1/account/reliability aggregates up to seven rolling days of existing generations and denied inference agent policy decisions. It uses Activity's account-or-own-key visibility including sessions, deleted-key account stamps and the agent team boundary. Agent decisions are omitted while agent policies are off.

Holds
Model identifiers; counts of recorded calls, non-cancelled/non-error completions, route records marked as fallback, and denied inference decisions grouped by lane, budget or other rulebook reasons; recorded streamed first-token latency and generation total time with interpolated median and p95. It reads only route presence/reason from existing receipt JSON and model/kind and reason codes from policy JSON, never messages, request text, arbitrary error strings, hashes, wallet addresses or key secrets. Percentages cover recorded calls or recorded routes only; pre-generation failures and general lane/balance refusals are missing. Decision counts are not unique requests and reason groups can overlap. No tables, columns, logs or Redis keys are added.
Lives for
Discarded after the response; cache-control is no-store. Browser state lasts until refresh, key change or leaving the view; no report persistence. Existing source retention applies.
src/reliability/read.ts

Market-data tool readings in memory

When DATA_TOOLS_ENABLED is on, GET /api/v1/data/stock/:symbol and /actions read a Stock Token's Chainlink feed and its uiMultiplier, newUIMultiplier, effectiveAt, paused and oraclePaused views from Robinhood Chain; GET /api/v1/data/ipx/:class reuses the inference price index snapshot. A paid call is charged once, after the reading passed its checks: a prepaid key through the ordinary hold and ledger (kind data_tool), a keyless caller through the existing per-call payment, whose quote binds the method and path.

Holds
Public chain readings per token (feed answer, decimals, update time, multiplier values, pause flags) and the read time, and the public index snapshot per class and hour. Nothing about the caller is kept here; the charge is the existing ledger line and, for per-call payments, the existing quote row with the payer's wallet address. No request text: these are GET requests without a body.
Lives for
A token reading is reused for 15 seconds and an index snapshot for 60 seconds; both are lost when the router instance exits.
src/data-tools/stock.ts

Decision tags in signed receipts

When DECISION_TAGS_ENABLED is on, a chat or completion call may send X-Anyroute-Decision-Tag: a SHA-256 digest the caller computed, for example of an order intent. The router signs it into that call's v1 and v2 receipts as decision_tag, so the caller can later show which model answered before a decision. A malformed tag is refused before anything is charged, and the unlinkable lane refuses a tag because a reused tag joins calls together. An Agent Guard decision whose details_sha256 equals a tag names the same agent's tagged calls as informed_by, and a proof pack lists the tags its receipts carry; both read the stored receipts and store nothing new.

Holds
The 64-hex digest as sent, inside the generation's stored receipt and receipt_v2. Never the intent itself, which the router never receives.
Lives for
Kept with the generation record and its receipt, under their existing retention.
src/receipts/decision-tag.ts

Account inbox response and browser seen time

GET /api/v1/inbox reuses Activity's account, ordinary-key, session-key, team, spending-alert and wallet-party agreement visibility. It merges retained alerts, posted deposit credits, key auto top-ups, indexed disputes/rulings and, when AGENT_PAY_ENABLED, confirmed agent payments sent by this account's keys or received by a published wallet of its agents, since the browser's seen time, with unexpired pending approvals regardless of that time. It reads up to 100 records per activity kind and up to 100 pending approvals and operated host records; capped indicates a source may have more. The count describes returned items, not an unbounded total. Owner/admin access follows the existing agent decision endpoint, which remains the sole approval writer. POST /api/v1/inbox/seen authenticates the key and echoes a validated displayed-snapshot timestamp; it does not read a body or persist state.

Holds
Fixed event titles, timestamps, recorded statuses, signed credited amounts, paid USDG amounts of agent payments, key names, approval ids, expiry and spending limits. Stored approval intents are read and projected to kind, model, lane, tool names, estimated cost and output limits; no request text or Telegram messages are added. Account wallet and provider operator addresses are read in memory to match this account's operated network hosts, without returning addresses or private provider configuration. Host items show current status at the provider record's update time, which can also change for reasons other than status; no transition history is inferred. A secret-keyed visibility digest separates account, team, management and ordinary/session key bookmarks, without exposing account ids or full key hashes.
Lives for
Responses live in memory and use cache-control no-store. The browser stores only a last-seen timestamp under anyroute-inbox-seen-v1:<visibility digest> in local storage until browser data is cleared; items and API keys are not stored there. Bookmarks do not sync between browsers. The unchanged API counts pending approvals until decided or expired. H173: the browser treats approvals at or before its bookmark as read while keeping them highlighted for a decision. Optional kinds filtering and six group counts are computed only from the authorized bounded response in request memory. Selected kinds stay in the page URL and browser history; an undo token holds only the visibility digest, previous/written timestamps and a ten-second deadline in component memory. Undo restores the matching browser bookmark only if not superseded. No additional storage family, body reader or address reader. No new database table/column, Redis key family, log field or Telegram message storage. Existing source retention still applies.
src/inbox/read.ts

Network host routing evidence in memory

When NETWORK_HOSTS_ENABLED is on, routing uses existing signed generation records, health probes and attestation outcomes to limit admitted hosts during probation and exclude unavailable hosts.

Holds
Provider ids, probation deadlines, aggregate attested success and recent outcome counts, fresh canonical active bond base units matched to the host id and operator wallet, probe availability and median latency, the latest attestation failure flag and refresh time. No request text or caller address. Successful network probes also record latency in the existing health table.
Lives for
Rebuilt by health refreshes, including idle flushes; evidence older than 120 seconds is refused. Failed refreshes clear the evidence. Lost when the router instance is released or exits.
src/network/routing.ts

Host registration on the operator’s computer

The join command reads a dedicated operator wallet key from the explicitly selected file or environment variable and signs the router’s existing wallet-auth message. It optionally reads the host-generated sidecar API key from an explicitly selected UTF-8 file or environment variable, trims and validates it, and checks POSIX file read permissions. It submits host name, sidecar endpoint, payout address, model ids and optional contact to the selected router. After successful signup, or in credential-only mode, it sends the sidecar API key and provider id over HTTPS to the router’s existing wallet-authenticated credential endpoint; an explicitly selected loopback router may use HTTP. Status polling sends a provider id without a wallet key. It sends no inference text and no transactions.

Holds
The operator’s existing wallet and sidecar key files or environment variables are left in place. The command reads the key and signup fields in process memory; the wallet address, timestamp and signature leave as authentication. The sidecar API key leaves in the credential request body and is stored in the router’s existing AES-GCM encrypted provider-key column; the router can decrypt it to call the sidecar. The command writes no key or signup file, logs no key and redacts loaded sidecar credentials (including JSON-escaped forms) and wallet-key-shaped output. Dry runs read neither key and show a redacted credential body, with the signup-assigned provider id still unknown. File read buffers are cleared, but JavaScript strings and signing-library memory cannot be reliably erased. Signup details and resulting status are printed to the operator’s terminal; the operator controls terminal retention. The router still reads inference request text in memory on every lane.
Lives for
Process memory lasts until the command exits. The key source and terminal history remain under the operator’s control. Router storage for host admission is described by the admission endpoint’s inventory when available.
scripts/network-join.ts

Public network statistics in router memory

When NETWORK_STATS_ENABLED is on, cache read-only network statistics and share one refresh among concurrent readers.

Holds
Only the public aggregate response: snapshot time, host status counts, fresh admitted host count, distinct eligible model IDs, 100,000-token ranges from retained public-lane generation counts, indexer total/active USDG bonds with freshness and block, waitlist counts and published policy version. Private-lane generation rows are excluded; existing router-wide DP releases cannot identify network-host totals. Database query results and public admission evidence are read temporarily to form the snapshot. The host query selects no credentials, operator wallets or contact fields. The existing bond adapter reads public on-chain projection metadata, which can include operator addresses; only aggregate amounts, freshness and indexed block enter this cache. No inference text or caller address is read. No new database rows, Redis keys or log fields.
Lives for
Cache freshness ends 30 seconds after refresh begins, with no stale-on-error serving. The single expired snapshot may remain allocated until replaced or the router exits. Query results are eligible for collection after refresh; process exit releases all cache memory.
src/network/stats.ts

Public commerce ledger in router memory

When COMMERCE_STATS_ENABLED is on, cache the public commerce ledger and share one refresh among concurrent readers.

Holds
Only the public aggregate response: snapshot time, receipt kinds, filter settings and transfer-index position, and per window and kind the gross and filtered settlement, distinct payer and payee counts, USDG volume, median price, refund count and rate, and the count excluded by each rule. To build it, the router reads in memory the payer and payee wallet or account identifiers, amounts, times, transaction hashes, anchor status and refund flags of settled payments, and public USDG transfers; none of these enter the cache. Figures are never split by privacy lane, so a private-lane settlement cannot be told apart. No inference text or caller network address is read. No Redis keys. A failed refresh logs one warning with the first line of the error, cut to 200 characters; database errors put the query text on that line, not its parameters.
Lives for
Cache freshness ends 60 seconds after refresh begins, with no stale-on-error serving. The single expired snapshot may remain allocated until replaced or the router exits. Settlement rows read for a refresh are eligible for collection when it ends.
src/commerce/stats.ts

Owner's sealed agent VM

The dedicated agent sidecar uses the guest agent's application-scoped GetKey with a measured-compose-specific path to seal a provisioned AnyRoute credential with AES-256-GCM. It obtains TDX quotes committing the key fingerprint, image, measured compose, version and TLS key. The internal proxy forwards agent request and response streams to fixed paths at the configured HTTPS router origin.

Holds
An encrypted credential file in the VM's sealed volume. Raw credential and guest-derived key enter process memory during provisioning or boot; the API credential is sent to AnyRoute as Bearer authentication over TLS. The agent container receives no credential. Provisioning input, guest console retention and any owner-held credential copies remain the owner's responsibility. VM software and administrators can access guest memory. JavaScript strings cannot be reliably erased. No prompt or answer file is written by the sidecar.
Lives for
Ciphertext survives restarts until volume removal or replacement. Memory lasts for the sidecar process; the KMS key is scoped to app identity and a path containing the measured compose. Manifest changes require fresh provisioning. No anti-rollback guarantee is provided.
sidecar/src/agent/credential-store.ts

Agreement escrow and dispute records on chain

Agreements are switched on at anyroute.tech, with the escrow and dispute contracts deployed on Robinhood Chain. A payer funds individual milestones in USDG and an oracle can pay only that agreement's payer or payee. The optional agreements service indexes this public state, stores party evidence and model verdict statements, and prepares payer-signed funding transactions; its separate database and reader disclosures appear in this inventory.

Holds
Public permanent blockchain state, transaction calldata and events: payer, payee, token, escrow, oracle, owner, panel and jury wallet addresses; agreement and milestone ids; amounts, deadline, immutable review window and dispute timeout, delivery and dispute-opening timestamps and status; terms and deliverable digests, opening evidence digest and evidence root; jury version, signer order, threshold, participation and consensus bitmaps, signed per-signer basis-point verdicts, tally digest, final verdict, neutral stale-dispute 50/50 recovery events and payouts; a panel-pending tally remains historical metadata after escrow recovery. The digest fields accept arbitrary caller-supplied bytes32 values; they do not prove the absence of encoded text or conceal low-entropy content. Evidence text is not required by the contracts, and any off-chain jury service needs its own retention disclosure. Deployment prints only escrow and oracle addresses.
Lives for
Permanent public chain history; the contracts have no deletion function. When enabled, the agreement service indexes chain records into the separately described agreement tables.
contracts/src/agents/AgreementEscrow.sol

Messages proxy prices on the caller's computer

The local proxy estimates a Messages budget using model prices fetched over Tor. The request text, code, tool schemas and results are read in memory to count tokens, then forwarded over Tor; count_tokens is answered locally without any network request.

Holds
The public unlinkable model directory in memory. The existing local tokens.json file atomically moves every selected bearer token to unconfirmed before sending; uncertainty keeps all members there, while a definite unserved refusal returns them. No request or answer text is written to that file or logged.
Lives for
Model prices are refreshed after one minute and lost on process exit. Local token credentials remain until expiry filtering, successful settlement or removal by the caller; uncertain sent sets are never automatically reused.
packages/private/src/messages.ts

Batch requests and answers in the router's memory, without Redis

Without Redis (a single router in development), the Batch API keeps the same sealed requests and answers in the router process's memory instead.

Holds
The same sealed requests and answers as the Redis keys batch:<batch id>:in and :out.
Lives for
The sealed requests are deleted when the batch finishes; the sealed answers BATCH_RESULTS_TTL after that (86,400 seconds, 24 hours, unless the operator changed it). A batch that never finishes ends when its 24-hour completion window closes, so nothing outlives the window plus that time. A restart loses them.
src/services/batches.ts

Response cache in the router's memory

The opt-in response cache also keeps each entry in the router process's memory (up to 5,000 entries), whether or not Redis is configured.

Holds
The same sealed answer as the Redis entry, and for the semantic mode a hashed word vector of the prompt.
Lives for
An entry is not served after its time-to-live, but it stays in memory until newer entries push it out (oldest first, at 5,000) or the process restarts.
src/gateway/cache.ts

Replay guards in memory

Two small in-memory sets stop replays: a used wallet signature (when Redis is not configured) and an Oblivious HTTP encapsulated request prefix.

Holds
SHA-256 digests of a wallet address, timestamp and request hash, and of the first bytes of an encapsulated request. Not the request.
Lives for
Ten minutes for a wallet signature (old entries are swept once the set passes 50,000); until the key's acceptance window ends for an encapsulated request, with at most 100,000 kept.
src/api/auth.ts

Private-lane counters in memory

Differentially private hourly counters for the attested and unlinkable lanes: how many requests, how many were refused and why, latency and token buckets. They contain no request, no address, no key and no timestamp finer than an hour.

Holds
Four families of counts for the current hour, released once with noise when the hour ends; the raw counts are then discarded.
Lives for
Released hours are kept for 48 hours; the privacy-budget ledger for 30 days.
src/lib/dpstats.ts

Trace export (OpenTelemetry), off unless an endpoint is set

When OTEL_EXPORTER_OTLP_ENDPOINT is set, one span per chat or text-completion call is sent to that endpoint: model, provider, token counts, cost, generation id, mode, attempt count, whether it streamed, and the trace id from a traceparent header if the caller sent one. Calls on the attested and unlinkable lanes send no span. Spans carry no prompt or completion.

Holds
The attributes listed, buffered in memory for up to five seconds before export.
Lives for
In memory for seconds; kept by whatever receives it, which the operator chooses.
src/api/chat.ts

Trace export to a key owner's own destination, off unless the owner sets one

A key's owner can set a tracing destination on the key (their OpenTelemetry collector, Langfuse or Helicone). Each public-lane call made with that key is then sent there: model, provider, token counts, sampling settings, finish reason, latency, cost, receipt id and lane. Prompt and completion text is included only if the owner set include_content. Calls on the attested and unlinkable lanes are never sent.

Holds
The listed fields of recent calls, in a bounded in-memory queue (2,000 calls at most across all keys; more are dropped and counted) until they are delivered or given up.
Lives for
In memory for seconds, or until retries end; kept by the destination the key's owner chose.
src/api/chat.ts

Encrypted database backups

A scheduled pg_dump (daily in the reference deployment) of the whole database, encrypted to public age recipients and uploaded to S3-compatible storage. Every table listed on this page is in it. The private key that opens it is never on the host that makes the backup.

Holds
The database as it was when the backup ran.
Lives for
The code writes each archive under a new key and never deletes one; how long archives last is set by the storage bucket's own rules, which are not in this repository.
scripts/backup-offsite.ts

The database, table by table.

115 tables and 1,230 columns, grouped by what they are for. “About a request” says whether a value is recorded for each call, summed from calls, or has nothing to do with calls. A column whose name or type suggests request content or a network address (a name such as prompt, body, ip or address, or a free-form JSON or network type) carries a written review, shown with the column.

Request records

Ordinary call rows hold the model, provider, token counts, cost and timing, without the text. Owner-chosen scheduled run replies are also described here and stored encrypted at rest.

appsPer request · 4 columns · 2 reviewed

Where calls come from, for app rankings: the HTTP-Referer and X-Title headers a caller chose to send, kept as the caller wrote them (truncated). Not recorded for the unlinkable lane.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextFirst 24 hex characters of SHA-256 of the referer and title, so the same app maps to one row.Per request
urltextThe HTTP-Referer header value, cut to 500 characters. It is whatever the calling application sent, usually its own site address.A request header, kept as written. A request header kept on purpose so apps can be ranked. It names an application's site, not the caller's network address, and callers can omit it.Per request
titletextThe X-Title header value, cut to 200 characters: the application's display name.A request header, kept as written. A request header kept on purpose for app rankings. It is a short label the caller chooses, not a prompt.Per request
created_attimestamp with time zoneWhen the row was created.Per request
batch_linesPer request · 12 columns

One row per line of a batch: its status, the HTTP status its call returned, the generation (and so the signed receipt) it produced and what it was charged. No request or answer text: that is sealed outside the database.

How long: Deleted with the batch's sealed answers when its results expire (BATCH_RESULTS_TTL after the batch finished, 24 hours unless the operator changed it).

ColumnWhat it holdsAbout a request
batch_idtextThe batch the line belongs to.Per request
idxintegerThe line's position in the batch, from 0.Per request
apitextchat or embeddings.Per request
statustextqueued, running, succeeded, failed, cancelled or expired.Per request
attemptsintegerHow many times the worker started the line (a line whose providers were all unavailable is tried again, up to BATCH_LINE_MAX_ATTEMPTS).Per request
status_codeintegerThe HTTP status the line's call returned.Per request
generation_idtextThe generation the line produced, whose receipt it has.Per request
costbigintWhat the line was charged, after the batch discount, in pico-USD.Per request
list_costbigintWhat the line would have cost without the discount, in pico-USD.Per request
failure_codetextFor a line that did not succeed, the error type (for example insufficient_credits or batch_cancelled). A fixed code, never text from a request.Per request
not_beforetimestamp with time zoneThe earliest the line runs (a rate-limited line waits), or, while it runs, when it counts as interrupted.Per request
finished_attimestamp with time zoneWhen the line ended.Per request
batchesSummed from requests · 18 columns

One row per batch sent to the Batch API (POST /api/v1/batches): the key that sent it, its status, how many lines it has and how many succeeded or failed, and what it cost. The requests and answers of its lines are never written to the database: they are kept sealed in Redis or the router's memory (see the Redis section) until the batch's results expire.

How long: No automatic deletion of the row itself; when the batch's results expire (results_expire_at), its line rows and its sealed requests and answers are deleted and purged_at is set.

ColumnWhat it holdsAbout a request
idtextThe batch id (batch_ and random hex).Summed from requests
account_idtextThe account the batch's lines are billed to.Summed from requests
key_hashtextThe hash of the API key that sent the batch; only that key can read or cancel it.Summed from requests
apitextWhich API every line calls: chat or embeddings.Summed from requests
statustextvalidating, in_progress, cancelling, completed, failed, expired or cancelled.Summed from requests
totalintegerHow many lines the batch has.Summed from requests
completedintegerHow many lines succeeded.Summed from requests
failedintegerHow many lines failed.Summed from requests
costbigintWhat the batch's lines were charged, after the batch discount, in pico-USD.Summed from requests
list_costbigintWhat the same calls would have cost without the batch discount, in pico-USD.Summed from requests
discount_bpsintegerThe batch discount in basis points (BATCH_DISCOUNT_BPS when the batch was sent; 5000 is half price).Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests
started_attimestamp with time zoneWhen the worker started the batch.Summed from requests
cancelling_attimestamp with time zoneWhen the key asked to cancel the batch.Summed from requests
finished_attimestamp with time zoneWhen the batch's last line ended.Summed from requests
expires_attimestamp with time zoneThe end of the 24-hour completion window: lines not run by then end unrun and unbilled.Summed from requests
results_expire_attimestamp with time zoneWhen the batch's answers and line rows are deleted (finished_at plus BATCH_RESULTS_TTL).Summed from requests
purged_attimestamp with time zoneWhen they were deleted.Summed from requests
generationsPer request · 47 columns · 6 reviewed

One row per call the router served: who was billed, which model and provider answered, token counts, cost, timing, how it was paid and the signed receipt. It holds hashes of the request and the response, never their text.

How long: No automatic deletion: no job or route in the code removes rows from this table. Rows are read back for receipts, usage history, settlement and provider scoring.

ColumnWhat it holdsAbout a request
projecttextOwner-chosen project label from X-Anyroute-Project or the key default, captured for this call. Null when absent. Retained with the call; not included in the signed receipt. Anyroute can read it. Activity JSON/CSV and Insights return labels and use them to filter within existing account/key permissions. A project-filtered Activity feed includes calls only; generation-linked refunds in Insights follow the original call label, unlinked refunds have no project. Labels can encode sensitive details; use non-sensitive names. No request text is read to derive the label. The unlinkable lane refuses project tags to preserve separation between calls. Statements are unchanged.Per request
idtextGeneration id, random. It is also the id of the signed receipt (the X-Receipt-Id response header).Per request
tstimestamp with time zoneWhen the call was recorded.Per request
key_hashtextSHA-256 of the API key that made the call (the key itself is never stored). Empty for wallet-paid and blind-token calls.Per request
account_idtextThe account that was billed. For a blind-token call it is the shared token pool, not a person.Per request
model_idtextThe catalogue model id that answered, such as author/slug.Per request
provider_idtextThe provider that served the call.Per request
tokens_inintegerPrompt tokens billed, as a count.Per request
tokens_outintegerCompletion tokens billed, as a count.Per request
reasoning_tokensintegerReasoning tokens billed, as a count.Per request
cached_tokensintegerPrompt tokens the provider served from its cache, as a count.Per request
cache_write_tokensintegerPrompt tokens written to the provider's cache, as a count.Per request
costbigintTotal charged to the caller, in pico-USD (1e-12 USD).Per request
upstream_costbigintWhat the provider charged the router for the call, in pico-USD.Per request
royaltybigintThe share of the cost owed to the model's creator, in pico-USD.Per request
marginbigintThe router's fee on the call, in pico-USD.Per request
cache_discountbigintThe discount given for cached prompt tokens, in pico-USD.Per request
modetextHow the call was paid: prepaid, per_call, paywith, byok, cache or blind.Per request
latency_msintegerMilliseconds until the provider's first response.Per request
generation_time_msintegerMilliseconds for the whole call.Per request
finish_reasontextWhy the model stopped, such as stop or length.Per request
native_finish_reasontextThe stop reason as the provider reported it.Per request
streamedbooleanWhether the answer was streamed.Per request
cancelledbooleanWhether the caller cancelled before the answer finished.Per request
quanttextQuantisation of the endpoint that answered (for example fp8), or unknown.Per request
data_regiontextThe first datacenter region the provider lists, not the caller's location.Per request
is_byokbooleanWhether the caller's own provider key paid for the call.Per request
privatebooleanWhether the caller asked for a private route (provider.private or a :private model).Per request
attestation_hashtextHash of the attestation report of the provider, when an attested provider served the call.Per request
receipt_idtextThe receipt's id (the same as id).Per request
receipt_sigtextThe router's Ed25519 signature over the receipt.Per request
receipt_key_idtextWhich receipt signing key signed it.Per request
receiptjsonbThe signed v1 receipt payload: model, provider, token counts, cost, timing, mode, lane, disclosure class, payer (a key hash or a wallet address), the two SHA-256 digests and a summary of the provider's attestation. Blind payment adds a single nullifier and issuer key id, or token_count, nullifiers and token_key_ids for a set; no buyer or credential bytes. The ciphertext chat adapter also signs end_to_end_encrypted and e2ee: version, suite, gateway_attested, complete, billing_basis, input_byte_bound, max_tokens, request_bytes, response_bytes and gateway_receipt with id, keyset digest, response-hash, request-hash and upstream verification state plus upstream session id and GPU claim. Request-hash verification remains false in the router. No public keys, replay nonces, credentials or content are retained. When ROUTE_EXPLAIN_ENABLED is true, route stores version, serving provider id, selection reason, eligible count, aggregate skip and fallback error-class counts, lane, required parameter names from a fixed allowlist and whether the provider is a network host. No other provider ids, weights, URLs, messages or content are added. With DECISION_TAGS_ENABLED, decision_tag stores the caller's X-Anyroute-Decision-Tag: a validated sha256 digest the caller computed, never what it was computed from. Fixed fields chosen by the router.Cannot hold request content. Every field is set by the router's receipt code from numbers, ids and hashes; it never copies request or answer text into the payload.Per request
receipt_leaftextThis receipt's leaf hash in the anchoring tree.Per request
anchor_indexintegerWhich anchor (Merkle root) this receipt was included in, once anchored.Per request
leaf_indexintegerThe receipt's position in that anchor tree.Per request
receipt_v2jsonbThe v2 receipt claims as JSON: model, provider, lane, hashed request and response, power-of-two token-count buckets and cost units. The optional route claim carries the same versioned selection summary as v1, without other provider ids, raw errors or weights. The optional decision_tag claim is the same caller-computed sha256 digest as v1. Null for receipts made before v2.Cannot hold request content. Built by buildClaimsV2 from ids, hashes and buckets; the claims carry no payer, address, IP or content.Per request
receipt_cosetextThe v2 receipt as signed COSE_Sign1 bytes, base64.Per request
receipt_leaf_v2textThe v2 receipt's leaf hash in the anchoring tree.Per request
leaf_index_v2integerThe v2 leaf's position in the anchor tree.Per request
paid_withjsonbFor a pay-with call: the token symbol and address, raw units accrued, the fair price used and the swap transaction, when there is one.Cannot hold request content. Written by the pay-with code from token symbols, addresses and amounts.Per request
payment_txtextFor a per-call payment: the transaction hash that paid.Per request
app_idtextLinks to the apps row when the caller sent HTTP-Referer or X-Title. Not recorded for the unlinkable lane.Per request
attemptsjsonbEvery provider the router tried for the call: provider, model, whether it worked, error kind, HTTP status and latency. A failed attempt also keeps up to 200 characters of the provider's own error message, with URLs, keys, emails and long hex removed.May hold a short piece of request text. The failure message is the provider's text, not ours. Providers normally send a generic reason, but a provider could quote part of a rejected request in it, so up to 200 characters of request text could end up here.Per request
request_sha256textOrdinary chat: SHA-256 of canonical request JSON (stream flags excluded). The E2EE adapter hashes the exact forwarded encrypted envelope bytes, including whitespace and stream flags. Someone who already has the exact request can check it against this; the text cannot be recovered from it.A hash, not the text. A hash of the request, kept so a receipt can be checked against a request the caller holds; it is 64 hex characters and holds no text.Per request
response_sha256textOrdinary chat: SHA-256 of response text (all choices joined). The E2EE adapter hashes encrypted JSON or SSE wire bytes, including framing; an interrupted response hashes the observed prefix. The text cannot be recovered from it.A hash, not the text. A hash of the answer, kept for the receipt; it is 64 hex characters and holds no text.Per request
settled_periodtextThe UTC hour in which the call was settled to the provider, for example 2026-09-26T13.Per request
healthPer request · 11 columns · 1 reviewed

One row per provider attempt (and per probe): did it work, how fast, which status. It feeds routing and provider scores. It has no request or answer text and no account id.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
model_idtextThe model that was tried.Per request
provider_idtextThe provider that was tried.Per request
tstimestamp with time zoneWhen the attempt finished.Per request
okbooleanWhether the attempt produced a usable answer.Per request
latency_msintegerMilliseconds until the first response.Per request
tpsrealOutput tokens per second, when it could be measured.Per request
empty200booleanWhether the provider answered 200 with an empty completion.Per request
status_codeintegerThe HTTP status the provider returned, when there was one.Per request
error_kindtextA fixed code for the failure from the router's ErrorKind list, such as http_5xx, rate_limited, provider_auth, rejected, empty200 or interrupted. Null when the attempt worked.Cannot hold request content. One of a short list of codes chosen by the router (ErrorKind); the provider's message is not stored here.Per request
sourcetexttraffic for a real call, probe for the router's own health probe.Per request
callertextA 16-character truncation of the SHA-256 of the account id, set only on failed attempts, so one caller cannot single-handedly mark a provider as failing. It is not the account id.Per request
schedule_runsPer request · 10 columns · 1 reviewed

The last ten claimed scheduled runs, including encrypted replies and bounded failure reasons.

How long: Last ten runs per schedule, pruned at the next claim; all removed when the schedule is deleted. Ordinary billing and receipt records retain their existing lifetimes.

ColumnWhat it holdsAbout a request
idtextRandom run identifier.Per request
schedule_idtextParent schedule identifier; deletion cascades.Per request
due_attimestamp with time zoneUnique due slot per schedule; coordinates competing workers without Redis.Per request
started_attimestamp with time zoneWhen the run was claimed.Per request
finished_attimestamp with time zoneWhen the run succeeded, failed or was marked interrupted.Per request
statustextRunning, succeeded or failed.Per request
reply_enctextThe full returned reply, encrypted with the same account-and-schedule AES-GCM scope as the prompt.Holds request text. This column keeps actual answer text encrypted under a router-held secret. It is decrypted for authorized owners and the first 300 characters are included in inbox and Telegram notices.Per request
reasontextBounded machine error code, never the upstream message or request text.Per request
generation_idtextPreselected ordinary generation identifier linking the run to its charge and receipt, including an uncertain interrupted call.Per request
notifiedbooleanOne outbound Telegram attempt claimed before delivery; failed or interrupted sends are not retried.Per request

Billing

Balances, the append-only ledger, spending holds, per-call payment quotes and what providers are owed.

accountsNot about requests · 10 columns

One row per billing account: an API-key account or a wallet account, with its settled balance and the amount held for calls in flight.

How long: No automatic deletion. The ledger refers to accounts and is append-only, so an account row stays.

ColumnWhat it holdsAbout a request
idtextThe account id. For a wallet account it is derived from the wallet address.Not about requests
low_balance_picobigintOptional owner-selected low-balance threshold in pico-USD; null disables alerts. Kept until changed or cleared.Not about requests
low_balance_alertedbooleanWhether the current threshold crossing has been recorded. Re-armed only after a worker observes settled balance above the threshold; false by default.Not about requests
inference_keys_defaultbooleanWhether newly provisioned child keys default to inference-only access. Management keys can explicitly select account scope.Not about requests
last_sent_weektextNullable previous ISO week identifier (YYYY-Www) last successfully sent as a weekly Telegram summary. Overwritten after delivery; retained with the account, including after unlink, to avoid sending that week again after relinking. No message text. With quiet hours, the week is marked after durable queue acceptance, before actual Telegram delivery. A later revoked, muted or expired queued summary is not resent.Not about requests
kindtextkey for an API-key account, wallet for a wallet account.Not about requests
wallettextThe wallet address of a wallet account. Empty for a key account.Not about requests
balancebigintThe spendable balance, including provisional deposit credits: the sum of the account's ledger lines, in pico-USD. A database trigger keeps it equal to that sum.Summed from requests
heldbigintThe amount reserved by open holds for calls in flight, in pico-USD.Summed from requests
created_attimestamp with time zoneWhen the row was created.Not about requests
holdsPer request · 9 columns · 1 reviewed

A reservation of balance made before a call runs, settled to the real cost afterwards or released. One hold per call.

How long: The database refuses to delete holds (trigger holds_apply_held), so they are kept permanently.

ColumnWhat it holdsAbout a request
idtextHold id; for a chat call it is the generation id.Per request
account_idtextThe account the amount is reserved on.Per request
key_hashtextThe key hash that made the call, when there is one.Per request
amountbigintThe reserved amount in pico-USD; it cannot change after creation.Per request
statustextheld, settled or released.Per request
kindtextWhat the hold was for; usage for a call, tool_call for a paid x402 tool, data_tool for a market-data tool call.Per request
resultjsonbHow the hold ended: the amount charged and any uncovered amount, as strings in pico-USD, and expired: true when the hold timed out.Cannot hold request content. Written only by settle() and release() in ledger.ts as { charged, uncovered, expired } amounts.Per request
created_attimestamp with time zoneWhen the row was created.Per request
expires_attimestamp with time zoneWhen an unsettled hold is released automatically (the holds-expire job).Per request
ledgerPer request · 9 columns · 1 reviewed

The append-only money ledger: deposits, credits, usage charges, refunds, withdrawals and adjustments. A usage line names the generation it paid for; it does not say what the call was about.

How long: The database refuses every update and delete on this table (trigger ledger_no_update), so lines are kept permanently.

ColumnWhat it holdsAbout a request
idtextLedger line id.Per request
account_idtextThe account the line applies to.Per request
key_hashtextThe key hash the line came from, when there is one.Per request
amountbigintThe signed amount in pico-USD: positive adds to the balance, negative takes from it.Per request
kindtextWhat the line is: provisional (early escrow credit), deposit, credit, usage, refund, paywith, change, adjustment, withdrawal_lock, withdrawal, blind_purchase, tool_call (a paid x402 tool), data_tool (a market-data tool call) and similar.Per request
reftextA unique idempotency reference, such as usage:<generation id> or escrow:<transaction>:<log index>, so a line can never be posted twice.Per request
generation_idtextFor a usage line, the generation it paid for.Per request
descriptiontextA short line written by the router, such as "<model> via <provider>", "USDG deposit <transaction hash>" or "Model usage". Never text from a request.Cannot hold request content. Every description is built in code from model ids, provider ids, transaction hashes and fixed phrases (ledger.ts, escrow.ts, indexer.ts); no caller-supplied string is used.Per request
created_attimestamp with time zoneWhen the row was created.Per request
low_balance_alertsSummed from requests · 5 columns

One durable inbox item per observed low-balance crossing, claimed together with the account alert flag.

How long: No automatic deletion. Earlier crossings remain after the balance recovers or the setting changes.

  • With LOW_BALANCE_ALERTS_ENABLED, the worker checks every five minutes. Authorized linked Telegram accounts receive balance, threshold and an Add funds link through the existing Telegram delivery path. The inbox claim is committed before a single send attempt; failures are not retried. No message body or Telegram delivery result is retained here. No new Redis key family or log field is added. Runway uses seven days of posted usage and paid-tool debits, scoped like credits, and stores no report.
ColumnWhat it holdsAbout a request
idtextRandom alert identifier.Summed from requests
account_idtextBilling account whose balance crossed its threshold.Summed from requests
balance_picobigintSettled balance at the crossing check, in pico-USD; not reduced by open holds.Summed from requests
threshold_picobigintOwner-selected threshold at the crossing check, in pico-USD.Summed from requests
created_attimestamp with time zoneWhen the worker recorded the crossing.Summed from requests
makegood_refundsPer request · 22 columns · 2 reviewed

One row per call (or per unserved per-call payment) that met a make-good refund rule: the rule, the capped refund, the signed refund receipt and, for calls paid on-chain per call, the on-chain refund still owed or paid. Disabled unless MAKEGOOD_ENABLED.

How long: No automatic deletion: no job or route in the code removes rows from this table. At most one row per source: the source id is unique, so a call is never refunded twice.

ColumnWhat it holdsAbout a request
idtextRefund id, also the id of its signed refund receipt (GET /api/v1/receipts/{id}).Per request
source_idtextWhat is refunded: the generation id, or payment:<transaction hash> for a per-call payment no provider served. Unique.Per request
generation_idtextThe refunded generation, whose id is also its original receipt id. Null for an unserved paid call.Per request
account_idtextAccount credited (or whose per-call wallet is refunded on-chain).Per request
key_hashtextHash of the API key that made the call, copied from the generation; null for a per-call wallet payer.Per request
ruletextFixed rule name: upstream_failure, fallback_price, truncated_stream, structured_output or unattested_lane.Per request
statustextpending until the settlement job decides it, then issued, or void when nothing charged is left to refund.Per request
amountbigintRefund in pico-USD: the rule's amount capped by what the ledger charged (or, for an unserved paid call, by the payment still unspent).Per request
chargedbigintWhat the ledger charged for the call, or what the unserved per-call payment was, in pico-USD.Per request
evidencejsonbFixed facts behind the rule: error class counts, provider ids, token counts, costs, lane and disclosure class, a payment transaction hash or the first call id of a JSON repair.Cannot hold request content. Written only by the make-good hooks from numbers, fixed codes, provider ids, generation ids and transaction hashes; never request or answer text, headers or caller addresses.Per request
provider_idtextProvider whose failure caused the refund, when one did; null when no provider is responsible (a JSON answer that does not parse).Per request
strikebooleanWhether the refund is also a strike against that provider (an attested-lane call served without a fresh attestation).Per request
payertextWallet address that paid the call on-chain per call, refunded on-chain; null for credits to a prepaid balance.Per request
onchain_usdgbigintUSDG base units owed on-chain for this refund (whole units; any remainder below one unit stays as balance).Per request
payout_statustextnone, owed, batched (in a signed transfer) or paid.Per request
payout_idtextThe makegood_payouts transfer that pays this refund.Per request
receiptjsonbThe signed refund receipt payload (kind refund): ids, rule, amounts, settlement, provider and the evidence above.Cannot hold request content. Canonical JSON built by issueRefund from the fields of this row and the original generation id; it carries amounts, fixed codes and hashes, no request or answer text.Per request
receipt_sigtextEd25519 signature over the canonical refund receipt, by the router's receipt key.Per request
receipt_key_idtextId of the receipt key that signed it.Per request
receipt_leaftextHash of the signed receipt in the form receipt anchoring uses; refund receipts are not yet anchored.Per request
detected_attimestamp with time zoneWhen the rule was met (the call settled or failed).Per request
issued_attimestamp with time zoneWhen the settlement job issued or voided the refund.Per request
network_fee_ledgerSummed from requests · 10 columns

Network host fees from confirmed per-host receipt roots, grouped in the UTC hour when they accrue. Gross and fee are pico-USD; net is invoiced through settlements. Closed-hour fees are swapped through the guarded buyback oracle path and transferred to the token dead address. Swap and burn transactions are public through the network burns API.

How long: No automatic deletion, and rows are never changed after they are written.

  • The planned executor reads its public token, adapter, oracle and keeper addresses, daily cap, operation state and transaction events from the chain in memory to check configured settings and reconcile swaps. Quotes use a pinned block and may add an independent pool TWAP. No request text, caller address, new log field or Redis key is read or stored by these checks. Payouts and fee burns are not switched on yet.
  • Sub-USDG-unit fee dust remains unswapped and is reported separately. Burns transfer to the dead address; the token's totalSupply is unchanged. Public totals aggregate across hosts; recent entries expose transactions, status and token amounts, without host invoice amounts. Transactions themselves are public on chain and can be correlated with hosts. Amounts above the configured per-run or remaining daily cap wait for a later run or operator reconciliation.
ColumnWhat it holdsAbout a request
idtextProvider and accrual-hour identifier; also the input to the on-chain operation digest.Summed from requests
provider_idtextThe host owed a net payout.Summed from requests
periodtextUTC hour when anchored receipts accrue, which may follow the served hour.Summed from requests
gross_piconumeric(78, 0)Sum of upstream_cost for eligible linked generations, before the network fee.Summed from requests
fee_piconumeric(78, 0)Floor of gross times configured basis points divided by 10000.Summed from requests
statustextaccrued, swapped or burned, reconciled with on-chain operation state.Summed from requests
swap_txtextConfirmed swap transaction hash, not request content.Summed from requests
burn_txtextConfirmed dead-address transfer transaction hash.Summed from requests
anyr_amountnumeric(78, 0)ANYR base units measured by the executor's balance delta.Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests
payoutsNot about requests · 7 columns

A payout to a provider: the amount in USDG, where it went and its status.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextPayout id.Not about requests
provider_idtextThe provider paid.Not about requests
usdgbigintAmount in USDG base units.Not about requests
totextThe destination address for the payout.Not about requests
statustextpending, submitted, paid or invoice.Not about requests
txtextThe payment transaction.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
project_budget_noticesSummed from requests · 7 columns

Durable 80 percent budget notice, at most once per account/project/UTC month.

How long: No automatic deletion. Removing or editing a budget preserves notice history and does not re-arm that month's notice.

  • PROJECT_BUDGET_TELEGRAM_ENABLED defaults false; the worker sends only when Telegram linking and a bot token are also configured. Current management principals only receive these account-wide notices. Telegram receives project label, spend, budget and a dashboard link. No new Redis families, caller address readers or log fields.
ColumnWhat it holdsAbout a request
account_idtextBilling account receiving this notice.Summed from requests
nametextProject label included in the inbox and optional Telegram text.Summed from requests
monthtextUTC calendar month as YYYY-MM, the deduplication boundary.Summed from requests
spent_picobigintMonth-to-date charged spend when the threshold was reached, excluding refunds.Summed from requests
budget_picobigintBudget in effect when the notice was created.Summed from requests
attimestamp with time zoneTime of threshold observation at settlement or budget save.Summed from requests
telegram_claimedbooleanDurable claim before a single Telegram delivery attempt; default false. No retries after failed or ambiguous sends.Summed from requests
project_budgetsNot about requests · 3 columns

Owner-selected monthly project spending caps in calendar months UTC.

How long: Until the account owner removes the budget; no automatic deletion.

ColumnWhat it holdsAbout a request
account_idtextBilling account that owns this cap.Not about requests
nametextLowercase non-sensitive project label, 1–48 ASCII letters, digits, dots, underscores or hyphens.Not about requests
budget_picobigintMonthly spending cap in pico-USD, zero refuses positive estimates.Not about requests
project_reservationsPer request · 5 columns

Project attribution on existing ledger holds; settlements count charged spending before the generation record is written.

How long: No automatic deletion; retained with billing records even when a budget is removed.

  • Tracks tagged calls even without a cap. Open holds count across month boundaries until settled or released by the existing expiry job. Earlier generations count once; refunds do not restore monthly allowance. No prompt or answer text is kept here. The router still reads ordinary request text in memory.
ColumnWhat it holdsAbout a request
idtextExisting ledger hold identifier; also the generation identifier for inference calls.Per request
account_idtextBilling account paying for the call.Per request
nametextValidated label from the existing project header or key default; Anyroute can read it.Per request
charged_picobigintActual ledger charge in pico-USD; zero before settlement or on released calls.Per request
charged_attimestamp with time zoneLedger settlement time, used to assign charged spend to a UTC month; null until settlement.Per request
quotesPer request · 11 columns · 1 reviewed

A price quoted for one pay-per-call request (HTTP 402 and x402), so a payment can be matched to exactly the request it was for.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
noncetextThe quote id (32 bytes hex). For an x402 payment claim it is x402:<payer wallet>:<authorization nonce>.Per request
price_usdgbigintThe quoted price in USDG base units (1e-6).Per request
price_picobigintThe same price in pico-USD.Per request
request_sha256textSHA-256 of the request the quote is for. It binds the quote to that one request; the request cannot be recovered from it.A hash, not the text. A hash of the request body, used to check that a payment belongs to the request it quoted.Per request
model_idtextThe model the quote is for.Per request
expires_attimestamp with time zoneWhen the quote stops being payable.Per request
statustextopen, paid, used, expired or failed.Per request
payertextThe wallet address that paid, once a payment is seen.Per request
tx_hashtextThe payment transaction.Per request
account_idtextThe account the payment was credited to.Per request
created_attimestamp with time zoneWhen the row was created.Per request
royaltiesSummed from requests · 7 columns

The royalty a model's creator earned in one period, and whether it was claimed.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
model_idtextThe model.Summed from requests
periodtextThe settlement period.Summed from requests
amountbigintRoyalty in pico-USD.Summed from requests
usdgbigintRoyalty in USDG base units.Summed from requests
creatortextThe creator's payout address, when one is known.Summed from requests
stream_txtextThe transaction that streamed the royalty.Summed from requests
claimedbooleanWhether the creator claimed it.Summed from requests
seller_gas_floatsSummed from requests · 5 columns

USDG a seller prepaid to the treasury so the facilitator settles its payments below the minimum; each such settle is debited at its measured gas times a buffer.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
seller_idtextThe listing the float belongs to.Summed from requests
balancenumeric(78, 0)USDG base units left.Summed from requests
fundednumeric(78, 0)USDG base units paid in, in total.Summed from requests
debitednumeric(78, 0)USDG base units taken for gas, in total.Summed from requests
updated_attimestamp with time zoneWhen the row was last changed.Summed from requests
settlementsSummed from requests · 10 columns

What one provider is owed for one UTC hour: token totals, request count, upstream cost, the router's fee and the USDG owed. Network hosts use only confirmed per-host receipts and the configured network fee; their period is the accrual hour.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
provider_idtextThe provider owed.Summed from requests
periodtextThe UTC hour, such as 2026-09-26T13.Summed from requests
tokensbigintTotal tokens invoiced in the hour; network hosts include only newly eligible anchored work.Summed from requests
requestsintegerNumber of calls invoiced in the hour; network hosts include only newly eligible anchored work.Summed from requests
upstreambigintUpstream cost for the hour, in pico-USD.Summed from requests
feebigintThe router's fee for the hour, in pico-USD.Summed from requests
usdg_owedbigintUSDG base units owed to the provider for the hour.Summed from requests
payout_idtextThe payout that included the hour, once paid.Summed from requests
paid_txtextThe transaction that paid it.Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests
skill_installsNot about requests · 9 columns · 1 reviewed

One row per (skill, installing account): the price paid, the author's share, the network fee and the signed install receipt. The ledger rows of a paid install use refs derived from the same pair, which makes an install idempotent.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextInstall id (si_...).Not about requests
skill_idtextThe skill installed.Not about requests
account_idtextThe installing account.Not about requests
key_hashtextThe key that installed it.Not about requests
price_usdgbigintThe price paid in USDG base units; 0 for a free skill or the author's own.Not about requests
author_sharebigintPico-USD credited to the author's account (the price less SKILLS_FEE_BPS).Not about requests
feebigintPico-USD credited to the network fee account.Not about requests
receiptjsonbThe install receipt: skill id, content hash, level, installer and author accounts, amounts and time, with an Ed25519 signature from the receipt key.Cannot hold request content. Ids, hashes, amounts and a timestamp chosen by our code, plus the signature over them.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
tool_callsPer request · 24 columns · 2 reviewed

One row per paid x402 tool call made with a key's balance: the seller, the tool address, the price and take, the hold, the signed authorization's nonce and the settlement transaction, the answer's hash and the signed tool.call receipt. Never the tool arguments, the query string or the answer.

How long: No automatic deletion: these are billing records, like generations and the ledger.

ColumnWhat it holdsAbout a request
idtextCall id (tc_...), also the id of its hold.Per request
key_hashtextThe key that paid.Per request
account_idtextThe account charged.Per request
seller_idtextThe tool listing id when the address is listed, else null.Per request
pay_totextThe seller's payTo wallet (public on chain).Per request
resourcetextThe tool's https origin and path that was paid, without the query string.Per request
methodtextGET or POST.Per request
networktextThe x402 network of the paid offer.Per request
x402_versioninteger1 or 2: which x402 wire format the seller spoke.Per request
price_unitsbigintThe seller's price in USDG base units.Per request
pricebigintThe seller's price in pico-USD.Per request
takebigintThe router's take in pico-USD (TOOLS_TAKE_BPS).Per request
hold_idtextThe hold on the key's balance.Per request
payertextThe router's own buyer wallet that signed the authorization.Per request
noncetextThe EIP-3009 nonce of that authorization; the reconcile job asks the chain whether it was used.Per request
valid_beforetimestamp with time zoneWhen that authorization expires.Per request
settle_txtextThe settlement transaction hash the seller reported, if any.Per request
response_sha256textSHA-256 of the tool's answer bytes, as in the receipt. The answer cannot be recovered from it.A hash, not the text. A hash of the tool answer kept for the signed receipt; 64 hex characters, no text.Per request
seller_statusintegerThe tool's HTTP status code.Per request
statustextpaying, ok, failed, released or charged_after_failure.Per request
failuretextA fixed failure code, such as seller_status_500 or response_too_large.Per request
receiptjsonbThe tool.call receipt: COSE_Sign1 bytes (base64), key id, leaf and the signed claims (hashes, amounts, seller, address, settlement).Cannot hold request content. Ids, hashes, amounts, the public tool address and wallet, and the signature over them; no arguments or answer text.Per request
created_attimestamp with time zoneWhen the row was created.Per request
closed_attimestamp with time zoneWhen the hold was charged or released.Per request
x402_paid_resultsPer request · 6 columns · 3 reviewed

One row per x402 payment whose call was answered, so a payer who lost the answer can have it sent again instead of paying twice. It names the paying wallet and the authorization nonce and holds hashes; the answer itself is sealed outside the database.

How long: 24 hours. Recovery refuses an older row, and the x402-recovery-expire job (and, at most hourly, each router replica that keeps answers) deletes it together with any sealed answer still held for it.

ColumnWhat it holdsAbout a request
payertextThe wallet that signed the payment authorization (lowercase hex), as on the public settlement.Per request
noncetextThe authorization's EIP-3009 nonce (32 bytes hex), public on-chain once settled.Per request
request_sha256textSHA-256 of the request the payment paid for (the receipt's request_sha256). A recovery must send the identical request.A hash, not the text. A hash of the request body, compared with the hash of a recovery request so an answer is sent again only for the request it answered.Per request
response_sha256textSHA-256 of the answer's bytes as they were sent, checked before the sealed answer is sent again.A hash, not the text. A hash of the answer bytes, so the answer sent again is checked to be byte-identical to the one first sent; the answer cannot be recovered from it.Per request
body_reftextThe name of the Redis key that holds the sealed answer: x402paid: and a SHA-256 of the payer and the nonce.Cannot hold request content. A fixed prefix and a hash of the payer and the nonce naming where the sealed answer lives; the answer bytes are never written to this column.Per request
created_attimestamp with time zoneWhen the row was created.Per request

Receipts & proofs

Signing keys, anchors and the transparency log that let anyone check a receipt without asking us.

agent_track_recordsSummed from requests · 6 columns · 1 reviewed

Portable track-record certificates: a router-signed count, total spend, refund and dispute rates of one key's anchored receipts, with a Merkle root over those receipts' anchor leaves.

How long: Until the key is deleted (cascade). Certificates expire after seven days but stay stored; published ones show on the card until they expire.

ColumnWhat it holdsAbout a request
idtextRandom public certificate id.Summed from requests
key_hashtextThe certified key; never published.Summed from requests
certificatejsonbThe signed certificate: random pseudonym, aggregate stats, Merkle root and anchor counts, the public profile slug and ERC-8004 agent id when registered.Cannot hold request content. Aggregates and hashes written by the router: no counterparty, no amount per counterparty, no request or answer text and no key hash.Summed from requests
publishedbooleanWhether the owner chose to show it on the public card.Summed from requests
created_attimestamp with time zoneWhen it was issued.Summed from requests
expires_attimestamp with time zoneSeven days after issuance.Summed from requests
anchorsSummed from requests · 8 columns

A Merkle root over the receipts signed in one interval, and the chain transaction that recorded it. Lets anyone check that a receipt existed at that time.

How long: No automatic deletion, and rows are never changed after they are written.

ColumnWhat it holdsAbout a request
indexintegerAnchor number, counting up from zero.Summed from requests
roottextThe Merkle root of the interval's receipt leaves (32 bytes, hex).Summed from requests
from_tstimestamp with time zoneStart of the interval covered.Summed from requests
to_tstimestamp with time zoneEnd of the interval covered.Summed from requests
countintegerHow many receipts the root covers.Summed from requests
tx_hashtextThe chain transaction that recorded the root.Summed from requests
statustextpending, submitted, confirmed or local.Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests
host_anchor_leavesPer request · 7 columns

The receipt leaves collected from attested hosts. A row holds a leaf hash, the receipt id and the time; not the receipt's own hashes or usage.

How long: No automatic deletion, and rows are never changed after they are written.

ColumnWhat it holdsAbout a request
provider_idtextThe attested host that produced the receipt.Per request
leaftextThe receipt's leaf hash.Per request
anchor_idintegerThe host_anchors row that includes it.Per request
leaf_indexintegerIts position in that root's tree.Per request
receipt_idtextThe receipt's id.Per request
receipt_tstimestamp with time zoneThe time the receipt itself states.Per request
collected_attimestamp with time zoneWhen the router collected the leaf.Per request
host_anchorsSummed from requests · 14 columns

A Merkle root over the receipts one attested host signed in an interval, tied to the attestation its receipt key was bound in.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Summed from requests
provider_idtextThe attested host.Summed from requests
attestation_reftextSHA-256 of the boot quote the router verified for that host.Summed from requests
receipt_key_idtextThe host's receipt key id.Summed from requests
receipt_public_keytextThe host's raw Ed25519 receipt public key, hex, as its verified quote bound it.Summed from requests
roottextThe Merkle root of the collected leaves.Summed from requests
from_tstimestamp with time zoneStart of the interval the leaves were collected in.Summed from requests
to_tstimestamp with time zoneEnd of that interval.Summed from requests
countintegerHow many leaves the root covers.Summed from requests
statustextpending, confirmed or local.Summed from requests
tx_hashtextThe chain transaction that recorded the root.Summed from requests
block_numberbigintThe block of that transaction.Summed from requests
chain_indexintegerThe anchor's index in the on-chain receipt anchor contract once posted.Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests
receipt_keysNot about requests · 7 columns

The Ed25519 keys that sign receipts, with the dates each was valid. Public halves are published; the private half is encrypted at rest.

How long: Keys are rotated (RECEIPT_KEY_ROTATION_DAYS) and retired, never deleted, so old receipts stay verifiable.

ColumnWhat it holdsAbout a request
idtextKey id: 16 hex characters, the first bytes of the public key's digest.Not about requests
public_keytextThe raw 32-byte public key, hex. Published at /api/v1/receipts/keys.Not about requests
private_key_enctextThe private key, AES-256-GCM encrypted with the router's APP_SECRET. Null for a key that can no longer sign; the router then makes a new one.Not about requests
valid_fromtimestamp with time zoneWhen the key started signing.Not about requests
retired_attimestamp with time zoneWhen it stopped signing, once rotated out.Not about requests
onchain_txtextThe transaction that published the public key on chain.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
tlog_checkpointsNot about requests · 5 columns

Signed checkpoints of the transparency log: its size and root, signed by the log's key.

How long: No automatic deletion, and rows are never changed after they are written.

ColumnWhat it holdsAbout a request
sizebigintThe tree size the checkpoint is for.Not about requests
root_hashtextThe tree's root hash, hex.Not about requests
checkpointtextThe checkpoint text: origin, size and base64 root hash.Not about requests
signaturetextThe log's signature line over that text.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
tlog_cosignaturesNot about requests · 7 columns

Witness cosignatures on checkpoints: independent parties confirming the log showed them the same tree.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
sizebigintThe checkpoint size the witness signed.Not about requests
witnesstextThe witness's key name.Not about requests
key_idtextHex of the 4-byte signed-note key id.Not about requests
timestampbigintThe cosignature's own time, in seconds.Not about requests
linetextThe signature line as the witness sent it.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen a newer cosignature from the same witness replaced the row.Not about requests
tlog_entriesNot about requests · 7 columns

The entries of the public transparency log: receipt keys, Oblivious HTTP key configurations, blind-token issuer keys, measurement bundles, attestation bindings and data inventories (this page's own hash).

How long: Append-only by design: entries are never updated or deleted, because the log's tree hashes them.

ColumnWhat it holdsAbout a request
idxbigintThe entry's leaf index in the log.Not about requests
kindtextreceipt_key, ohttp_key_config, blind_issuer_key, measurement_bundle, attestation_binding or data_inventory.Not about requests
sha256textHex digest of the key or configuration the entry names.Not about requests
subjecttextThe key id, epoch, provider or inventory the entry is about.Not about requests
entrytextThe exact canonical JSON that was hashed into the log: public keys, digests and configuration, never request data. Sidecar bindings v2 include the source archive hash, engine name and image digest, and model ID and digest.Not about requests
leaf_hashtextThe entry's RFC 6962 leaf hash.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
tlog_rekor_anchorsNot about requests · 19 columns · 3 reviewed

Records of checkpoints the router anchored in a public Rekor log, with the proof that the entry is included.

How long: A pending row that turns out not to be an entry for its checkpoint is dropped and the checkpoint is submitted again; verified rows are kept.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
sizebigintThe checkpoint's tree size.Not about requests
root_hashtextThe checkpoint's root hash, hex.Not about requests
notetextThe signed checkpoint note that was anchored: checkpoint text, a blank line and the log's signature line.Cannot hold request content. The note is the transparency-log checkpoint text (origin, size, root hash) plus a signature line; nothing else is ever placed in it.Not about requests
artifact_sha256textThe SHA-256 the Rekor entry holds.Not about requests
key_idtextSHA-256 of the anchoring key's public key info, hex.Not about requests
rekor_urltextThe address of the Rekor log the entry was submitted to.A public address, not a caller's. The address of a public transparency log server, set by the operator; it is not a caller's address.Not about requests
uuidtextThe Rekor entry id.Not about requests
statustextpending or verified. Only verified rows are served.Not about requests
log_indexbigintThe entry's index in Rekor.Not about requests
integrated_timebigintWhen Rekor integrated the entry, in seconds.Not about requests
log_idtextRekor's log id.Not about requests
entry_base64textThe entry body as Rekor returned it, base64.Not about requests
inclusion_proofjsonbThe inclusion proof: log index, tree size, root hash, hashes and Rekor's checkpoint.Cannot hold request content. Copied from Rekor's inclusion-proof response and typed as { logIndex, treeSize, rootHash, hashes, checkpoint }.Not about requests
signed_entry_timestamptextRekor's signed entry timestamp, base64.Not about requests
checkpoint_verifiedbooleanWhether Rekor's checkpoint signature verified against the pinned key.Not about requests
set_verifiedbooleanWhether the signed entry timestamp verified against the pinned key.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
verified_attimestamp with time zoneWhen the inclusion proof verified.Not about requests

Keys & auth

API keys (stored as hashes), teams with their passkey and wallet members and audit log, agent sessions, keys you bring, and the issuer and gateway keys behind blind tokens and Oblivious HTTP.

account_linked_walletsNot about requests · 3 columns

Signature-verified secondary wallets associated with an account for escrow deposit crediting and paying another agent.

How long: Until the owner unlinks the wallet; unlink deletes this association. Existing deposit, ledger and payment records remain under their original account.

  • Wallet addresses are public chain identifiers that can correlate this account with its deposits and agent payments. Linking does not merge accounts or let the secondary wallet sign in to the owner account.
ColumnWhat it holdsAbout a request
wallettextLowercase secondary wallet address verified by a personal signature, unique across accounts.Not about requests
account_idtextOwning account whose owner requested and verified the link.Not about requests
linked_attimestamp with time zoneWhen verification linked the wallet to the account.Not about requests
agent_action_decisionsPer request · 12 columns

Action checks, reported outcomes and rolling action limits for the deciding agent key, separate from model spend.

How long: Rows remain until operator deletion. Rolling day and hour limits read only the preceding 24 hours and hour; those windows do not delete records.

  • Action and target labels remain readable, including symbols, recipient wallet addresses or hosts supplied by the agent. Do not send secrets or request text in these labels. Only a SHA-256 digest of order details is accepted; full orders are not accepted here.
  • Unreported allowed actions count their requested amount. Executed outcomes count the agent-reported amount; skipped and failed outcomes release the daily amount. All allowed checks still count toward the hourly count. These records do not prove execution or control brokerage or wallet keys.
ColumnWhat it holdsAbout a request
idtextRandom URL-safe decision identifier, not an authentication credential.Per request
key_hashtextHash of the deciding API key; only that key can report an outcome.Per request
event_idbigintIdentifier of the aggregate action decision on the existing agent event hash chain; events have their own retention.Per request
actiontextCaller-chosen bounded action name such as trade.order or transfer.send.Per request
targettextOptional caller-chosen symbol, recipient wallet address or host label, stored verbatim; this is not the caller's network address.Per request
amount_piconumeric(78, 0)Requested action amount in integer pico-USD; an unreported allow holds this amount against the daily action limit.Per request
details_sha256textOptional SHA-256 digest of canonical order JSON; order details themselves are not stored.Per request
decisiontextallow, deny or approval_required from the rulebooks checked at decision time.Per request
created_attimestamp with time zoneWhen the decision was recorded.Per request
outcome_statustextNull before reporting; executed, skipped or failed afterward, accepted once only for an allowed action.Per request
outcome_amount_piconumeric(78, 0)Optional agent-reported actual pico-USD amount, required for executed; it may exceed the allowed amount and is not verified against a brokerage or chain.Per request
outcome_attimestamp with time zoneWhen the deciding key reported its outcome, or null before reporting.Per request
agent_approvalsPer request · 11 columns · 1 reviewed

Principal approval of an agent's estimated inference spend or reported action amount, consumed once by the requesting key.

How long: Approval validity defaults to 15 minutes (AGENT_APPROVAL_TTL_S). Pending and approved rows become expired on access or another approval evaluation. Rows remain until operator deletion; validity expiry does not delete records.

  • No prompt or answer fields are stored. Model and declared tool names remain readable; callers choose these identifiers. The router still reads request text in memory on every lane. Action approvals store the action name, optional readable target (including wallet or host labels), optional order digest and amount, never full order details. Council and dual requests store the entire set of model intents with a shared total cost ceiling.
ColumnWhat it holdsAbout a request
idtextRandom URL-safe approval identifier, not an authentication credential.Per request
key_hashtextThe API or session key requesting this approval; approval cannot transfer to another key.Per request
intentjsonbExplicit projection of model, lane, declared tool names, output token limit and estimated pico-USD cost, or action name, target, order digest and pico-USD amount; a multi-model request stores an intents array.Settings written by you or an operator. Only routing or action metadata is copied; action targets can be symbols, recipient wallets or hosts. messages, answers, tool arguments and descriptions are excluded. Declared model and tool identifiers are caller-chosen labels whose meaning cannot be inferred by shape checks.Per request
intent_hashtextSHA-256 of canonical projected intents including the estimated cost, used to reuse an identical pending approval.Per request
max_cost_piconumeric(78, 0)The original estimated pico-USD cost ceiling; retries may cost less but cannot exceed this amount.Per request
statustextpending, approved, denied, expired or used. Only approved, unexpired approvals can be consumed.Per request
requested_attimestamp with time zoneWhen the approval was created.Per request
decided_attimestamp with time zoneWhen the principal approved or denied the request, or null.Per request
decided_bytextThe deciding principal's API key hash, or null before a decision.Per request
expires_attimestamp with time zoneThe fixed validity deadline from request time; approval does not extend it.Per request
used_attimestamp with time zoneWhen the router consumed the approval after a successful spend reservation, on an allowed cache hit, or on an allowed action check.Per request
agent_feedbackNot about requests · 12 columns

Paid feedback: a 0 to 100 score and up to two short tags per receipt, accepted only from the receipt's payer about its payee or the agent it served.

How long: Until the subject key is deleted (cascade). A reviewer can withdraw an entry, which stops counting it; the row is kept with its withdrawal time. No automatic deletion.

  • Public: the score, tags, receipt kind, a coarse payment band and the payment day, linked to the agent's public profile slug. Never public: the reviewer's account, the receipt id and the exact amount. One entry per receipt.
ColumnWhat it holdsAbout a request
idtextRandom public feedback id.Not about requests
subject_key_hashtextThe reviewed agent's key; never published.Not about requests
reviewer_account_idtextThe paying account, kept to enforce one entry per receipt and the reviewer's right to withdraw; never published.Not about requests
receipt_kindtextFixed receipt kind such as model.call or agreement.release.Not about requests
receipt_idtextThe router's own receipt or agreement milestone id that backs the entry; never published.Not about requests
scoreintegerScore from 0 to 100.Not about requests
tag1textOptional short tag (letters, digits, spaces and . _ : - only, up to 32 characters).Not about requests
tag2textOptional second short tag, same limits.Not about requests
paid_picobigintWhat the reviewer paid on the receipt, net of recorded refunds, in pico-USD; used for weighting and shown only as a band.Not about requests
paid_attimestamp with time zoneWhen the payment happened; weights halve every PAID_FEEDBACK_HALF_LIFE_DAYS after it.Not about requests
created_attimestamp with time zoneWhen the entry was written.Not about requests
revoked_attimestamp with time zoneWhen the reviewer withdrew it; null while it counts.Not about requests
agent_identitiesNot about requests · 12 columns · 2 reviewed

Per agent key: the owner's identity opt-out and reputation opt-in, and the progress of an ERC-8004 identity registration the owner asked for.

How long: Until the key is deleted (cascade). Opting out keeps the row so the choice persists. A registration sent to the chain is public and permanent there; deleting this row does not remove it.

  • The ERC-8004 identity registry is a public contract the router does not operate. The registration file it points to is served only while the key has not opted out and contains owner-written profile fields and router links, never the key hash or account. Keys whose rulebook allows only the unlinkable lane are opted out unless the owner opts in.
ColumnWhat it holdsAbout a request
key_hashtextThe agent key these choices belong to; never published.Not about requests
idtextRandom 144-bit public id used in the registration file URL; independent of the key hash and the profile slug.Not about requests
identity_opt_outbooleanOwner's choice; null means the default (opted out only when the key's rulebook allows only the unlinkable lane).Not about requests
reputation_opt_inbooleanOwner's choice to accept paid feedback; false by default.Not about requests
statustextFixed registration state: none, awaiting_owner, queued, submitted, registered or failed.Not about requests
modetextowner (the owner's wallet sends the transaction) or registrar (the isolated worker sends it).Not about requests
registrytextPublic registry identifier eip155:<chain id>:<contract address>.Not about requests
agent_idtextThe public ERC-8004 agent id read from the registration transaction.Not about requests
owner_addresstextThe wallet that holds the identity token, read from the public registration event.A wallet address, not a network address. A blockchain wallet address from a public on-chain event, not a network address; it is shown to the owner only.Not about requests
tx_hashtextThe public registration transaction hash.Not about requests
errortextFixed failure code of the last registration attempt.Cannot hold request content. Only fixed codes written by the router (reverted, no_registration, uri_mismatch, send_failed); never library text, a request or an answer.Not about requests
updated_attimestamp with time zoneWhen the row last changed.Not about requests
agent_livenessNot about requests · 8 columns · 3 reviewed

The latest signed liveness probe of each listed agent's declared endpoint (daily agent-liveness job).

How long: Replaced by each probe; deleted with the key (cascade). A result for an endpoint the owner has since changed is not shown.

ColumnWhat it holdsAbout a request
key_hashtextThe listed agent key; never published.Not about requests
endpoint_sha256textSHA-256 of the probed endpoint URL, so a changed endpoint invalidates the old result.A hash, not the text. A digest of the owner-declared public endpoint URL; never a caller's network address.Not about requests
livebooleanWhether the endpoint answered with a status below 500, other than 404 and 410, within the timeout.Not about requests
http_statusintegerThe status code the endpoint answered with; null when it did not answer.Not about requests
latency_msintegerTime to the response headers in milliseconds.Not about requests
errortextFixed failure code: timeout, network, blocked or http.Cannot hold request content. Only fixed codes chosen by the router; no response body, header or library message is stored.Not about requests
probed_attimestamp with time zoneWhen the probe ran.Not about requests
receiptjsonbThe probe receipt the router signed with its receipt key: the public profile slug, endpoint digest, time, result, status and latency.Cannot hold request content. Fixed fields written by the router, signed with the published receipt key; no response body, headers or key hash.Not about requests
agent_policiesNot about requests · 11 columns · 1 reviewed

The principal's current agent rulebook and kill state, enforced by the router for requests through AnyRoute.

How long: Until the principal removes the rulebook. Updating a rulebook replaces its current specification and preserves kill state.

  • Model and tool identifiers and a kill reason are user-supplied text. Shape and size checks cannot judge the meaning a principal assigns to these labels. Action rules retain owner-chosen action names and target allow/deny labels, including recipient wallets or hosts; amount limits are separate from model caps. No prompt or answer fields are accepted.
  • D144: Saving replacements also appends full rules to policy_versions; removing the current rulebook does not remove those revisions.
  • G161: Optional work_hours keeps selected weekdays, local start/end clocks, an Intl-validated IANA time zone and refuse/ask_first mode in the existing readable rulebook JSON. Current rules, playbook copies and saved history retain it under their existing retention rules. No new table, column, Redis family, log field or request-body/address reader. The router still reads ordinary request text in memory.
ColumnWhat it holdsAbout a request
key_hashtextThe API key this rulebook governs.Not about requests
versionintegerRulebook schema version, currently 1.Not about requests
specjsonbOptional agreements.max_escrow_usd and counterparties_allow restrict preparation through the router; they do not enforce transactions sent elsewhere. Strict bounded rulebook: model and tool allow/deny names, lanes, an optional default privacy route (route_default) for requests that name no lane, cost and output caps, UTC windows, approval threshold, optional spend/request/denial/distinct-model circuit breakers and breach action, plus optional action and target allow/deny lists, separate action amount and count caps and an action approval threshold. Optional autonomy stores bounded rung requirements, spending multipliers and selected reset event kinds; it contains no prompt fields.Settings written by you or an operator. A strict schema excludes prompt and answer fields. Model and tool labels are owner-written identifiers of at most 160 characters; their contents are whatever the owner chooses to write.Not about requests
sha256textSHA-256 of the canonical rulebook JSON.Not about requests
killedbooleanWhether the router refuses the next request under this rulebook.Not about requests
killed_attimestamp with time zoneWhen the rulebook was killed, if it is killed.Not about requests
killed_reasontextA principal-supplied reason of at most 160 characters, or fixed policy reason codes for an automatic kill, including breaker:<field> for circuit breakers.Not about requests
kill_untiltimestamp with time zoneB117: Optional owner-selected stop deadline (future when set, at most 30 days ahead). Null means stopped until manually resumed. Cleared by manual Resume or atomically at the next enforcement check after expiry, including following playbook keys.Not about requests
updated_attimestamp with time zoneWhen the policy or kill state last changed.Not about requests
updated_bytextThe principal key hash or the agent key hash for an automatic kill or scheduled resume.Not about requests
playbook_idtextThe playbook this key follows, or null. While set, spec and sha256 hold a copy of that playbook's current rules, rewritten in the same transaction as every playbook change; stopping following keeps the copy as the key's own rulebook.Not about requests
agent_policy_eventsPer request · 10 columns · 2 reviewed

A per-key hash chain of rulebook decisions and policy, kill and resume changes. Decisions contain routing metadata, never prompts or answers.

How long: 90 days; the agent-policy-retention worker removes older events hourly when AGENT_POLICY_ENABLED is on and the worker runs this job. With the flag off or the worker absent, deletion waits. A retained suffix starts with its prior hash as a checkpoint. For active autonomy rulebooks, the latest autonomy_state checkpoint and following suffix remain until superseded or the rulebook is removed, even beyond 90 days, to preserve earned progress.

ColumnWhat it holdsAbout a request
idbigserialMonotonically allocated event identifier for pagination.Per request
key_hashtextThe key whose rulebook was evaluated or changed; parent decisions are recorded under the parent key.Per request
tstimestamp with time zoneWhen the event was recorded, at millisecond precision.Per request
kindtextaction_decision and action_outcome (readable action/target identifiers, order digest and reported amounts), decision, breaker_request (one observation per policy admission batch with breakers), policy_set, killed, resumed, resume (scheduled stop expiry), approval_requested, approval_approved, approval_denied or approval_used. Approval events are recorded under the requesting key. Removing a rulebook records policy_set with a null intent. Autonomy also records autonomy_clean once per allowed reservation or cache/tool authorization, autonomy_state for derived progress, and breaker for an agent breaker event.Per request
decisiontextallow, deny or approval_required for a decision; null for changes; breaker_request stores the batch decision.Per request
reasonsjsonbFixed reason codes and router-written messages; policy change events carry an empty list except a scheduled resume, which carries code scheduled and the fixed message Scheduled stop ended. G161: outside_work_hours and approval_work_hours messages include the computed next opening, its UTC instant and the owner-selected validated time zone.Cannot hold request content. Only evaluator-defined codes and router-written messages are stored. No request text or principal-written kill reason is copied into this field. Work-hour messages also contain a derived date and validated time zone configuration; they do not contain inference text.Per request
intentjsonbInference model, lane, estimated pico-USD cost, maximum output tokens and declared tool names; or an MCP tool name; action intents include a readable action and optional target (including recipient wallets or hosts), an amount and optional order digest, never full order details. Outcome events include the decision id, reported status and amount and whether it exceeded the requested amount. Approval and breaker_request events may contain an intents array for the full model set. Breaker counters read these routing identifiers and decisions; legacy decision events without a batch marker count individually. Resume resets breaker observations, leaving cap spend unchanged. Null for policy changes. An autonomy_state checkpoint stores only rung number, rung since timestamp, clean request count and last clean timestamp. Autonomy clean and breaker events have null intent; none stores prompt text.Settings written by you or an operator. Explicit metadata projection excludes messages, tool arguments, descriptions and answers. Model and tool identifiers are readable labels from the request or catalogue; a caller can choose what a declared tool name means.Per request
policy_sha256textDigest of the evaluated or changed rulebook.Per request
prev_hashtextThe previous retained chain head, or 64 zeros when no preceding event remains.Per request
hashtextSHA-256 of prior hash bytes and canonical event fields excluding id, prev_hash and hash.Per request
agent_profilesNot about requests · 4 columns · 2 reviewed

Opt-in public agent cards and an internal mapping to the owned key for updates, removal and selected live rulebook summaries.

How long: Until unpublish or deletion of the key. Profile updates replace settings and certificates. Database backups and copies made by public readers can outlive deletion.

  • Public: random slug, owner-written name, description, optional homepage, optional payout wallet, capability tags, only selected boolean rulebook categories, and selected router-issued certificates while signatures and expiry are valid. Publishing intentionally links certificate pseudonyms to this profile. The private key-hash mapping is never returned publicly; the router still knows it. Disabled or expired keys are hidden. No certificate or rulebook proves host sealing or hardware attestation, which is reported unavailable. User-written text can identify its owner. No inference prompt or answer is collected here.
ColumnWhat it holdsAbout a request
slugtextRandom 144-bit public identifier independent of the key hash; regenerated after unpublish and republish.Not about requests
key_hashtextInternal unique key association for ownership checks and current opted-in policy categories; never returned in public cards.Not about requests
settingsjsonbValidated public display name, short description, optional HTTP(S) homepage, optional HTTPS agent endpoint (probed daily for liveness when AGENT_IDENTITY_ENABLED is on), optional payout wallet that other agents pay directly in USDG, capability tags and selected rulebook categories.Settings written by you or an operator. Owner-supplied publication settings deliberately become public. They contain bounded text and chosen category names, never a copied private rulebook or automatic key identifiers.Not about requests
certificatesjsonbLatest router-issued certificate for the selected key and chosen claims; replaced or cleared on each publication update.Cannot hold request content. Strict signed claim identifiers, fresh pseudonym, issuance and expiry times, signing key identifier and signature. Valid certificates are public; expired or invalid certificates stay stored until update or deletion but are not returned publicly.Not about requests
agent_sessionsNot about requests · 11 columns · 1 reviewed

A short-lived sub-key for one agent run, with its own budget and expiry, so an agent's spending can be capped and ended.

How long: Ended sessions keep their row; a session ends at its expiry, when its budget is spent or when its owner ends it.

ColumnWhat it holdsAbout a request
idtextSession id.Not about requests
account_idtextThe account the session belongs to.Not about requests
parent_key_hashtextThe key that created the session.Not about requests
key_hashtextThe session's own key hash (a row in keys).Not about requests
nametextA label the creator gave the session.Not about requests
budgetbigintThe session's spend cap in pico-USD; empty means only the parent key's limits apply.Not about requests
expires_attimestamp with time zoneWhen the session ends by itself.Not about requests
ended_attimestamp with time zoneWhen it ended.Not about requests
end_reasontextended, expired or budget.Not about requests
metadatajsonbLabels the creator attached to the session: up to 32 short string, number or boolean values, 2 KB in all.Settings written by you or an operator. checkMetadata refuses key names that look like prompt or completion text (such as prompt or messages), at most 32 keys, string values of at most 256 characters and 2,048 bytes in all. It cannot judge what a creator types into a value, so the text is whatever the creator wrote.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
blind_keysNot about requests · 12 columns

Issuer keys for blind tokens (Privacy Pass): one per epoch and denomination. Nothing here links a buyer to a token.

How long: The private half is wiped when the epoch stops issuing; the public half stays so old tokens remain verifiable.

ColumnWhat it holdsAbout a request
key_idtextThe token key id: hex SHA-256 of the RFC 9578 public key info.Not about requests
epochintegerThe epoch the key issues in.Not about requests
denominationintegerToken units a token from this key is worth.Not about requests
unit_pricebigintPico-USD per token unit, fixed when the key is made.Not about requests
spkitextThe public key, base64url.Not about requests
private_enctextThe private key, AES-GCM encrypted with APP_SECRET. Null once the key no longer issues.Not about requests
valid_fromtimestamp with time zoneWhen the key started.Not about requests
issue_untiltimestamp with time zoneWhen it stops signing new tokens.Not about requests
redeem_untiltimestamp with time zoneWhen tokens from it stop being accepted.Not about requests
revoked_attimestamp with time zoneWhen it was revoked, if it was.Not about requests
issuedbigintHow many tokens were signed: a count and nothing else.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
blind_nullifiersPer request · 6 columns

Spent blind tokens, one row per token including each member of a request set reserved atomically. A row holds the SHA-256 of a token so it cannot be spent twice; the issuer cannot connect that hash to the blinded request it signed.

How long: A reservation is deleted if the request fails before anything is served; spent rows are kept so a token cannot be replayed.

ColumnWhat it holdsAbout a request
nullifiertextSHA-256 of the token.Per request
key_idtextThe issuer key that signed it.Per request
statustextreserved while a request runs, spent once served.Per request
reserved_attimestamp with time zoneWhen the token was reserved.Per request
spent_attimestamp with time zoneWhen the request it paid for was served.Per request
generation_idtextThe generation the token paid for; all members of a set share it, linking those redeemed tokens to the same request but never to a purchase.Per request
byok_keysNot about requests · 6 columns

A provider API key an account brought so calls to that provider use its own account there. Stored encrypted; only the router can decrypt it, to make calls for that account.

How long: Kept until the owner deletes it (DELETE /api/v1/byok/:provider removes the row).

ColumnWhat it holdsAbout a request
idtextRow number, counting up from 1.Not about requests
account_idtextThe account that brought the key.Not about requests
provider_idtextThe provider the key is for.Not about requests
key_enctextThe provider key, AES-256-GCM encrypted with the router's APP_SECRET.Not about requests
labeltextA masked label so the owner can tell keys apart.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
key_topupsSummed from requests · 14 columns

One row per auto top-up of a key's limit, and one per top-up the router skipped and why (once per key, reason, limit and week). No money moves: the limit is an allowance on the account's own balance. Activity and the inbox show these rows.

How long: No automatic deletion, and rows are never changed after they are written.

ColumnWhat it holdsAbout a request
idtextRandom record id.Summed from requests
reftextWhat triggered it: settle:<hold id> after a debit, reserve:<request id> when the key's limit would refuse a request, or skip:<key hash>:<reason>:<limit>:<week> for a skipped top-up. Unique, so each is recorded once.Summed from requests
key_hashtextThe key whose limit was raised.Summed from requests
account_idtextThe account the key belongs to.Summed from requests
outcometextadded, skipped_balance (the account's available credits did not cover the key's allowance after it), skipped_weekly (the rule's weekly maximum) or skipped_org_budget (the team's org budget).Summed from requests
amount_picobigintThe rule's top-up amount in pico-USD.Summed from requests
limit_before_picobigintThe key's limit before, in pico-USD.Summed from requests
limit_after_picobigintThe key's limit after; the same as before when skipped.Summed from requests
spent_picobigintThe key's spend counted against its limit when checked, in pico-USD.Summed from requests
available_picobigintThe account's balance minus open holds when checked, in pico-USD.Summed from requests
week_starttimestamp with time zoneUTC Monday 00:00 of the week the top-up counts in.Summed from requests
week_total_picobigintTop-ups added to the key that week, including this one when added, in pico-USD.Summed from requests
max_per_week_picobigintThe rule's weekly maximum, in pico-USD.Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests
keysNot about requests · 30 columns · 6 reviewed

One row per API key. The secret is never stored: the row holds its SHA-256 and a masked label. It also holds the key's limits, budget and spend.

How long: Deleting a key only disables it (DELETE /api/v1/keys/:hash sets disabled); the row stays because generations and balances refer to it.

ColumnWhat it holdsAbout a request
key_hashtextSHA-256 of the key's secret. The secret itself is never stored.Not about requests
chain_key_hashtextkeccak256 of the address derived from the secret, the id the on-chain contracts use for the key.Not about requests
key_addresstextThe blockchain address derived from the key's secret. It is public on chain when the key is funded.A wallet address, not a network address. A blockchain address derived from the key, not a network address of a caller.Not about requests
account_idtextThe account the key belongs to.Not about requests
parent_hashtextFor a key made from another key (an agent session), the parent's key hash.Not about requests
projecttextOwner-chosen default project label, lowercased, 1–48 letters, digits, dots, underscores or hyphens. PATCH replaces or clears it. Not a secret; retained with the key even after disabling.Not about requests
nametextThe label the owner gave the key.Not about requests
labeltextA masked display form of the key, such as sk-ar-v1-abcd...wxyz: the first and last few characters only.Not about requests
budgetbigintThe key's spend limit in pico-USD. Empty means unlimited.Not about requests
budget_resettextHow often the budget resets: daily, weekly or monthly, or never.Not about requests
period_starttimestamp with time zoneWhen the current budget period began.Not about requests
spentbigintSpend in the current budget period, in pico-USD.Summed from requests
spent_totalbigintAll-time spend of the key, in pico-USD.Summed from requests
rpmintegerRequests-per-minute limit for the key.Not about requests
tpmintegerTokens-per-minute limit for the key.Not about requests
team_idtextThe team the key belongs to, when it has one.Not about requests
allowed_modelstext[]If set, the only models the key may call.Not about requests
allowed_ipstext[]The owner-set list of up to 32 IPv4 or IPv6 addresses or CIDR ranges from which this key may be used. Null means no IP restriction. Observed request addresses are compared in memory and never copied here or logged by this feature.Settings written by you or an operator. Network restrictions written explicitly by the owner through key-edit authentication, validated as IPs or CIDRs. This is retained configuration, not a record of callers or calls.Not about requests
pay_with_defaulttextThe Stock Token symbol the key pays with by default.Not about requests
scopetextNull keeps account access; inference permits model calls and this key’s own generation and receipt reads only; read permits only explicitly listed account GET records, with owner read visibility and no spending, writes, wallet actions or secret access.Not about requests
include_byok_in_limitbooleanStored compatibility selection. Provider-side BYOK expenditure is not tracked; usage counts router-billed charges once.Not about requests
managementbooleanWhether the key may manage other keys.Not about requests
routingjsonbImported routing presets: model aliases and default provider preferences the owner set for this key.Settings written by you or an operator. Routing settings written by the key's owner and validated as aliases and provider preferences; there is no field for message text.Not about requests
guardrailsjsonbThe key's input guardrails: PII mode, phrases to block, a maximum input length and whether to redact output.Settings written by you or an operator. The owner's filter settings. Deny phrases are words the owner wants blocked (up to 50 of 200 characters); they are rules, not requests.Not about requests
tracingjsonbWhere the key's owner asked for traces of this key's public-lane calls to go (their own OpenTelemetry collector, Langfuse or Helicone), and whether to include prompt and completion text. The destination URL and credentials are AES-256-GCM encrypted with APP_SECRET and never returned by the API.Settings written by you or an operator. Destination settings written by the key's owner: a type, flags, a masked host, header names and one sealed string. The schema has no field for message text; content is only ever sent to the owner's destination, never stored here.Not about requests
topupjsonbThe key's auto top-up rule, or empty: below_usd, add_usd and max_per_week_usd. When the key has less than below_usd of its limit left, the router raises the limit by add_usd from the account's own credits, at most max_per_week_usd per UTC week.Settings written by you or an operator. Three numbers written by the key's owner and checked against a strict schema; there is no field for text.Not about requests
disabledbooleanWhether the key is turned off.Not about requests
expires_attimestamp with time zoneWhen the key stops working, if it expires.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
last_usedtimestamp with time zoneWhen the key last made a call.Per request
ohttp_keysNot about requests · 11 columns

Oblivious HTTP gateway keys, one per epoch. Their public halves are published; each private half is destroyed when its epoch's window ends.

How long: The private half is destroyed when the epoch's acceptance window ends, after which recorded traffic for that epoch can no longer be opened. The public half stays.

ColumnWhat it holdsAbout a request
epochintegerThe key's epoch.Not about requests
key_idintegerThe 8-bit key identifier of the key configuration (epoch mod 256).Not about requests
kem_idintegerThe HPKE KEM identifier.Not about requests
public_keytextThe public key, base64url.Not about requests
configtextThe encoded key configuration (RFC 9458), base64url.Not about requests
config_sha256textSHA-256 of that configuration.Not about requests
private_enctextThe private key, AES-GCM encrypted with APP_SECRET. Null once destroyed.Not about requests
valid_fromtimestamp with time zoneWhen the key starts to be used.Not about requests
accept_untiltimestamp with time zoneRequests to this key are opened until here.Not about requests
revoked_attimestamp with time zoneWhen it was revoked, if it was.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
playbook_changesNot about requests · 13 columns · 1 reviewed

A record of every playbook change (create, update, rename, delete) with its version, digest, rules and the number of keys following it; changes to a team's playbooks also appear in the team inbox.

How long: Rows remain until operator deletion, including after the playbook is deleted.

  • G161: Optional work_hours keeps selected weekdays, local start/end clocks, an Intl-validated IANA time zone and refuse/ask_first mode in the existing readable rulebook JSON. Current rules, playbook copies and saved history retain it under their existing retention rules. No new table, column, Redis family, log field or request-body/address reader. The router still reads ordinary request text in memory.
ColumnWhat it holdsAbout a request
idbigserialMonotonically allocated change identifier.Not about requests
playbook_idtextThe playbook changed; kept after the playbook is deleted.Not about requests
account_idtextThe owning account.Not about requests
team_idtextThe owning team, or null for an account-wide playbook.Not about requests
nametextThe playbook's name after this change.Not about requests
actiontextcreate, update (new rules and version), rename or delete.Not about requests
versionintegerThe playbook's version after this change.Not about requests
sha256textSHA-256 of the canonical rules after this change.Not about requests
specjsonbThe rules as of this change, so each recorded digest can be checked.Settings written by you or an operator. A copy of a playbook's strict rulebook: owner-written configuration validated against a schema that excludes prompt and answer fields.Not about requests
followersintegerHow many keys followed the playbook when it changed.Not about requests
actortextHash of the principal key that made the change.Not about requests
notifybooleanWhether the change belongs to a team (a team playbook, or an account-wide one in an account with teams); updates marked so appear in the inbox of the team's owners and admins.Not about requests
attimestamp with time zoneWhen the change was recorded, at millisecond precision.Not about requests
playbooksNot about requests · 10 columns · 1 reviewed

Shared rulebooks (playbooks): one named rulebook that many keys of an account or team follow, so one change applies to all of them.

How long: Until a principal deletes the playbook. Deleting is refused while keys follow it unless they each keep its rules as their own.

  • The rules are the same strict rulebook as agent_policies.spec and carry the same owner-written labels. The name is owner-written text of at most 100 characters. No prompt or answer fields are accepted.
  • G161: Optional work_hours keeps selected weekdays, local start/end clocks, an Intl-validated IANA time zone and refuse/ask_first mode in the existing readable rulebook JSON. Current rules, playbook copies and saved history retain it under their existing retention rules. No new table, column, Redis family, log field or request-body/address reader. The router still reads ordinary request text in memory.
ColumnWhat it holdsAbout a request
idtextRandom playbook identifier.Not about requests
account_idtextThe account that owns the playbook.Not about requests
team_idtextThe team whose owners and admins may change it, or null for an account-wide playbook that only management keys change.Not about requests
nametextOwner-chosen name, unique within the account regardless of case.Not about requests
specjsonbThe playbook's current rulebook, validated by the same strict schema as a key's own rulebook.Settings written by you or an operator. The strict rulebook schema excludes prompt and answer fields. Model, tool and action labels are owner-written identifiers of at most 160 characters; their contents are whatever the owner chooses to write.Not about requests
sha256textSHA-256 of the canonical rulebook JSON, the same digest each following key's rulebook carries.Not about requests
versionintegerCounts rule changes: 1 at creation, plus one for each change of rules. A rename keeps it.Not about requests
created_attimestamp with time zoneWhen the playbook was created.Not about requests
updated_attimestamp with time zoneWhen its name or rules last changed.Not about requests
updated_bytextHash of the principal key that made the last change.Not about requests
policy_versionsNot about requests · 7 columns · 1 reviewed

Saved revisions of each key's rulebook, copied atomically when its rules are saved, restored, allowed next time or copied from a playbook.

How long: Until operator deletion, including after removal of the current rulebook. The migration copies the current rules only; it cannot recover earlier versions.

  • Readable rulebooks include owner-written model, tool, action and target labels. Shape checks cannot judge the meaning an owner gives a label. No inference prompt or answer fields are accepted. Backfilled date and actor use the current row's last update, which can be a Stop or Resume.
  • G161: Optional work_hours keeps selected weekdays, local start/end clocks, an Intl-validated IANA time zone and refuse/ask_first mode in the existing readable rulebook JSON. Current rules, playbook copies and saved history retain it under their existing retention rules. No new table, column, Redis family, log field or request-body/address reader. The router still reads ordinary request text in memory.
ColumnWhat it holdsAbout a request
idbigserialMonotonically allocated revision identifier; repeated saves of the same digest remain separate revisions.Not about requests
key_hashtextThe API key governed by this saved rulebook.Not about requests
sha256textSHA-256 of the canonical rulebook JSON.Not about requests
specjsonbComplete strict rulebook as saved, including caps, models, lanes, tools, hours, approvals, actions and optional rules.Settings written by you or an operator. The strict rulebook schema excludes inference prompt and answer fields; owner-written labels remain readable and may carry whatever meaning the owner chooses.Not about requests
saved_attimestamp with time zoneWhen the revision was retained; for the migration copy, the current rulebook row's last update time.Not about requests
saved_bytextHash of the principal key that saved this revision; backfill uses the current row's last updater.Not about requests
sourcetextsave, approve_and_allow, restore or playbook; backfill uses save for own rules and playbook for following keys.Not about requests
team_auditNot about requests · 9 columns · 1 reviewed

A team's audit log: who changed members, keys, budgets, presets, routes and lane settings, and when. Each entry is hash-chained to the one before it, so an export can be checked offline (scripts/verify-audit.mjs). It records settings changes only, never what anyone asked a model.

How long: No automatic deletion, and rows are never changed after they are written. A database trigger rejects UPDATE and DELETE.

ColumnWhat it holdsAbout a request
team_idtextThe team.Not about requests
seqintegerThe entry's position in the team's chain: 1, 2, 3, ...Not about requests
attimestamp with time zoneWhen the change was made.Not about requests
actortextWho made it: key:<first 16 hex digits of the key hash>, passkey:<member id> or wallet:<address>.Not about requests
actiontextWhat changed, such as member.join, key.create, budget.set, preset.save or route.update.Not about requests
targettextWhat it changed: a key hash, member id, invite hash prefix, preset or route name.Not about requests
detailjsonbA few fixed fields about the change: a role, a limit, a lane, a version and hash, the names of the fields that changed.Settings written by you or an operator. Fields chosen by the router for each action (src/teams/audit.ts, src/api/teams.ts): no free text from a call, and for presets only the version, hash and lane, never the system prompt.Not about requests
prev_hashtextThe previous entry's hash (64 zeros for the first entry).Not about requests
hashtextsha256(prev_hash bytes || canonical JSON of the entry).Not about requests
team_membersNot about requests · 5 columns

Which keys are in which team and their role.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
team_idtextThe team.Not about requests
key_hashtextThe member key's hash.Not about requests
roletextowner, admin, dev, viewer or agent (member is the older default).Not about requests
principal_idtextFor a key issued when a member signed in with a passkey or wallet, that member (team_principals.id).Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
team_principalsNot about requests · 11 columns

Members of a team who sign in without an API key: a passkey (WebAuthn) or a wallet. There is no email, name or device information: a passkey row holds only its credential id and public key (attestation is not requested), a wallet row only its address.

How long: Kept while the team exists; revoking a member disables the row and the keys issued to it.

ColumnWhat it holdsAbout a request
idtextMember id (tp_...).Not about requests
team_idtextThe team.Not about requests
kindtextpasskey or wallet.Not about requests
subjecttextFor a passkey, its credential id (random bytes the authenticator chose, base64url); for a wallet, its address.Not about requests
public_keytextThe passkey's public key (COSE, base64url). It can check signatures, not make them.Not about requests
algintegerThe passkey's signature algorithm: -7 ES256, -8 EdDSA or -257 RS256.Not about requests
sign_countbigintThe passkey's signature counter, so a cloned authenticator is noticed.Not about requests
roletextThe member's role: owner (the bound owner wallet), admin, dev or viewer.Not about requests
disabledbooleanWhether the member was revoked.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
last_usedtimestamp with time zoneWhen the member last signed in.Not about requests
teamsNot about requests · 8 columns · 1 reviewed

A team, also called an organisation: a named group of keys under one owning account, optionally bound to a wallet or a Safe, with an optional org budget.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextTeam id.Not about requests
nametextThe team's name, chosen by its owner.Not about requests
owner_accounttextThe account that owns the team.Not about requests
owner_addresstextThe wallet or Safe that owns the team, once it signed a one-time message (checked by recovery for a wallet, by EIP-1271 isValidSignature for a contract wallet). Empty until one is bound.A wallet address, not a network address. A blockchain address the owner chose to bind, not a network address of a caller.Not about requests
owner_kindtextaccount (no wallet bound), eoa (a wallet) or contract (a Safe or another smart wallet).Not about requests
owner_verified_attimestamp with time zoneWhen the owner's wallet signature was checked.Not about requests
budgetbigintThe org budget in pico-USD: a cap on the sum of the limits of the team's keys. Empty means no cap.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests

Providers & attestation

The provider registry and model catalogue, attestation results, measurements, disclosure profiles and the day-zero model lane.

attestation_eventsNot about requests · 14 columns · 3 reviewed

The public proof-time record: one row per attestor run, canary run or change of the health probe's outcome.

How long: Rows older than ATTESTATION_HISTORY_DAYS (default 30) are pruned by the attestor job (pruneAttestationEvents); 0 turns recording off.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
provider_idtextThe provider.Not about requests
kindtextattestation, canary or probe.Not about requests
tstimestamp with time zoneWhen it happened.Not about requests
okbooleanWhether it passed.Not about requests
reasontextA failure code from a fixed list, empty when it passed.Not about requests
simulatedbooleanWhether the evidence came from development mode; never counts as a fresh attestation.Not about requests
tee_kindtextThe hardware type.Not about requests
attestation_hashtextThe report hash of a passing run.Not about requests
tls_spki_sha256textSHA-256 of the certificate key the connection was pinned to, when pinned.Not about requests
measurementsjsonbDigests and hardware registers of a passing run.Cannot hold request content. Only digests (image, compose, model) and register values; the table's comment states nothing raw from the provider is stored.Not about requests
measurement_changedbooleanWhether the measurement differs from the previous passing run.Not about requests
verifiersjsonbThe names of the verifiers that accepted the quote.Cannot hold request content. A list of verifier names configured by the operator.Not about requests
detailjsonbFurther check results as codes and numbers.Cannot hold request content. Written by the attestation-events code from fixed fields; the table's comment states nothing raw from the provider is stored.Not about requests
attestationsNot about requests · 9 columns · 2 reviewed

The result of each attestation run against a provider: whether it passed, the report hash and the measurements it committed to.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
provider_idtextThe provider.Not about requests
tstimestamp with time zoneWhen the run happened.Not about requests
okbooleanWhether it passed.Not about requests
tee_kindtextThe hardware type.Not about requests
report_hashtextHash of the report.Not about requests
noncetextThe fresh nonce the router sent to prove the report was made for this run.Not about requests
measurementsjsonbThe image, compose and model digests and hardware registers the report committed to.Cannot hold request content. Digests and register values taken from a verified report.Not about requests
detailjsonbWhy a run failed, or which verifiers accepted it, with the signing address and classifier flag, as short strings and flags written by the attestor.Cannot hold request content. Written by attestProvider about a report the router fetched with a fresh nonce. An attestation run starts from the router's schedule, so no caller's request can reach this column.Not about requests
canariesNot about requests · 8 columns · 1 reviewed

Results of quantisation checks: known prompts sent to a provider to see whether it serves the precision it declares. Made from fixed prompts the router wrote itself, not from any customer request.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
model_idtextThe model checked.Not about requests
provider_idtextThe provider checked.Not about requests
tstimestamp with time zoneWhen the check ran.Not about requests
quant_matchbooleanWhether the result matched the declared precision.Not about requests
quant_guesstextThe precision the result looks like.Not about requests
distancerealHow far the result was from the reference.Not about requests
qualityrealA quality score for the result.Not about requests
detailjsonbThe check's accuracy, how many prompts were answered, the declared precision and the fingerprint length.Cannot hold request content. Numbers and the declared precision written by runCanaries (accuracy, answered, declared, logprobs, fingerprint_tokens); the canary prompts are the router's own.Not about requests
canary_referencesNot about requests · 5 columns · 1 reviewed

The reference fingerprint of a model at each precision, which canary results are compared to.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
model_idtextThe model.Not about requests
quanttextThe precision the fingerprint is for: bf16, fp8, int4 and so on.Not about requests
fingerprintjsonbThe model's output fingerprint at that precision for the router's own canary prompts.Cannot hold request content. A model-behaviour fingerprint (token probabilities on the router's own fixed prompts), not a device or network fingerprint and not a customer request.Not about requests
sourcetextWhere the reference came from.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
lane_candidatesNot about requests · 18 columns · 2 reviewed

New open-weights uploads found on Hugging Face that derive from an approved base model, with their evaluation status.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
hf_repotextThe repository.Not about requests
base_modeltextThe base model.Not about requests
revisiontextThe revision seen at discovery.Not about requests
licensetextThe licence.Not about requests
varianttextThe variant.Not about requests
creator_handletextThe uploader's handle.Not about requests
statustextdiscovered, rejected, evaluated, failed, approved or servable.Not about requests
reasontextWhy a candidate was rejected.Not about requests
model_idtextThe catalogue model id it is served under.Not about requests
endpoint_providertextThe provider whose offer for the model is evaluated.A public address, not a caller's. A provider slug (a short name such as deepinfra), not a network address.Not about requests
source_created_attimestamp with time zoneWhen the repository was created.Not about requests
approved_bytextWho approved it.Not about requests
approved_attimestamp with time zoneWhen it was approved.Not about requests
approval_notetextA note written by the approving operator.Settings written by you or an operator. Free text written by an operator when approving a candidate; not derived from any request.Not about requests
servable_attimestamp with time zoneWhen it became servable.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
lane_claimsNot about requests · 11 columns · 1 reviewed

Creator royalty claims: the router issues a challenge, the uploader publishes it in their Hugging Face repository, and the router checks it.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextClaim id.Not about requests
model_idtextThe model.Not about requests
hf_repotextThe repository.Not about requests
handletextThe uploader's Hugging Face handle.Not about requests
addresstextThe wallet address royalties are to be sent to.A wallet address, not a network address. A blockchain wallet address supplied by the creator, not a network address.Not about requests
challengetextThe challenge text the uploader must publish.Not about requests
statustextpending or verified.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
expires_attimestamp with time zoneWhen the challenge expires.Not about requests
verified_attimestamp with time zoneWhen it was verified.Not about requests
onchain_txtextThe transaction that recorded the claim.Not about requests
lane_evalsNot about requests · 11 columns · 1 reviewed

One row per evaluation run of a candidate endpoint: refusal rate, capability score and canary accuracy. Made from fixed prompts the router wrote itself, not from any customer request.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
candidate_idintegerThe candidate evaluated.Not about requests
tstimestamp with time zoneWhen it ran.Not about requests
provider_idtextThe provider evaluated.Not about requests
model_idtextThe model evaluated.Not about requests
refusal_raterealShare of the benign probe prompts that were refused.Not about requests
capability_scorerealShare of the exact-check prompts answered correctly.Not about requests
canary_accuracyrealThe canary exact-match score.Not about requests
canary_quant_matchbooleanWhether the canary matched the declared precision.Not about requests
passedbooleanWhether the candidate passed.Not about requests
detailjsonbScores and counts for the run.Cannot hold request content. Numbers written by the evaluation code; the prompts used are the router's own fixed sets.Not about requests
measurement_bundlesNot about requests · 21 columns · 3 reviewed

Signed measurement bundles: what a provider's measurement is made of, signed with the measurement key, recorded in a public log and verified by the router.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
provider_idtextThe provider.Not about requests
compose_hashtextThe deployment hash the bundle describes.Not about requests
bundle_digesttextSHA-256 of the canonical bundle bytes.Not about requests
bundlejsonbThe bundle itself: the components a measurement is made of.Cannot hold request content. A signed, canonical bundle of digests and component names that an operator hands over and the router verifies.Not about requests
signaturetextThe bundle's signature, base64.Not about requests
signer_key_idtextSHA-256 of the signer's public key info.Not about requests
statustextpending, verified or rejected.Not about requests
rekor_uuidtextThe public-log entry id.Not about requests
rekor_entrytextThe entry hash inside that id.Not about requests
rekor_log_indexbigintThe entry's index in the public log.Not about requests
rekor_integrated_attimestamp with time zoneWhen the public log integrated it.Not about requests
rekor_entry_jsonjsonbThe public-log entry as the log returned it.Cannot hold request content. The response of a public transparency log for the bundle's entry (body, proof, signed timestamp).Not about requests
rekor_inclusion_verifiedbooleanWhether the inclusion proof verified.Not about requests
rekor_checkpoint_verifiedbooleanWhether the log's checkpoint signature verified.Not about requests
rekor_set_verifiedbooleanWhether the signed entry timestamp verified.Not about requests
checked_attimestamp with time zoneWhen the log was last checked.Not about requests
verified_attimestamp with time zoneWhen the bundle verified.Not about requests
errortextWhy the bundle was rejected or could not be checked.Cannot hold request content. An error string produced while verifying a bundle and its public-log entry; nothing in that check involves a caller's request.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
measurementsNot about requests · 32 columns · 1 reviewed

The image, compose and model digests a provider's confidential endpoint has been seen running, each bound into a hardware quote a verifier accepted, with whether the digest was found in a public log.

How long: History is kept: a superseded measurement gets superseded_at and stays.

ColumnWhat it holdsAbout a request
idserialRow number, counting up from 1.Not about requests
provider_idtextThe provider.Not about requests
image_digesttextThe container image digest.Not about requests
compose_hashtextThe hash of the deployment definition.Not about requests
model_digesttextThe digest of the model weights.Not about requests
statustextobserved, ready, registered or revoked.Not about requests
verifiertextWhich verifiers accepted the quote, comma separated.Not about requests
tee_kindtextThe hardware type.Not about requests
quotetextThe verified hardware quote, hex.Not about requests
quote_proof_hashtextkeccak256 of the quote bytes.Not about requests
report_hashtextThe attestation report hash that produced the row.Not about requests
attested_attimestamp with time zoneWhen it was attested.Not about requests
last_seen_attimestamp with time zoneWhen it was last seen.Not about requests
rekor_uuidtextThe public-log entry id, when found.Not about requests
rekor_entrytextThe entry hash inside that id.Not about requests
rekor_log_indexbigintThe entry's index in the public log.Not about requests
rekor_kindtextThe entry type.Not about requests
rekor_integrated_attimestamp with time zoneWhen the public log integrated it.Not about requests
rekor_inclusion_verifiedbooleanWhether the inclusion proof verified.Not about requests
rekor_checkpoint_verifiedbooleanWhether the log's checkpoint signature verified.Not about requests
rekor_checked_attimestamp with time zoneWhen the public log was last checked.Not about requests
rekor_errortextThe last error from checking the public log, as a short code or message.Cannot hold request content. An error string produced while looking up a public log entry; nothing in this lookup involves a caller's request.Not about requests
calldatatextPrepared registry call data, when built.Not about requests
calldata_targettextThe registry contract it is for.Not about requests
calldata_built_attimestamp with time zoneWhen it was built.Not about requests
tx_hashtextThe registering transaction.Not about requests
registered_attimestamp with time zoneWhen it was registered.Not about requests
revoked_attimestamp with time zoneWhen it was revoked.Not about requests
superseded_attimestamp with time zoneWhen a later verified quote committed to other digests.Not about requests
superseded_byintegerThe row that replaced this one.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
modelsNot about requests · 12 columns · 2 reviewed

The model catalogue: id, name, context length, modalities and creator.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextModel id, author/slug.Not about requests
authortextThe author part of the id.Not about requests
nametextDisplay name.Not about requests
descriptiontextA short description of the model, from the provider listing or an operator.Settings written by you or an operator. Descriptive text about a model from provider listings; it is catalogue data, not a request.Not about requests
ctxintegerContext length in tokens.Not about requests
max_outintegerMaximum output tokens.Not about requests
archjsonbModality, input and output modalities, tokenizer and instruction type.Cannot hold request content. Fixed catalogue fields about the model: modality, input_modalities, output_modalities, tokenizer, instruct_type.Not about requests
hf_repotextThe Hugging Face repository the weights come from, when known.Not about requests
creatortextThe creator's payout address, when known.Not about requests
royalty_bpsintegerThe creator's royalty in basis points.Not about requests
created_unixintegerWhen the model was created, in Unix seconds.Not about requests
hiddenbooleanWhether the model is hidden from listings.Not about requests
models_laneNot about requests · 10 columns

Per-model metadata for open-weights variants: which lane a model can be served on, its base model, licence and weights source.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
model_idtextThe model.Not about requests
varianttextmainstream, native_low_refusal or abliterated.Not about requests
statustextservable or candidate (not approved for serving).Not about requests
base_modeltextThe model it derives from.Not about requests
licensetextThe licence identifier from the weights' model card.Not about requests
weights_sourcetextWhere the weights come from.Not about requests
weights_revisiontextThe commit the weights were taken from.Not about requests
weights_digesttextSHA-256 of the weights manifest, when there is one.Not about requests
creator_handletextThe uploader's Hugging Face handle.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
offersNot about requests · 19 columns · 1 reviewed

What one provider charges to serve one model, and the model's features at that provider.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
model_idtextThe model.Not about requests
provider_idtextThe provider.Not about requests
provider_model_idtextThe id the provider uses for the model.Not about requests
price_promptbigintPico-USD per prompt token.Not about requests
price_completionbigintPico-USD per completion token.Not about requests
price_requestbigintPico-USD per request.Not about requests
price_imagebigintPico-USD per image.Not about requests
price_reasoningbigintPico-USD per reasoning token.Not about requests
price_cache_readbigintPico-USD per cached prompt token.Not about requests
price_cache_writebigintPico-USD per token written to cache.Not about requests
quanttextQuantisation, such as fp8, or unknown.Not about requests
ctxintegerContext length at this provider.Not about requests
max_outintegerMaximum output tokens at this provider.Not about requests
supported_parameterstext[]Request parameters the provider supports.Not about requests
featuresjsonbFeature flags such as tools or json mode.Cannot hold request content. Feature flags and limits read from the provider's model listing; about the offer, not any request.Not about requests
is_moderatedbooleanWhether the provider moderates content.Not about requests
statustextlive, shadow or disabled.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
provider_disclosureNot about requests · 8 columns · 2 reviewed

What a provider says, and can prove, about how it handles a prompt: retention, jurisdiction, legal hold and training use, each with a source and a date. Curated by an operator, or retention alone set after network sidecar attestation and signed host policy verification; nothing here comes from traffic.

How long: Kept and replaced in place when an operator updates a provider's profile or a network host passes admission or scheduled policy renewal; removed on network rejection.

ColumnWhat it holdsAbout a request
provider_idtextThe provider.Not about requests
retentiontextattested, policy or logs (the most conservative when there is no row).Not about requests
jurisdictiontextThe provider's jurisdiction, or unknown.Not about requests
training_usetextnone, opt_in, yes or unknown.Not about requests
claimsjsonbFor each stated value, the document it comes from and its date.Cannot hold request content. A map of claim name to { source, as_of } written by an operator. Network admission and scheduled renewal record only retention with the checked host policy version and current time; the host dashboard reads this version and time to describe current build approval without storing another record; jurisdiction, legal hold and training use remain undeclared.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
providersNot about requests · 29 columns · 9 reviewed

The provider registry: each upstream that serves models, how to reach it, its status, whether its software is attested, and its bond and payout details.

How long: Kept while the provider is listed; a provider that leaves is delisted (status), not deleted.

ColumnWhat it holdsAbout a request
network_hostbooleanWhether this provider was created by wallet-authenticated self-serve network signup; false for existing providers.Settings written by you or an operator. A boolean indicating the admission path, despite its network-related name. It cannot contain an address or any text.Not about requests
network_modelstext[]One to eight distinct requested model IDs supplied by the wallet operator, retained for network admission and re-application; separate from priced catalogue entries.Not about requests
network_reasonsjsonbCurrent admission or scheduled renewal refusal reasons, returned publicly by the network status and host dashboard APIs.Cannot hold request content. Admission and scheduled renewal write policy and screening explanations and attestor failure messages about operator-supplied endpoints and model IDs. No inference body, key or contact is included; endpoint failure messages may name the host server.Not about requests
idtextProvider slug, such as deepinfra.Not about requests
nametextDisplay name.Not about requests
base_urltextThe provider's API address that the router calls.A public address, not a caller's. The address of a provider's server, set by the operator. It is not a caller's address.Not about requests
api_key_enctextThe router's own key at that provider, AES-256-GCM encrypted with APP_SECRET.Not about requests
kindtextopenai for a standard API, tee for an attested endpoint, sidecar for a network host.Not about requests
headersjsonbExtra HTTP headers the router sends to that provider on every call, usually credentials. Stored only as one AES-GCM ciphertext under the router's APP_SECRET.Settings written by you or an operator. Fixed headers the provider's operator supplied in its application, stored encrypted (encrypted_v1). Nothing from a caller's request is ever written to it.Not about requests
data_policyjsonbWhat the provider says about training on prompts, retaining them, retention days and zero-data-retention, as entered by the operator or the provider.Cannot hold request content. Fixed fields (training, retains_prompts, retention_days, zdr, moderated) validated on entry; about the provider's policy, not about any request.Not about requests
datacentertext[]Regions the provider lists.Not about requests
attestedbooleanWhether the provider's last verified attestation passed.Not about requests
attestation_urltextWhere the provider publishes its attestation report.A public address, not a caller's. The address of a report on a provider's server, set by the operator.Not about requests
attestation_hashtextHash of the last attestation report the router verified.Not about requests
attested_attimestamp with time zoneWhen it was verified.Not about requests
tee_kindtextThe hardware type: tdx, snp, nvidia-cc, tinfoil or dev.Not about requests
classifier_enabledbooleanWhether the last verified attestation reported the in-enclave hard-block classifier as enabled.Not about requests
bond_usdgbigintThe provider's bond in USDG base units.Not about requests
anyr_stakebigintThe provider's $ANYR stake in base units.Not about requests
operatortextThe operator's name.Not about requests
payout_modetextinvoice or usdg.Not about requests
payout_addresstextThe wallet address payouts go to, when the provider is paid in USDG.A wallet address, not a network address. A blockchain wallet address for payouts, not a network address of a caller.Not about requests
statustextapplied, shadow, live, suspended or delisted; network signup uses pending, probation or rejected.Not about requests
shadow_untiltimestamp with time zoneWhen a shadow provider is due to be considered for live, or the end of a network host probation period.Not about requests
timeout_msintegerRequest timeout for this provider.Not about requests
static_modelsjsonbA model list with prices for providers whose own listing lacks pricing, or network probation offers copied from the signed policy for requested quote-bound model IDs. Rejection clears this list and disables retained offers.Cannot hold request content. A list of model IDs, catalogue slugs, names, optional Hugging Face IDs and quantization, prices, token limits and text modalities entered by an operator and checked before it is applied. Network admission copies these terms only after published-policy signature and hardware quote binding verification.Not about requests
contacttextA contact for the provider's operator, as given in the provider application.Settings written by you or an operator. A contact detail for the provider's operator, given by the operator in a provider application. It is not about callers.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests

Chain

Blockchain events the router has read, escrow deposits, pay-with sessions and swaps, provider payouts and slashes.

agent_paymentsPer request · 24 columns · 1 reviewed

One row per allowed pay.agent decision: who asked, the recipient wallet and amount Agent Guard allowed, and, once confirmed, the USDG transfer found on Robinhood Chain and the signed payment receipt. Anyroute never holds or moves this money; no balance changes. Disabled unless AGENT_PAY_ENABLED.

How long: No automatic deletion: no job or route in the code removes rows from this table. The status changes from seen to final at the chain's finality point, or to reversed if the transfer leaves the canonical chain within ESCROW_REORG_HORIZON_BLOCKS.

  • Recipient and payer wallets and the transaction are public on chain and can be correlated with the agent key that asked. Paying a public profile id also stores that profile and its key hash, so the recipient's owner sees the payment in their inbox. An optional memo is accepted only as a SHA-256 digest; the memo itself is never sent to the router.
ColumnWhat it holdsAbout a request
decision_idtextThe Agent Guard decision (agent_action_decisions.id) this payment belongs to; random, not a credential.Per request
key_hashtextHash of the paying agent key; only that key confirms the payment.Per request
account_idtextAccount of the paying key, whose linked wallets may send the transfer.Per request
policy_sha256textDigest of the rulebook (or sorted rulebook digests) the decision was made under.Per request
recipient_profiletextPublic profile id that was paid, or that publishes the paid wallet; null for a wallet with no single profile.Per request
recipient_key_hashtextKey hash behind that profile, used only to show the payment in its owner's inbox; never returned publicly.Per request
recipient_wallettextLowercase 0x wallet that receives the USDG.Per request
amount_unitsnumeric(78, 0)Allowed amount in USDG base units (6 decimals).Per request
memo_sha256textOptional SHA-256 digest of the payer's memo; the memo is not stored.Per request
statustextawaiting_transfer, seen (waiting for finality), final or reversed.Per request
status_attimestamp with time zoneWhen the status last changed.Per request
created_attimestamp with time zoneWhen the row was created.Per request
tx_hashtextThe confirming Robinhood Chain transaction (public); unique with its log index.Per request
log_indexintegerLog index of the USDG Transfer that pays the decision.Per request
block_numberbigintBlock of that transfer.Per request
block_hashtextCanonical hash of that block when last checked.Per request
payer_wallettextLinked wallet the USDG was sent from.Per request
paid_unitsnumeric(78, 0)USDG base units actually transferred; counted against the daily action limit.Per request
verified_attimestamp with time zoneWhen the router first verified the transfer.Per request
checked_attimestamp with time zoneWhen it was last re-verified.Per request
reasontextFixed reason text when a payment is reversed.Per request
receiptjsonbThe signed payment receipt payload (anyroute.agent.payment.v1): decision, rulebook digest, payer, recipient, amounts, chain, transaction, block and status.Cannot hold request content. Canonical JSON built by src/agents/pay.ts from the fields of this row; wallets, hashes, amounts and fixed codes only, no request or answer text.Per request
receipt_sigtextEd25519 signature over the canonical receipt, by the router's receipt key; re-signed on each status change.Per request
receipt_key_idtextId of the receipt key that signed it.Per request
agreement_cursorNot about requests · 5 columns · 1 reviewed

Finality-aware resumable agreement event cursor and cross-worker serialization lock.

How long: Public chain journal and projections remain until the operator removes the agreement index. Orphaned events and projections are removed and replayed on reorganization.

ColumnWhat it holdsAbout a request
scopetextChain id, configured escrow and oracle addresses; isolates deployments.Not about requests
blockbigintLast canonical scanned block number.Not about requests
block_hashtextHash at the canonical scan endpoint.Not about requests
checkpointsjsonbUp to 128 scan endpoint block/hash pairs used to find a canonical reorg rewind point.Cannot hold request content. Only decoded public agreement event values and canonical block metadata are stored: wallets, USDG amounts, hashes, identifiers, bps and timestamps. No inference or evidence content is accepted into the chain journal or projection.Not about requests
checked_attimestamp with time zoneCaught-up scan time, zero during backfill. Jury, posting and deletion require freshness within 120 seconds.Not about requests
agreement_eventsNot about requests · 7 columns · 1 reviewed

Reversible public AgreementEscrow event journal, bounded by confirmation and finality checks.

How long: Public chain journal and projections remain until the operator removes the agreement index. Orphaned events and projections are removed and replayed on reorganization.

ColumnWhat it holdsAbout a request
scopetextChain id, configured escrow and oracle addresses; isolates deployments.Not about requests
tx_hashtextPublic transaction hash, unique with deployment scope and log position.Not about requests
log_indexintegerCanonical log position in a block.Not about requests
blockbigintCanonical event block number.Not about requests
block_hashtextEvent block hash checked against the RPC.Not about requests
eventtextAgreementEscrow milestone lifecycle events and DisputeOracle TallyRecorded, PanelRequired and RulingPosted ABI event names.Not about requests
argsjsonbPublic event arguments: agreement id, payer/payee wallets, USDG base-unit amount, terms/deliverable/evidence hashes, milestone index, deadline, oracle address, review deadline, payout amounts, ruling path and verdict encoding, evidence root, jury version, participation and consensus bitmaps and tally hash. indexedEscrow and indexedOracle identify configured contracts. indexedAt is the canonical block timestamp.Cannot hold request content. Only decoded public agreement event values and canonical block metadata are stored: wallets, USDG amounts, hashes, identifiers, bps and timestamps. No inference or evidence content is accepted into the chain journal or projection.Not about requests
agreement_evidencePer request · 7 columns · 1 reviewed

Party-uploaded text or JSON evidence, encrypted with APP_SECRET and hash-committed. Only the parties have REST access; the router and jury providers read the decrypted bundle.

How long: Evidence and signed jury statements are deleted after canonical resolution plus AGREEMENT_RETENTION_DAYS (30 by default), while agreement-retention runs with a fresh index. Parties may delete their own evidence after that interval. Backups follow the operator backup policy; deletion is not erasure from backups or chain.

ColumnWhat it holdsAbout a request
scopetextChain id, configured escrow and oracle addresses; isolates deployments.Per request
agreement_idtextComposite decimal agreement.milestone identifier from the configured escrow contract.Per request
disputetextCanonical dispute transaction hash and log index, or before-dispute plus the creation transaction/log identity for earlier evidence; prevents reuse of a reorged id from exposing old content.Per request
partytextAuthenticated account wallet matched to the indexed payer or payee, never a caller IP.Per request
sha256textSHA-256 of canonical JSON content before encryption; public to both parties.Per request
contenttextAES-GCM encrypted canonical JSON evidence; may contain arbitrary text including prompts, deliverables and personal information. The router decrypts it for party detail and jury calls. Default cap 16 KiB per item and 32 entries per party. Evidence is not end-to-end encrypted through the router.Holds request text. The feature explicitly persists party-uploaded evidence content. Encryption at rest does not prevent the router or an operator with APP_SECRET from reading it. Only wallet-linked parties can retrieve it through these routes, and configured attested models receive it for adjudication.Per request
created_attimestamp with time zoneTime this record was first saved by the router.Per request
agreement_jurySummed from requests · 11 columns · 1 reviewed

Router-signed model jury statement and durable ruling intent for the canonical dispute. Complete hung tallies may enter the panel path; failed or abstaining votes remain unresolved until a valid tally or expiry. Default consensus status is dry_run.

How long: Evidence and signed jury statements are deleted after canonical resolution plus AGREEMENT_RETENTION_DAYS (30 by default), while agreement-retention runs with a fresh index. Parties may delete their own evidence after that interval. Backups follow the operator backup policy; deletion is not erasure from backups or chain.

ColumnWhat it holdsAbout a request
scopetextChain id, configured escrow and oracle addresses; isolates deployments.Summed from requests
agreement_idtextComposite decimal agreement.milestone identifier from the configured escrow contract.Summed from requests
disputetextCanonical dispute transaction hash and log index, or before-dispute plus the creation transaction/log identity for earlier evidence; prevents reuse of a reorged id from exposing old content.Summed from requests
roottextRFC 6962 SHA-256 Merkle root of canonical header and ordered party-evidence leaves.Summed from requests
statustextdry_run, panel, submitted, posting_failed or posted. A dry_run does not send a transaction. Posted denotes a successful transaction receipt, with escrow state reconciled separately by the index.Summed from requests
statementjsonbSigned jury scope, dispute, root, leaf digests, fixed rubric digest, model list, majority threshold, per-model verdict/reason or fixed failure code, receipt id/link/policy hash, internal router-signed operational receipt with request/response hashes, provider attestation reference including report hash/time/TEE/TLS pin, checked gateway receipt reference and upstream claims, provider-list-price operator cost estimate and token usage (not an invoice; failed calls may incur unmeasured cost), consensus bps, agreeing-model bitmap (separate from on-chain signer-order bitmaps), issuance time and trust notice. Model reasons may quote evidence text.Holds request text. Structured model verdict reasons are answer text and can repeat uploaded evidence. This statement therefore stores answer content openly in the inventory, behind party-only API access and resolution-based retention. The public key log contains public signing material. Chain calldata contains evidence root and per-key basis-point votes with EIP-712 signatures; the oracle records signer-order bitmaps and tally hash. The worker holds one operator-configured private key per model; models do not hold these keys.Summed from requests
key_idtextExisting router Ed25519 receipt signing key id, published in the transparency key log when enabled and always before posting; dry-run can omit the key log.Summed from requests
signaturetextBase64 Ed25519 signature over canonical statement JSON.Summed from requests
posting_txtextHash of the persisted oracle transaction, public once broadcast.Summed from requests
posting_rawtextAPP_SECRET-encrypted signed oracle transaction, saved before broadcast for identical nonce/byte retries. No private signer key is saved here.Summed from requests
created_attimestamp with time zoneTime this record was first saved by the router.Summed from requests
agreement_projectionNot about requests · 4 columns · 1 reviewed

Canonical agreement state rebuilt from the journal; both parties' wallet-linked accounts have API access.

How long: Public chain journal and projections remain until the operator removes the agreement index. Orphaned events and projections are removed and replayed on reorganization.

ColumnWhat it holdsAbout a request
scopetextChain id, configured escrow and oracle addresses; isolates deployments.Not about requests
kindtextFixed agreement projection kind; each row is an individual milestone.Not about requests
idtextComposite decimal agreement.milestone identifier from the configured escrow contract.Not about requests
datajsonbAgreement id and creation transaction/log identity, public payer/payee wallets, amount, terms hash, ordered deliverable hashes, agreement deadline, milestone index, oracle address, review deadline and exact payout amounts, dispute identity/evidence hash/time, resolution time and public on-chain ruling. No uploaded evidence or model reasons.Cannot hold request content. Only decoded public agreement event values and canonical block metadata are stored: wallets, USDG amounts, hashes, identifiers, bps and timestamps. No inference or evidence content is accepted into the chain journal or projection.Not about requests
chain_cursorNot about requests · 3 columns

How far the router has read each chain.

How long: One row per cursor, overwritten as the chain advances.

ColumnWhat it holdsAbout a request
idtextThe cursor's name.Not about requests
blockbigintThe last block read.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
chain_eventsNot about requests · 10 columns · 2 reviewed

Contract events the router has read from the chain, each processed once.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
tx_hashtextThe transaction.Not about requests
log_indexintegerThe log's position in the transaction.Not about requests
contracttextThe contract that emitted it.Not about requests
eventtextThe event name.Not about requests
block_numberbigintThe block.Not about requests
argsjsonbThe event's decoded arguments: addresses, amounts and hashes.Cannot hold request content. Decoded on-chain event arguments; public blockchain data.Not about requests
processedbooleanWhether the router has acted on it.Not about requests
processed_attimestamp with time zoneWhen it did.Not about requests
errortextWhy processing the event failed, when it did.Cannot hold request content. An error string from the chain indexer while handling a public on-chain event; the indexer never sees a request.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
commerce_transfersNot about requests · 9 columns · 2 reviewed

When COMMERCE_STATS_ENABLED and COMMERCE_FUNDING_FROM_BLOCK are set, every USDG Transfer on the configured chain from that block on, so the commerce ledger can tell which wallets funded which. Public chain data only; no account, key, receipt or request is linked to a row.

How long: No automatic deletion: the funding filter reads the whole copy from the start block. Removed only when the operator drops the table or clears the copy.

ColumnWhat it holdsAbout a request
tx_hashtextThe public transaction hash.Not about requests
log_indexintegerThe log's position in the transaction.Not about requests
block_numberbigintThe block.Not about requests
block_timetimestamp with time zoneThe block's time.Not about requests
from_addresstextThe wallet the USDG left.A wallet address, not a network address. A lowercase blockchain wallet or contract address copied from a public USDG Transfer log; not a caller's network address.Not about requests
to_addresstextThe wallet the USDG went to.A wallet address, not a network address. A lowercase blockchain wallet or contract address copied from a public USDG Transfer log; not a caller's network address.Not about requests
value_usdgbigintThe amount in USDG base units, capped at the bigint maximum.Not about requests
authorizedbooleanWhether an EIP-3009 authorization of the sender moved it (an AuthorizationUsed log by the sender in the same transaction).Not about requests
tx_fromtextFor an authorized transfer, the public address that sent the transaction (the relayer); null otherwise.Not about requests
escrow_depositsNot about requests · 21 columns · 2 reviewed

Stock Token, $ANYR and USDG transfers into the escrow wallet: one row per transfer, its price, its status and whether it was credited.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtext<transaction>:<log index>.Not about requests
tx_hashtextThe transaction.Not about requests
log_indexintegerThe log's position in the transaction.Not about requests
block_numberbigintThe block.Not about requests
tokentextThe token contract.Not about requests
symboltextThe token symbol.Not about requests
from_addresstextThe wallet that sent the tokens, as recorded on chain.A wallet address, not a network address. A blockchain wallet address that is public in the transfer itself; not a network address.Not about requests
raw_amountnumeric(78, 0)The amount in token base units.Not about requests
statustextpending_finality, pending, provisional (credited while settling), credited, orphaned or reversed.Not about requests
block_hashtextThe block hash when recorded; the credit is checked against it.Not about requests
account_idtextThe account it was credited to.Not about requests
price18textUSD per whole token at 18 decimals, as read from the price feed (USDG: exactly 1, credited at par).Not about requests
price_updated_attimestamp with time zoneWhen the feed last updated.Not about requests
creditedbigintThe pico-USD credited after the haircut.Not about requests
errortextWhy crediting failed, when it did.Cannot hold request content. An error string from the escrow indexer about an on-chain transfer; no request is involved.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
credited_attimestamp with time zoneWhen it was credited.Not about requests
checked_attimestamp with time zoneWhen the credit was last re-verified against the canonical chain.Not about requests
reversed_attimestamp with time zoneWhen a credit was reversed.Not about requests
review_reasontextSet when an operator has to look: a reversal, or an orphan after finality.Not about requests
reviewed_attimestamp with time zoneSet once an operator has reconciled it.Not about requests
facilitator_settlementsPer request · 21 columns · 1 reviewed

One row per facilitator settle that passed verification: the payer's signed USDG authorization relayed straight to the seller's payTo (or to the treasury for a gas float top-up). (payer, nonce) is unique, so an authorization settles at most once here. Settled rows carry a signed receipt of kind facilitator.settle that joins the hourly anchor.

How long: No automatic deletion: no job or route in the code removes rows from this table.

  • Payer, payTo, amount, nonce and transaction hash are the same facts the public chain shows for the transfer. Payers are not screened: the facilitator never holds the funds it relays.
ColumnWhat it holdsAbout a request
idtextRandom settlement identifier (fst_ followed by 24 hex characters); also the receipt id.Per request
kindtextpayment, or gas_float for a seller's gas float top-up.Per request
payertextLowercase wallet address that signed the authorization.Per request
pay_totextLowercase wallet address the USDG went to.Per request
valuenumeric(78, 0)Authorized USDG base units.Per request
noncetextThe authorization's EIP-3009 nonce.Per request
tx_hashtextRelay transaction hash, once settled.Per request
statustextverified (claimed, relay in flight), settled or failed.Per request
errortextA fixed code for a failed relay (relay_failed).Cannot hold request content. A fixed code written by the facilitator code, never chain error text, a request body or an answer.Per request
seller_idtextListing the payment belongs to, when the payTo has one.Per request
x402_versionsmallintx402 protocol version of the payment, 1 or 2.Per request
fee_valuenumeric(78, 0)USDG base units of the facilitator fee authorization, when a fee is charged.Per request
fee_tx_hashtextTransaction hash of the relayed fee authorization.Per request
gas_debitnumeric(78, 0)USDG base units taken from the seller's gas float for this settle.Per request
settled_attimestamp with time zoneWhen the relay landed and the receipt was signed.Per request
receipt_cosetextThe signed receipt (base64 COSE_Sign1): network, asset, transaction, amount, payTo and fee. It names no payer.Per request
receipt_leaftextThe receipt's leaf hash in the hourly anchoring tree.Per request
receipt_key_idtextReceipt signing key id.Per request
anchor_indexintegerAnchor (Merkle root) this receipt was included in, once rooted.Per request
leaf_indexintegerPosition of the receipt's leaf in that anchor's tree.Per request
created_attimestamp with time zoneWhen the row was created.Per request
host_bond_cursorNot about requests · 5 columns · 1 reviewed

Resumable HostBond event scan cursor, isolated by chain and contract. Serializes scans and slash intents across workers.

How long: Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency.

ColumnWhat it holdsAbout a request
scopetextChain id and HostBond contract address; public chain identifiers.Not about requests
blockbigintLast scanned canonical block, or the deployment block minus one before scanning.Not about requests
block_hashtextCanonical block hash at the scan cursor.Not about requests
checkpointsjsonbUp to 128 scan endpoints as block number/hash pairs. Reorgs rewind to the newest matching checkpoint, or the deployment block when none remain canonical.Cannot hold request content. Contains only public HostBond event values or projections: wallet and contract identifiers, amounts, reason codes, hashes, flags and block times. No inference content or caller connection address is read.Not about requests
checked_attimestamp with time zoneLast caught-up scan time. Zero during backfill; routing boosts and slashing stop after 120 seconds without a caught-up pass.Not about requests
host_bond_eventsNot about requests · 7 columns · 1 reviewed

Every decoded event from the configured HostBond deployment, including ownership and parameter changes. Reversible journal; no inference records are changed.

How long: Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency.

ColumnWhat it holdsAbout a request
scopetextChain id and HostBond contract address.Not about requests
tx_hashtextPublic transaction hash, unique with scope and log index.Not about requests
log_indexintegerLog position within the canonical block.Not about requests
blockbigintCanonical event block number.Not about requests
block_hashtextBlock hash checked against the RPC's canonical chain.Not about requests
eventtextABI event name, including Bonded, UnbondRequested/Cancelled/Unbonded, slash lifecycle, role, ownership and minimum changes.Not about requests
argsjsonbDecoded public ABI arguments: bytes32 host id/evidence root/dispute hash, slash id, operator/recipient/role wallets, amount, total, reason, cooldown/dispute deadline and delisting flag. Numbers are decimal strings; no arbitrary transaction calldata is stored.Cannot hold request content. Contains only public HostBond event values or projections: wallet and contract identifiers, amounts, reason codes, hashes, flags and block times. No inference content or caller connection address is read.Not about requests
host_bond_projectionNot about requests · 4 columns · 1 reviewed

Reversible HostBond state reduced from the journal, with one row per host, slash or parameter set. The provider's existing bond_usdg field is left unchanged.

How long: Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency.

ColumnWhat it holdsAbout a request
scopetextChain id and HostBond contract address.Not about requests
kindtextProjection kind: host, slash or parameters.Not about requests
idtextBytes32 host id, decimal slash id, or the fixed current parameter key.Not about requests
datajsonbHost projections contain operator wallet, total and queued bond, unbond deadline and delisting flag. Slash projections contain host id, amount, contract reason, evidence root, dispute deadline/hash, status, approval generation and transaction history. Parameter projection contains minimum bond, approval generation, owner/pending owner, slasher and refund pool wallets. All values are public on-chain data.Cannot hold request content. Contains only public HostBond event values or projections: wallet and contract identifiers, amounts, reason codes, hashes, flags and block times. No inference content or caller connection address is read.Not about requests
host_slash_evidenceSummed from requests · 13 columns · 1 reviewed

Hash-committed evidence of quote-bound host policy rejection and invalid receipts from the pinned host feed, plus durable proposal/execution intents. Disabled unless NETWORK_BONDS_ENABLED.

How long: Kept until the operator removes the bond index. Orphaned journal events and projections are removed on a chain reorganization; slash intent and evidence commitments are retained for idempotency.

ColumnWhat it holdsAbout a request
scopetextChain id and HostBond contract address.Summed from requests
roottext0x-prefixed SHA-256 commitment of the exact canonical evidence bundle; primary key with scope prevents repeated proposal intents.Summed from requests
provider_idtextNetwork provider id from the registry.Summed from requests
host_idtextkeccak256 of the provider id, matched to the HostBond operator before proposal.Cannot hold request content. A bytes32 contract host identifier, derived from the provider id with keccak256. It is not a caller connection address or a host's network endpoint.Summed from requests
canonicaltextExact canonical structured bundle: format, provider/host ids, fault kind, contract reason or null, policy version/hash where applicable, observed binding or receipt digest, attestation reference, receipt public key when applicable, and rejection digest. Contains hashes and identifiers only. Raw quotes, bindings, receipt envelopes, signature bytes, prompt and answer text are not retained here. A commitment does not by itself prove fault; review requires the source evidence.Summed from requests
reasonintegerContract MeasurementDrift code 0 for verified policy rejection; -1 means invalid receipt evidence awaiting policy review, never automatically proposed.Summed from requests
amounttextProposal amount in USDG base units: current whole bond at preparation, or would-be amount in dry run. Owner independently approves the exact proposal.Summed from requests
statustextready, review, dry_run, submitted, executing, cancelled or executed; always reconciled against the canonical journal before action.Summed from requests
proposal_txtextHash of the single persisted proposal transaction.Summed from requests
proposal_rawtextAPP_SECRET-encrypted signed proposal transaction. Saved before broadcasting; retries reuse identical bytes and nonce. The signed transaction becomes public on broadcast; no slasher key is persisted.Summed from requests
execution_txtextHash of the single persisted execution transaction.Summed from requests
execution_rawtextAPP_SECRET-encrypted signed execution transaction, saved before broadcast and reused on retry. Independent owner approval and the undisputed window are checked before preparation.Summed from requests
created_attimestamp with time zoneTime this exact evidence commitment was first stored.Summed from requests
makegood_payoutsSummed from requests · 8 columns

On-chain make-good refund transfers: one USDG transfer from the refund treasury per payer per batch, signed and stored before it is broadcast so a retry resends the same transfer and never pays twice.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextTransfer id.Summed from requests
payertextWallet address the refund is sent to.Summed from requests
usdgbigintAmount in USDG base units: the sum of that payer's owed refunds in the batch.Summed from requests
statustextsigned (stored, possibly broadcast), paid (mined successfully) or failed (reverted; its refunds are owed again).Summed from requests
tx_hashtextHash of the signed transfer transaction.Summed from requests
signed_tx_enctextThe signed transaction bytes encrypted under APP_SECRET, kept to rebroadcast the identical transfer; never the treasury key.Summed from requests
created_attimestamp with time zoneWhen the transfer was signed.Summed from requests
settled_attimestamp with time zoneWhen it was seen mined or reverted.Summed from requests
network_payout_dispatchNot about requests · 3 columns

Durable signed USDG transfer for a network payout. Written before broadcasting so recovery sends identical bytes and cannot pay again using another nonce.

How long: No automatic deletion, and rows are never changed after they are written.

  • The signed transaction can authorize only its encoded transfer, but replaying it before inclusion broadcasts that transfer. It is encrypted with APP_SECRET and never exposed by public APIs. No private signing key is stored here. Reverted, destination-changed or nonce-conflicted transfers require operator reconciliation.
ColumnWhat it holdsAbout a request
payout_idtextThe payout whose claimed invoices this transfer settles.Not about requests
signed_tx_enctextEncrypted serialized signed blockchain transfer: chain, nonce, USDG contract, destination, amount and fees; no inference text or signing key.Not about requests
tx_hashtextHash of the signed transfer, fixed before first broadcast.Not about requests
paywith_debtsPer request · 11 columns

What a pay-with call owes in tokens, until a swap settles it.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextDebt id.Per request
chain_key_hashtextThe key's chain hash.Per request
account_idtextThe account.Per request
generation_idtextThe generation that created the debt.Per request
tokentextThe token contract.Per request
amountbigintPico-USD owed.Per request
raw_estimatebigintEstimated token units.Per request
fair_price18textThe fair price used, 18 decimals.Per request
swap_idtextThe swap that settled it.Per request
raw_allocatedbigintToken units allocated to it by the swap.Per request
created_attimestamp with time zoneWhen the row was created.Per request
paywith_sessionsNot about requests · 10 columns

Pay-with sessions: a wallet's daily cap for paying with a Stock Token through a key.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
key_hashtextThe key's chain hash.Not about requests
wallettextThe wallet that opened the session.Not about requests
tokentextThe token contract.Not about requests
symboltextThe token symbol.Not about requests
cap_raw_daybigintThe daily cap in token base units.Not about requests
spent_raw_todaybigintSpent today in token base units.Summed from requests
day_starttimestamp with time zoneWhen today's window began.Not about requests
activebooleanWhether the session is active.Not about requests
opened_txtextThe transaction that opened it.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
paywith_swapsSummed from requests · 11 columns · 2 reviewed

Swaps that turn pay-with tokens into USDG to settle debts.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextSwap id.Summed from requests
key_hashtextThe key's chain hash.Summed from requests
tokentextThe token contract.Summed from requests
raw_spentbigintToken units spent.Summed from requests
fair_pricetextThe fair price used.Summed from requests
usdg_outbigintUSDG base units received.Summed from requests
txtextThe swap transaction.Summed from requests
statustextpending, submitted, confirmed or failed.Summed from requests
errortextWhy the swap failed, when it did.Cannot hold request content. An error string from a swap transaction; no request is involved.Summed from requests
tstimestamp with time zoneWhen the swap was created.Summed from requests
allocationsjsonbWhich debts the swap settled and how much of it each got.Cannot hold request content. Debt ids and token amounts written by the pay-with aggregator.Summed from requests
slashesSummed from requests · 17 columns · 1 reviewed

Penalties proposed against a provider for empty answers, precision fraud, poor uptime or dropped parameters, with the evidence and where it stands.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
idtextSlash id.Summed from requests
provider_idtextThe provider.Summed from requests
model_idtextThe model, when the penalty is per model.Summed from requests
kindtextempty200, quant_fraud, uptime or param_drop.Summed from requests
amount_usdgbigintThe amount in USDG base units.Summed from requests
delistbooleanWhether the provider is delisted with it.Summed from requests
evidence_roottextA Merkle root over the evidence.Summed from requests
evidencejsonbThe evidence: counts of requests and empty answers, canary results or uptime figures, and the window they cover.Cannot hold request content. Assembled by gatherEvidence in slasher.ts from counts, canary results and time windows; no request or answer text is read.Summed from requests
statustextproposed, disputed, cancelled, executed or auto_refunded.Summed from requests
proposed_attimestamp with time zoneWhen it was proposed.Summed from requests
executable_attimestamp with time zoneWhen it may be executed.Summed from requests
executed_attimestamp with time zoneWhen it was.Summed from requests
dispute_hashtextThe hash of the provider's dispute.Summed from requests
disputed_attimestamp with time zoneWhen it disputed.Summed from requests
onchain_idtextThe id on chain.Summed from requests
tx_hashtextThe transaction.Summed from requests
refundedbigintPico-USD refunded to callers affected.Summed from requests
spent_rootsSummed from requests · 8 columns · 1 reviewed

A Merkle root over every key's cumulative spend, posted on chain so balances can be settled.

How long: No automatic deletion: no job or route in the code removes rows from this table.

ColumnWhat it holdsAbout a request
epochintegerThe epoch.Summed from requests
roottextThe Merkle root.Summed from requests
as_oftimestamp with time zoneThe time the spend is counted to.Summed from requests
total_spent_usdgbigintTotal spend in USDG base units.Summed from requests
leavesjsonbPairs of a key's chain hash and its cumulative spend in USDG base units, in tree order.Cannot hold request content. [chainKeyHash, cumulativeSpentUsdg] pairs built from ledger totals.Summed from requests
tx_hashtextThe transaction that posted the root.Summed from requests
statustextpending, submitted or confirmed.Summed from requests
created_attimestamp with time zoneWhen the row was created.Summed from requests

Operations

Settings you save (routes, presets, spend alerts) and the router's own key-value state.

character_memoryNot about requests · 10 columns

Character memory an account keeps: rolling summaries, facts and lorebook notes sealed on the account's own device (AES-256-GCM) under a viewing key the router never receives. The router stores ciphertext, never the memory's text, and cannot tell which character a memory belongs to.

How long: Kept until the account deletes it (DELETE /api/v1/memory/:id, or ?scope= / ?all=1 for many).

ColumnWhat it holdsAbout a request
idtextMemory id.Not about requests
account_idtextThe account that owns it.Not about requests
scopetextAn HMAC of the character id under the client's key: it groups one character's memories without naming the character.Not about requests
kindtextsummary, fact, lorebook or state, as the client labels it.Not about requests
sealedtextThe ciphertext the client sealed (arm1.<iv>.<ciphertext>); the API refuses anything that is not in this sealed form.Not about requests
key_idtextA 16-hex fingerprint derived from the client's key, so the client can tell which key sealed it. The key cannot be recovered from it.Not about requests
bytesintegerSize of the ciphertext in characters.Not about requests
embeddingreal[]Only when the client opts in (embedding_opt_in): a vector the client computed from the memory, for similarity search. It cannot be turned back into the text, but it can reveal what the memory is about, so it is off by default. Empty otherwise.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
character_usageSummed from requests · 4 columns

Creator attribution for public characters: how many calls used each one and what they cost, summed per UTC day. It records no request, answer, key or caller.

How long: No automatic deletion: no job or route in the code removes rows from this table. Rows are deleted with their character.

ColumnWhat it holdsAbout a request
character_idtextThe public character.Summed from requests
periodtextThe UTC day, YYYY-MM-DD.Summed from requests
callsintegerCalls that used the character that day (never counted on the unlinkable lane).Summed from requests
costbigintWhat those calls cost in total, in pico-USD.Summed from requests
charactersNot about requests · 13 columns · 1 reviewed

Character cards an account registers (Tavern Card v2 or v3). A public or unlisted card is text its creator publishes for others to use, kept as written. A private card is kept only as the ciphertext the owner's own device sealed, with the SHA-256 of the card; the router never receives its key or its text at rest.

How long: Kept until the owner deletes the character (DELETE /api/v1/characters/:id), which also deletes its attribution counters.

ColumnWhat it holdsAbout a request
idtextCharacter id, used as @character/<id>.Not about requests
account_idtextThe account that owns it.Not about requests
visibilitytextpublic (listed in discovery), unlisted (readable by anyone with the id) or private (sealed, owner only).Not about requests
nametextThe card's name; empty for a private card.Not about requests
tagstext[]The card's tags, lowercased, for discovery; empty for a private card.Not about requests
creatortextThe card's creator field as the card states it; empty for a private card.Not about requests
spectextchara_card_v2 or chara_card_v3; empty for a private card.Not about requests
cardjsonbThe normalized card of a public or unlisted character: name, description, personality, scenario, greetings, example dialogue, system prompt, post-history instructions, tags, creator notes and lorebook. Empty for a private card.Settings written by you or an operator. Written by the card's owner through POST or PUT /api/v1/characters and normalized to the Tavern card fields, at most 512 KB. It is text a creator publishes for others to use, not text taken from a call: chats with the character are not stored here or anywhere else, and a private card is never stored in this column.Not about requests
sealed_cardtextA private card as the owner's device sealed it: AES-256-GCM ciphertext under a key the router never receives. Empty for a public or unlisted card.Not about requests
card_hashtextSHA-256 of the card's canonical JSON. For a private card the router checks a card sent with a chat against it before using it.Not about requests
default_modeltextThe model @character/<id> uses when a request names none.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
facilitator_sellersNot about requests · 11 columns · 1 reviewed

Sellers who opted in to the facilitator's discovery index: the paid URL, a price hint, an output schema and tags, each listing signed by the seller's payTo key. Shown publicly at /facilitator/discovery/resources while listed.

How long: Kept until the seller replaces it with a later signed listing; listed false hides it from discovery. No job removes rows.

ColumnWhat it holdsAbout a request
idtextRandom listing identifier (fsl_ followed by 24 hex characters).Not about requests
pay_totextLowercase wallet address the seller is paid at, which signed the listing. Public in every 402 response the seller sends.Not about requests
resourcetextThe seller's paid https URL as signed. The first payTo to list a URL owns that entry.Not about requests
price_hintnumeric(78, 0)Price the seller states, in USDG base units; the seller's own 402 response stays authoritative.Not about requests
result_schemajsonbJSON schema the seller published for its endpoint's result (x402 outputSchema), as signed.Settings written by you or an operator. Seller-written description of a public paid endpoint's result shape, signed by its payTo key and shown in discovery; never a caller's request or answer.Not about requests
tagstext[]Up to ten lowercase words the seller chose for search.Not about requests
listedbooleanWhether the listing shows in discovery.Not about requests
signaturetextThe payTo key's EIP-712 signature over the listing.Not about requests
signed_attimestamp with time zoneissuedAt of the stored signature; only a later signature replaces the listing.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
host_policiesNot about requests · 7 columns

Public versions of the network host admission policy, signed with the transparency log's Ed25519 key. Publication alone does not admit providers; wallet-authenticated network admission verifies this policy before probation.

How long: No automatic deletion, and rows are never changed after they are written.

ColumnWhat it holdsAbout a request
versionintegerConsecutive policy version, beginning at 1.Not about requests
issued_attimestamp with time zoneThe policy's issue time supplied by the operator.Not about requests
canonicaltextCanonical JSON of the operator's policy: version, issue time, TEE kinds, approved sidecar image and source hashes, engine names and image digests, model IDs and digests, GPU CC requirements and optional model offer terms: catalogue slug, display name, Hugging Face ID, context and completion limits, quantization and positive USD-per-token prompt/completion prices. Offer terms are public operator-provided metadata, not inference content. A strict bounded schema accepts no prompt fields; names are operator-written identifiers with a restricted alphabet, so the router cannot know what meaning the operator assigns them. Public through the policy API.Not about requests
sha256textSHA-256 of the exact canonical policy bytes.Not about requests
signaturetextBase64 Ed25519 signature over the canonical policy bytes.Not about requests
verifier_keytextThe public signed-note verifier key identifying the log key that signed this version.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
kvNot about requests · 4 columns · 1 reviewed

The router's small key-value store: job status, cursors, provider facts, sign-in challenges, Telegram state, notification settings and encrypted delayed notice text, including scheduled answer previews.

How long: Per key family: a wallet sign-in or team challenge is deleted when used and any older than 10 minutes is deleted when the next challenge is made; a team invite is deleted when used and expired ones when the next invite is made; a Telegram user's row is deleted by /forget; other families are overwritten in place.

  • deposit-watch:<chain id>:<account id>:<transaction hash>: account-scoped submitted-deposit status. Keeps account id, lane (escrow or USDG), transaction hash and submission time, up to 20 submitted hashes per account. Removed after indexed credit, otherwise retained until operator deletion. No typed amount or sender is accepted; display amounts and senders come from public chain logs. The deposit list also caches decoded unindexed USDG logs in process memory for five seconds, containing public key hashes, sending wallets, amounts, transaction hashes and block numbers; it does not credit funds.
  • fast-credit:lock: an empty singleton row locked during escrow crediting to serialize account and global outstanding-credit caps. Kept until operator deletion.
  • fast-credit:deposit:<chain id>:<lane>:<transaction>:<log index>: durable provisional deposit bookkeeping. Stores chain and lane identity, account id, sending wallet, transaction and log index, block and canonical hash, fixed capped pico-USD total, provisional pico-USD amount, provisional/final/reversed status, ledger and reversal references and kinds, and escrow price with its timestamp and per-deposit cap marker. Final settlement changes state and credits only the remainder; reversals debit the provisional amount. Kept indefinitely for idempotency. No inference text or caller network address.
  • deposit-ping:<chain id>:<deposit id>: account id, deposit id, notice timestamp and credited USD decimal amount. The worker reads newly credited $ANYR and stock deposits from the last day (including early credit), at most 100 per pass, and inserts one permanent marker per deposit. Inbox reads show up to 100 notices from the last 90 days under account-wide Activity access; ordinary and session keys receive none. Markers remain until operator deletion to prevent replay. Telegram sends once per eligible existing account link after the claim commits, using the current balance; a crash or failed send can lose delivery and is not retried. Telegram receives readable token amount, symbol, credited amount and account balance. No prompt, answer, API key, message text, new body reader or caller address is retained.
  • telegram-link-code:<account id>: SHA-256 of a random single-use code, account id, principal key hash and expiry. One code per account, replaced on issuance, deleted on consumption/cancellation. Valid for five minutes; expired rows are purged on enabled polling or issuance. The code itself is returned once and stays in page memory until linking, cancellation or navigation; it is never saved in browser storage.
  • telegram-link:<Telegram user id>: account id, owner/admin principal key hash, Telegram user id, random generation and linked timestamp. One account per Telegram identity and one identity per principal key. Kept until /unlink or DELETE /api/v1/telegram/link; disabling or expiring the key or removing its role prevents use. No API key or message text. Existing chat keys under telegram:user are separate.
  • telegram-approval:<approval id>:<Telegram user id>:<link generation>: approval id, Telegram user id, generation, expiry, Telegram message id and fixed decision status. Delivery markers stop repeat polling sends and bind buttons to the originating message and current link. Deleted on unlink; expired markers are purged on enabled polling or issuance. Worker interruptions can repeat a notification; decisions use the dashboard's atomic logic. Telegram receives readable intent metadata and alerts, not inference messages or tool arguments. With AGENT_RULEBOOK_WORDS_ENABLED it also receives the current rulebook amount caps and approval thresholds (including inherited rules); this display text is not stored. Message text is never stored here.
  • upstream-balance:<provider id>: latest USD balance (including zero and negative readings), check time and unknown/unsupported check state, with the last successful reading and its time retained across failed checks; upstream-credit-hold:<provider id>: expiry of a five-minute provider-wide routing hold after explicit insufficient credits. Balance readings at or below UPSTREAM_BALANCE_EXHAUSTED_USD (default 0) block routing until a later reading exceeds that threshold, including across restarts and failed polls. Enabled only by UPSTREAM_MONITOR_ENABLED. Overwritten in place; expired hold rows remain until operator deletion. No response text, API keys or caller identifiers are copied. Alerts use the existing alerts:state and alerts:lease rows and configured operations webhook. Balance state changes alert immediately with hashed provider check names; exhausted reminders are no more frequent than six hours. The alerts:state checks also retain the last delivered time for balance notices.
  • agent-alerts:<account id>: newest 100 metadata-only owner alerts per account, visible for up to 90 days; expired feed, denial and dedupe metadata is purged on the next alert write or enabled worker cleanup, while inactive account rows remain until operator deletion; threshold cooldowns, denial counts with up to 10,000 recent timestamps and random transaction batch markers per key (10-minute rolling retention on writes/cleanup), timestamps, optional stopped_until deadline copied from the stopped policy for timed-stop alerts (also sent in webhook and Telegram delivery), key hashes, selected channels, delivery attempts, destination rule ids or Telegram ids and per-account delivery rate/lease state. No prompt, answer, intent, kill reason, webhook URL or API key is copied. Existing Spend Watch destinations are decrypted for guarded egress; existing Telegram principal links are decrypted and permission-checked before delivery. Email has no account destination. Delivery is at-least-once; a crash after sending can repeat an attempt.
  • telegram:offset, telegram:user:<Telegram user id>: the update cursor, and per user the API key sealed under APP_SECRET, the chosen model and the private-mode switch (services/telegram.ts). Message text is not stored.
  • wallet-login:<nonce>: a sign-in challenge (wallet address, the router's own origin, chain id, expiry and the message to sign). Deleted when used; older ones are pruned.
  • team-invite:<sha256 of the invite>: a single-use team invite (team, role, how to join, expiry and the inviting key's hash). The invite itself is never stored. Deleted when used; expired ones are deleted when the next invite is made.
  • team-challenge:<id>: a team join, sign-in or owner challenge (team, method, the WebAuthn challenge or the message to sign, and the wallet address when there is one). Deleted when used; older than 10 minutes are pruned.
  • job-health:<job>, alerts:state, alerts:lease, backup:last: when each background job last ran, a fixed failure marker (operator job snapshots and queue failures redact configured private chain RPC URLs), alert state, an alert lease and the time and checksum of the last database backup.
  • agreement-jury:heartbeat: written by the isolated agreement-jury worker each pass after its signer keys matched the DisputeOracle's jury on chain: the escrow and oracle addresses, threshold, the jury signers' public addresses and the time. GET /api/v1/status reads it to report whether automatic rulings are on. Overwritten in place; no evidence, verdict or key material.
  • tls-pin:<provider>, aci-gateway:<provider>, aci-gpu:<model>, attest-policy:<provider>, attest-allow:<provider>, static-models-pending:<provider>, apply-token:<application id>: facts about providers (pinned certificate keys, verified gateway keysets, operator allow-lists, a pending model list, and the SHA-256 of an application token).
  • paywith-allowance:<chain key hash>, paywith-intent:<chain key hash>, paywith-commitment:<commitment>: a signed pay-with allowance (wallet address and signature), the wallet and token a key holder registered for pay-with, and the swap a usage commitment belongs to.
  • escrow:checkpoints, spent_settled:<epoch>, margin_unsent, holder-credits-run:<period>:<time>, ipx-oracle:*: chain cursors and settlement bookkeeping. margin_unsent retains accumulated protocol margin and provider-side fees in pico-USD; settlement reports the rounded USDG amount without transferring or clearing it.
  • key-rotation:<key hash> in kv stores from and to key hashes, at, grace_ends_at and history_key_hash. The replacement keeps the old key's settings, team membership and principal, current policy and saved policy_versions (including saved-by attribution and dates), agent approvers, quiet-alert hour choice and spend-alert rules including sealed webhook destinations. Usage, delivery history, existing agent approvals and spend records stay with the old key. Quiet-alert delivery state and spend-alert history restart for the replacement. The security-alerts event stores a sanitized Key rotated title and actor under its existing family, and uses the existing security_alerts notification type, preferences and quiet-hour delivery. Browser sign-ins, Telegram link credentials and attestation records are not cloned; there is no new address reader, Redis family or log field. Rotation links remain with key history until account data is removed. Copied settings use the existing tables' retention. The secret exists in router response memory and the browser's reveal state until dismissed; it is never persisted by the rotation interface.
  • agent-approvers:<agent key hash>: strict owners, owners_and_admins or specific_members mode and up to 100 unique team principal IDs or member key hashes. Stored only by an authenticated account management or team owner/admin key when AGENT_TEAM_APPROVERS_ENABLED is enabled; overwritten on each save and retained until removed by the operator or account data removal. No new table, column, Redis family or log field. Team membership, principal revocation, disabled/expired keys and agent sessions are rechecked at decision time; no requester can decide their own key or the same principal's requests. Existing agent_approvals.decided_by records the deciding key hash. Activity reads its current key name. With SECURITY_ALERTS_ENABLED, settings and decisions add existing security-alerts:event records with account/team, status, times and sanitized key names; the deciding name is captured then. Existing Telegram link families also accept eligible approvers when enabled; only delegated approval delivery uses their access, while other notifications and Stop retain owner/admin guards. Telegram receives readable approval metadata and current rulebook amount caps and thresholds, never inference text or tool arguments. Existing link-code expiry, single-use and delivery markers remain unchanged. Off preserves prior permissions and responses.
  • security-alerts:event:<change id, policy event id, or team id and sequence> holds account id, nullable team id, inbox-arrival timestamp (recording time while pending), readable title and pending/inbox/muted state. Titles contain sanitized key and team names, management status, the kind of change and the acting key name. The request middleware holds only a digest of the presented Bearer key in an asynchronous request scope to correlate the already-authenticated team audit writer with its exact acting key; no credential is retained. Team audit entries authenticated by wallet or passkey name that member type instead of inventing a key. Wallet sign-in reads the already-verified account wallet in memory, keeping only its first six and last four characters in a sign-in title. Full wallet addresses, key secrets, prompt text, policy contents, stop reasons and Telegram messages are not copied. security-alerts:cursor keeps a processed-event count and lock; per-event states are the durable cursor so late commits and equal timestamps remain eligible. security-alerts:preference:<account id> keeps the enabled boolean. Telegram can read the security titles and key names it receives. Unlinked members receive no later alert, including their unlink notice; other eligible links may receive it. Claimed and muted event rows are removed after ninety days by enabled worker runs; pending events remain until claimed. Flag off pauses recording, delivery, inbox projection and cleanup. Events from before recording was enabled are not reconstructed. Preference and cursor rows remain until removed. Claims commit before one send attempt per eligible link: worker crashes, failed and ambiguous sends can leave an inbox item without Telegram delivery; sends are not retried. Key change hooks use the existing write boundaries; changes whose key write commits but notice write fails can miss a notice. Policy, team audit and Telegram notices commit with their source transaction. No new database table/column, Redis family or log field; the settings route is the only new request-body reader.
  • sealed-agent:<key hash>: owner-selected HTTPS /attest URL, expected image digest and measured compose hash, random registration revision, last check timestamp, fixed success/failure code, verifier names and verified TLS SPKI hash. Overwritten on registration and each check; deleted by the principal's DELETE endpoint. No quote, certificate, API credential or inference content is stored. Owner-selected hostnames are settings and may carry meanings chosen by that owner. Records remain while disabled until explicitly removed; badge success expires after 30 minutes.
  • J184: summaries also read existing reliability totals, savings estimates and catalogue metadata, retained watched-model notices (management only), current agent cap settings with posted ledger charges at week end and recorded cap refusals, and undecided approval expiry times. Sections and Inbox page links exist only in response memory or the existing Telegram delivery/quiet-hours payload. No new tables, columns, Redis families, logs, body or address readers. Historical cap settings are not retained; current settings apply. Source retention can omit older activity. Telegram can read these sections.
  • Weekly summaries read existing agent call charges, key names, model names, approval statuses and stop events for the previous Monday–Sunday UTC. They send readable totals and names to Telegram, which can read them. The first eligible opted-in link receives one summary per account, restricted to that principal's current team if it is not a management key. Empty weeks are skipped. The existing link-action rate counter also limits summary attempts to twenty per minute per Telegram user; no message text is copied into Redis. The account's last_sent_week prevents ordinary repeat and concurrent sends. A crash or ambiguous network failure after Telegram accepts a send but before the database commits can repeat delivery.
  • model-first-seen:<public model id>: the first catalogue observation in Unix seconds and a seeded flag. model-arrivals:seed: initialization marker and baseline time. Recorded during catalogue refresh only when MODEL_ARRIVALS_ENABLED is on (default false), retained until operator deletion including removed model IDs so reintroduction does not reset dates. Baseline model arrival dates are unknown and published as null; later observations are published as added_at and in the public models feed. No account, request, prompt, answer or address data, new Redis keys or log fields.
  • quiet-agent-alert:<key hash>: per-agent hours (null means off), enable timestamp, last claimed quiet-period activity timestamp, and newest 100 notices with random id, timestamp, readable agent-name title, hour window and last charged-call/Guard-decision time. Settings and the dedupe anchor persist until operator deletion. Enabled runs and changed settings prune notices older than 90 days; disabled cleanup pauses, while inbox reads hide expired notices. Deleted keys leave inaccessible settings until operator deletion. No rulebook field, table, column, Redis family, address reader or log field is added.
  • browser-session:<key hash> in kv keeps only a fixed browser-family and operating-system label derived from User-Agent at wallet sign-in. No full header, version, device model or network address is retained by this feature. Rows remain after sign-out because existing keys are disabled, not deleted; retained until operator deletion. Existing keys.created_at records sign-in, and keys.last_used records the last charged call, not browsing or every API request. Older wallet-issued root management keys have no browser label. Sub-keys, team keys and agent sessions are excluded from the browser list.
  • notification-prefs:<account id> stores channel booleans and nullable from_utc/to_utc daily clocks. Weekly Telegram reads and writes only existing telegram-link weekly_summary_opted_in columns, and security Inbox/Telegram use the existing security-alerts:preference value with enabled as their aggregate for recording; the older security switch replaces that value and controls both. notification-quiet:<random id> stores account id, Telegram user id and link generation, source and principal key hashes, team id and management snapshot, notice category, due/creation times, a legacy-link marker and text encrypted under APP_SECRET. Text includes notice names and amounts, and can include scheduled answer previews. The router can decrypt these previews; Telegram can read delivered messages. No inference credential, new Redis key, address reader or log field is added. Browser component memory holds the settings and current local clock conversion; nothing new enters browser storage. Preferences remain until changed or removed. NOTIFICATION_QUIET_HOURS_ENABLED defaults false: only the enabled minute worker queues and flushes delayed Telegram notices. Approvals and approval reminders are never queued. Each tick reads at most 500 queue entries and sends one bounded-excerpt bundle per recipient and generation; larger backlogs can yield later bundles. Successful delivery removes entries; muted, revoked, unlinked or changed-scope entries are discarded. Failed sends remain for a later attempt. Entries older than seven days are discarded by enabled ticks; flag off pauses queue delivery and cleanup. Delivery can repeat after Telegram accepts a message before transaction commit. The worker revalidates current link, role, team, management status, source key ownership and scheduled-result owner rights. A source feature switched off pauses its queued notices until enabled or expired. Existing sender success counters treat skipped channels or durable queue acceptance as acknowledged delivery. Weekly last_sent_week is marked when a summary enters the queue; a later discarded summary is not resent. Daily clocks are saved in UTC using the device's current offset; saving again is needed after clock or time-zone changes. Future Telegram links retain the existing weekly opt-in default.
  • approval-nudged:<approval id> in kv stores the claim time and approval expiry time. Existing telegram-approval:<approval id>:<Telegram user id>:<link generation> values additionally store reminder_message_id, the reminder's Telegram message identifier; original and reminder buttons use the same single-use approval. notification-prefs:<account id> adds Inbox and Telegram booleans for approval_reminders, both on by default. No new table, column, Redis family, log field, address or body reader. Reminder text uses existing readable approval metadata: agent name, routing or action identifiers, amounts and rulebook summaries, never prompt or answer text. Telegram can read delivered details. The router reads ordinary request text in memory. APPROVAL_NUDGES_ENABLED defaults false. Enabled non-API workers inspect up to 100 eligible approvals each minute. Claims commit before outbound delivery, preventing repeats across concurrent workers. Each current linked recipient is attempted once, with current authority and channel settings checked under the link and account locks. Quiet hours never delay reminders. A crash after claiming, an unavailable destination or a failed send can lose a reminder; it is not retried. Claims are deleted after approval expiry by enabled ticks, and pause while off; decided claims remain until expiry. Existing Telegram notices are pruned by Telegram delivery after expiry or unlinking. Preferences remain until changed or removed. The inbox countdown appears only to current decision makers, only while pending and unexpired, and uses existing approval response fields. No expiry or approval consumption changes.
  • G159: notification-prefs channel choices and notification-quiet notice categories also include model_watch. Its delayed text contains only the public model name and availability wording, never inference content. Existing encrypted quiet-hour queue retention, feature rechecks and link authority apply.
  • H169: notification-prefs channels also include status_incidents, default false for Inbox and Telegram. incident-notices:subscription:<account id> stores nullable per-channel opt-in timestamps, preserved across unrelated settings saves and reset when a channel is turned off and on. Subscriptions remain until changed or removed. incident-notices:change:<SHA-256 account id>:<SHA-256 incident/update identity> is both a unique claim and an inbox record; its value stores the claim id, account id, public update timestamp, incident id, public incident title with status prefix, public update text and whether Inbox was enabled at claim time. Only confirmed public investigating/identified/monitoring/resolved updates are read, never suggestion evidence, prompts, answers or addresses. SHA-256 update identity covers incident id, array index, update time, status and public text. The account hash is pseudonymous, not anonymous. An enabled worker checks every minute and replays up to 90 days after each channel's opt-in. Row locks and unique kv keys claim each account/change once across workers. Inbox records and claims older than 90 days are deleted by enabled ticks; disabling the feature pauses processing and cleanup. A claim commits before one Telegram attempt per current management link; a crash or failed send can lose that attempt and it is not retried by this worker. Quiet hours queue incident text using the existing encrypted notification-quiet family; its existing seven-day expiry, authority checks, channel checks and retry/possible repeated bundle delivery apply. Flag off pauses queued incident delivery. Inbox is management-only and filtered by the current channel preference. No new table, column, Redis family, application log field, body reader or address reader. Settings reuse the existing guarded notification settings reader. Ordinary inference request text remains readable by the router in memory.
  • wallet-link:<random nonce> holds the owner account id, secondary wallet, origin, chain id, five-minute expiry and exact link message. Signatures are checked in memory and not retained. Successful linking consumes the row atomically. Expired rows are removed on later challenge requests once ten minutes old; without later requests they remain until removed.
  • business-details:<account id> holds business_name, multi-line address, tax_id and reference in kv.value, linked to the account id in kv.key, plus kv.updated_at. The router reads these optional settings in memory. Statement reads with business_details=true add them beside payload, alg, key_id and sig; default statement responses are unchanged. The browser uses these current fields, including for earlier months, for the unsigned Billed to block, CSV and print/PDF. Signed JSON downloads omit them. There is no billing email field; the reference rejects email addresses, but free-text business identity fields can contain personal information supplied by the owner. Kept until replaced or deleted, without automatic expiry. Delete in Settings > Statements sends PUT with an empty object and removes the kv row; it does not remove earlier backups or exports on the caller's device. Browser memory holds the form and loaded statement details until navigation; no new browser storage. No new table, column, Redis family or log field.
ColumnWhat it holdsAbout a request
keytextThe key, a family name plus an identifier (see the families above).Not about requests
weekly_summary_opted_inbooleanNullable opt-in flag on telegram-link rows only. True enables a weekly Telegram summary for this link; false or empty means off. Deleted with the link on either unlink path. No request text or new tracking.Not about requests
valuejsonbThe value, as JSON. Its shape depends on the key family.Holds request text. Most families hold ids, hashes, timestamps, amounts and settings. The notification-quiet family additionally retains encrypted Telegram notice text, including previews copied from scheduled model answers. APP_SECRET lets the router decrypt them. Queue cleanup and retention are described under this table.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
model_watchesNot about requests · 5 columns · 1 reviewed

Account-selected models and durable availability debounce, pairing and inbox notice history.

How long: Until unwatch deletes the row, except a down claim within the rolling hour retains an inactive row with only the last-down cooldown and reset state. An enabled worker tick deletes expired inactive cooldowns and prunes active notices older than 30 days. Flag off pauses processing and pruning. Existing database backups follow operator retention.

  • Up to 20 active rows per account; inactive cooldown rows do not count against the watch cap. Account and watch row locks enforce caps and single claims without new Redis keys. The worker reads shared health events and live offers/providers, including existing hashed health callers for the empty-answer outage rule. Five-minute holds reset on stale gaps; recovery requires a successful reading and a prior down claim. The one-hour cap is per account/model watch, measured from the down claim. Unwatch clears notices and open pairing state but preserves an unexpired last-down cooldown, so rewatching cannot bypass the hourly cap. Telegram attempts are claimed before sending and never retried after failure or interruption; unwatch does not erase already queued or delivered Telegram notices; an accepted quiet-hour queue entry uses the existing queue's delivery and retention rules. Inbox channel preferences filter notices at read time, and muting one channel can hide one half of the pair. No new application log fields, address readers or Redis families. Ordinary inference text remains readable by the router in memory.
ColumnWhat it holdsAbout a request
account_idtextOwning account id, associated with the owner's model choices.Not about requests
model_idtextPublic catalogue model identifier chosen by the account; never prompt or answer text.Not about requests
watchingbooleanWhether this is an active watch, or an inactive one-hour cooldown after unwatching.Not about requests
created_attimestamp with time zoneWhen the account most recently began watching this model.Not about requests
statejsonbCandidate availability, candidate start time, last check, whether a down pair is open, last down claim time and up to 30 days of notices with random id, UTC time, public model id and availability title.Settings written by you or an operator. Only worker-created availability state and fixed notice wording plus a public catalogue model name are stored. The strict owner input is a catalogue id; this object never stores prompts, answers or caller addresses.Not about requests
network_waitlistNot about requests · 9 columns · 1 reviewed

Network interest sign-ups, not host admission or attestation. Stores exactly the submitted role, hardware, readiness, continent, optional contact and payout preference, plus an id, deletion digest and time. Free text is private to the owner export; public statistics contain only counts.

How long: Until the participant deletes it with their code, or the owner deletes the list when the program launches or is cancelled. Program-wide removal is an owner operation; no automatic launch or cancellation signal exists.

  • Hardware, readiness and contact are user-supplied text. Do not paste prompts or other sensitive information. The owner can read these fields through the ADMIN_TOKEN-protected read-only export. No network address or user agent is stored in this table. The delete code itself is returned once and never stored.
ColumnWhat it holdsAbout a request
idtextRandom UUID identifying this sign-up, not an account or machine identity.Not about requests
roletextSelected role: host_gpu, host_cpu, relay, witness or developer.Not about requests
hardwaretextHardware description typed by the participant, at most 200 characters; unverified free text, not a prompt sent to a model.Not about requests
readinesstextOptional pasted readiness hints, at most 300 characters; unverified free text, not attestation or a prompt sent to a model.Not about requests
regiontextSelected continent only; not inferred from a network address.Not about requests
contacttextOptional contact typed by the participant, at most 120 characters; may identify them. Null when omitted or blank.Settings written by you or an operator. Voluntarily supplied contact for the owner to respond to interest, not a connection address read from the request. May contain an email, handle or any contact the participant chooses; kept privately until deletion.Not about requests
paid_intextPayout preference only: usdg, anyr or any. Payouts are planned, not available.Not about requests
delete_code_hashtextSHA-256 of a random 32-byte deletion code. The raw code is returned once to its holder.Not about requests
created_attimestamp with time zoneServer timestamp when the sign-up was saved.Not about requests
preset_versionsNot about requests · 10 columns · 1 reviewed

The versions of a preset an account calls as @preset/<name>[@<version>]: one row per saved version, never changed after it is written. A preset is a saved route plus the defaults a route cannot hold: a system prompt, a response_format and tool definitions the account owner writes.

How long: Kept until the account deletes the preset (DELETE /api/v1/presets/:name), which deletes every version.

ColumnWhat it holdsAbout a request
idtextVersion id.Not about requests
account_idtextThe account that owns it.Not about requests
nametextThe name used in @preset/<name>.Not about requests
versionintegerThe version number: 1, 2, 3, ... per preset.Not about requests
hashtextSHA-256 of the version's canonical JSON, so two versions with the same content have the same hash.Not about requests
configjsonbThe preset: models, provider preferences, sampling controls and, when the owner sets them, a description (up to 280 characters), a system prompt (up to 16,000 characters), a response_format and up to 32 tool definitions.Settings written by you or an operator. Written by the account owner through PUT /api/v1/presets/:name and validated by a strict schema (presetDocSchema) with size caps. The system prompt is text the owner saves as a setting, not text taken from a call: requests that use the preset are not stored here or anywhere else.Not about requests
sourcetextput for a saved change, rollback for a version restored from an earlier one.Not about requests
restored_fromintegerThe version a rollback copied; empty otherwise.Not about requests
created_bytextThe key that saved the version.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
sanctions_addressesNot about requests · 3 columns · 1 reviewed

EVM-compatible digital currency addresses extracted from the public OFAC SDN XML for provider admission and USDG payout screening. No names or identity records are stored.

How long: Replaced atomically on a successful refresh; a failed refresh keeps the last good list.

ColumnWhat it holdsAbout a request
addresstextLowercase 0x-prefixed 20-byte wallet address listed by OFAC.A wallet address, not a network address. A public digital currency wallet identifier from the SDN list, never a caller's IP or connection address.Not about requests
list_datetimestamp with time zonePublication date from the SDN XML, at midnight UTC.Not about requests
source_hashtextSHA-256 of the exact downloaded XML bytes; no XML or identity text is retained.Not about requests
sanctions_metaNot about requests · 6 columns

Singleton metadata for the current sanctions list, exposed by GET /api/v1/network/sanctions.

How long: Replaced with the address list on a successful refresh; retained on failure.

ColumnWhat it holdsAbout a request
idintegerSingleton identifier, always 1.Not about requests
list_datetimestamp with time zonePublication date from the SDN XML, at midnight UTC; this date determines freshness.Not about requests
source_hashtextSHA-256 of the downloaded XML bytes.Not about requests
entry_countintegerNumber of distinct EVM-compatible wallet addresses stored.Not about requests
ignored_countintegerNumber of digital currency entries whose identifier is not an EVM-compatible 0x address.Not about requests
refreshed_attimestamp with time zoneWhen the successful download was stored, in UTC; does not reset the publication date's age.Not about requests
saved_routesNot about requests · 9 columns · 2 reviewed

A saved routing policy an account calls as @route/<slug>: ordered fallback models, provider preferences and default sampling settings. It cannot hold prompt or system-prompt text.

How long: Kept until the account deletes the route (DELETE /api/v1/routes/:slug).

ColumnWhat it holdsAbout a request
idtextRoute id.Not about requests
account_idtextThe account that owns it.Not about requests
slugtextThe name used in @route/<slug>.Not about requests
nametextThe route's display name, up to 80 characters.Not about requests
descriptiontextA description written by the account, up to 280 characters.Settings written by you or an operator. A label the owner types about the route (limited to 280 characters). It is a setting, not a request; the API cannot tell what an owner chooses to write.Not about requests
configjsonbThe route: models, provider preferences and a closed list of sampling controls (temperature, top_p, max_tokens, seed, stop sequences and similar).Settings written by you or an operator. Validated by a strict schema (routeConfigSchema) that lists the allowed fields. There is no field for messages or system prompts; the only free text is up to four stop sequences of 32 characters.Not about requests
created_bytextThe key that created it.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
schedulesNot about requests · 14 columns · 1 reviewed

Owner-chosen recurring prompts and the key that pays for each ordinary chat call.

How long: Until the owner deletes the schedule. Deletion cascades to its saved runs. Database backups follow the operator's retention policy.

ColumnWhat it holdsAbout a request
idtextRandom schedule identifier.Not about requests
account_idtextOwning account identifier.Not about requests
owner_hashtextHash of the owner key that last saved the schedule; rechecked before each run.Not about requests
key_hashtextHash of the paying key; its normal budget, rulebook, lane and approval checks apply.Not about requests
nametextOwner-chosen schedule name, also shown in inbox and Telegram.Not about requests
prompt_enctextThe complete owner-chosen prompt, encrypted with AES-GCM using APP_SECRET scoped to the account and schedule.Holds request text. This is stored prompt text, encrypted at rest with a router-held secret. The router decrypts it for scheduled inference; encryption does not prevent Anyroute from reading it.Per request
modeltextSelected model identifier.Not about requests
cadencetextHourly, daily or Monday recurrence.Not about requests
time_utctextUTC hour and minute for daily or Monday recurrence; null for hourly.Not about requests
max_cost_picobigintRequired per-run cost ceiling in pico-USD, checked against the normal worst-case hold before inference.Not about requests
pausedbooleanWhether automatic runs are paused, including after three consecutive failures.Not about requests
failuresintegerConsecutive refused, failed or interrupted run count.Not about requests
next_attimestamp with time zoneNext due UTC instant; missed intervals are coalesced into one run.Not about requests
created_attimestamp with time zoneWhen the owner created the schedule.Not about requests
skillsNot about requests · 22 columns · 4 reviewed

Agent skills published to the Skills Hub: the manifest from SKILL.md, the files as one canonical tar, its SHA-256, where it came from and the static scan report. A skill is public content its author chose to publish; it is not a request.

How long: Kept while the hub lists the skill. A revoked skill stays, marked revoked, so its report and hash remain checkable.

ColumnWhat it holdsAbout a request
idtextSkill id: sk_ followed by the first 24 hex characters of content_hash.Not about requests
nametextThe skill's name from SKILL.md, up to 64 characters.Not about requests
slugtextThe name in lowercase letters, digits and hyphens.Not about requests
versiontextThe version from SKILL.md, up to 32 characters.Not about requests
descriptiontextThe description from SKILL.md, up to 1,024 characters.Settings written by you or an operator. Written by the skill's author in the SKILL.md frontmatter of a skill they publish; shown in the public registry. It is not a request to a model.Not about requests
authortextThe author named in SKILL.md, up to 80 characters.Not about requests
account_idtextThe publishing account, credited the author share of paid installs; empty for a mirrored skill.Not about requests
created_bytextThe key hash that imported the skill; empty for the mirror job.Not about requests
sourcejsonbWhere the skill came from: upload, git (repository URL, ref, commit, folder) or mirror (the registry index).A public address, not a caller's. The public repository URL, ref, commit and folder the importer named, or the registry index the operator configured in SKILLS_SOURCES. It identifies public code, not a caller.Not about requests
filesjsonbThe skill's files: path, type, mode, size and SHA-256 of each, in canonical order.Cannot hold request content. Paths, sizes, modes and hashes computed from the published archive.Not about requests
tar_sha256textThe content hash: SHA-256 of the canonical tar of the files, which a client checks after download and the key on chain (SkillRegistry).Not about requests
archivetextThe files as a gzipped canonical tar (base64), capped at SKILLS_MAX_BYTES unpacked. It is the published skill, served by the download route.Not about requests
sizeintegerUnpacked bytes.Not about requests
file_countintegerNumber of files.Not about requests
leveltextThe scan level: trusted, caution or dangerous.Not about requests
scoreintegerThe scan score, 0 to 100.Not about requests
reportjsonbThe scan report: scanner version, score, level, counts per severity and each finding (rule, file, line, a 160-character excerpt of the skill's own file, severity).A public address, not a caller's. Computed by the scanner from the published skill's files; the excerpts are lines of those files. Nothing from any request is written here.Not about requests
price_usdgbigintInstall price in USDG base units (6 decimals); 0 for a free skill.Not about requests
revoked_attimestamp with time zoneWhen the operator revoked the skill.Not about requests
revoked_reasontextThe operator's reason for revoking it, up to 280 characters.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
spend_alertsNot about requests · 14 columns · 2 reviewed

Alert rules on spend (threshold, share of a budget, anomaly), evaluated by the spend-watch job. They read spending totals, not requests.

How long: Kept until the account deletes the rule (DELETE /api/v1/spend/alerts/:id).

ColumnWhat it holdsAbout a request
idtextRule id.Not about requests
account_idtextThe account.Not about requests
key_hashtextThe key the rule watches; empty means the whole account.Not about requests
kindtextthreshold, budget_pct or anomaly.Not about requests
windowtextday, week or month.Not about requests
thresholdbigintThe spend threshold in pico-USD, for a threshold rule.Not about requests
pctintegerThe budget percentage, for a budget_pct rule.Not about requests
webhook_url_enctextThe address alerts are posted to, if the owner set one. Stored encrypted with the router's APP_SECRET.Settings written by you or an operator. A destination the account owner chose for alerts, stored only as ciphertext. It is not a caller's address.Not about requests
enabledbooleanWhether the rule is on.Not about requests
last_fired_attimestamp with time zoneWhen it last fired.Not about requests
last_periodtextThe period it last fired for, so it fires at most once per period.Not about requests
statejsonbThe rule's firing history and delivery status.Cannot hold request content. Firings and their delivery status written by the spend-watch job (period, amount, status, lease); it holds spend figures, never request content.Not about requests
created_bytextThe key that created it.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
status_dp_hoursSummed from requests · 4 columns · 1 reviewed

The differentially private hourly releases of the private-lane counters (the same releases GET /api/v1/stats publishes), copied as released so the status page can show 90 days for the attested and unlinkable lanes. Copying and summing released values is post-processing: it spends no privacy budget and adds nothing about any request.

How long: Deleted after 91 days by the status loop (services/slo.ts pruneStatus).

ColumnWhat it holdsAbout a request
instancetextA random id of the router process that released the hour (a new one each start), so the releases of several processes can be summed.Summed from requests
hourtimestamp with time zoneThe UTC hour the release covers.Summed from requests
epsilonrealThe privacy budget the release spent (the sum over its families).Summed from requests
countsjsonbThe released noisy counts: requests per lane, refusals per fixed reason and requests per fixed latency bucket.Cannot hold request content. Three objects of noisy integers keyed by the fixed, public label lists of lib/dpstats.ts and services/private-stats.ts, copied from a release that was already public. No request, key or time finer than the hour.Summed from requests
status_incidentsNot about requests · 13 columns · 5 reviewed

Incidents on the public status page: written by the operator through the incident API, or recorded as a suggestion when a lane's availability falls below its target (a suggestion is not shown until the operator confirms it).

How long: No automatic deletion: the incident history is part of the public record.

ColumnWhat it holdsAbout a request
idtextIncident id (inc_... for an operator's incident, sug_... for an automatic suggestion).Not about requests
titletextThe incident's headline, up to 140 characters.Settings written by you or an operator. Written by the operator through POST /api/v1/status/incidents (or a fixed sentence for a suggestion). It is a status notice, not a request.Not about requests
statustextsuggested, investigating, identified, monitoring, resolved or dismissed.Not about requests
impacttextnone, minor, major or critical.Not about requests
lanesjsonbThe privacy lanes affected.Cannot hold request content. An array of lane names from the fixed list public, attested, unlinkable.Not about requests
surfacesjsonbThe API surfaces affected; empty for all.Cannot hold request content. An array of surface names from the fixed list in services/slo.ts.Not about requests
sourcetextoperator or auto.Not about requests
updatesjsonbThe status updates, oldest first: time, status and the operator's text (up to 2,000 characters each).Settings written by you or an operator. Each update is a time, a status from a fixed list and text the operator writes through POST /api/v1/status/incidents/:id/updates; a suggestion's first update is a fixed sentence with numbers. No request text is ever written here.Not about requests
evidencejsonbFor an automatic suggestion: the lanes, surfaces, window, measured availability, target, request count and whether the figure was DP-noised.Cannot hold request content. Numbers and names from fixed lists, computed from status_windows or status_dp_hours, which are themselves sums.Not about requests
started_attimestamp with time zoneWhen the incident began.Not about requests
resolved_attimestamp with time zoneWhen it was resolved.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
status_windowsSummed from requests · 7 columns

The public status page's record of the public lane (GET /api/v1/status/slo): per API surface and five-minute bucket, how many public-lane requests succeeded, failed with a 5xx, were refused with a 4xx or were rate limited, and how many served requests fell in each fixed latency bucket. Requests on the attested and unlinkable lanes are never counted here.

How long: Deleted after 91 days by the status loop (services/slo.ts pruneStatus).

ColumnWhat it holdsAbout a request
surfacetextThe API surface: chat, embeddings, batch, messages, ollama or rerank.Summed from requests
buckettimestamp with time zoneStart of the five-minute bucket (UTC).Summed from requests
okintegerPublic-lane requests answered with a 2xx or 3xx.Summed from requests
failedintegerPublic-lane requests answered with a 5xx: these count against availability.Summed from requests
rejectedintegerPublic-lane requests refused with a 4xx other than 429: the caller's error, not counted against availability.Summed from requests
rate_limitedintegerPublic-lane requests refused with a 429.Summed from requests
latencyinteger[]Served public-lane requests per fixed latency bucket (the edges in lib/dpstats.ts), in edge order: time to first token for streams, time to the full response otherwise.Summed from requests
tool_canary_runsNot about requests · 8 columns

Results of the daily paid canary probe of each listed tool: whether the known answer came back, latency, a failure code, what the probe paid and the settlement transaction.

How long: Deleted after 90 days by the canary job; deleted with the listing.

ColumnWhat it holdsAbout a request
idbigserialRun id, a sequence number.Not about requests
seller_idtextThe tool listing probed.Not about requests
okbooleanWhether the answer matched the listing's known answer.Not about requests
latency_msintegerTime for the probe.Not about requests
failuretextA fixed failure code, or null.Not about requests
price_unitsbigintWhat the probe paid, in USDG base units, if it paid.Not about requests
settle_txtextThe settlement transaction hash the seller reported, if any.Not about requests
attimestamp with time zoneWhen it ran.Not about requests
tool_listingsNot about requests · 18 columns · 1 reviewed

x402 tools a seller account listed for the paid tool catalog (/tools), each with a known-answer canary probe and its current probe state. A Skills Hub skill's paid invocation is a listing that names the skill.

How long: Until the listing account removes it (the row stays with status removed so the address cannot silently change hands); delisted rows stay to show why.

ColumnWhat it holdsAbout a request
idtextListing id (tl_...), also the seller id on tool calls and canary runs.Not about requests
account_idtextThe account that listed the tool.Not about requests
created_bytextKey hash that listed it; never a raw API key.Not about requests
skill_idtextThe Skills Hub skill whose paid invocation this is, or null.Not about requests
nametextSeller-written tool name, up to 80 characters.Not about requests
summarytextSeller-written one-line summary, up to 280 characters.Not about requests
resourcetextThe tool's public https origin and path, without a query string.Not about requests
methodtextGET or POST.Not about requests
price_unitsbigintThe price the tool quoted in its 402 when listed, in USDG base units.Not about requests
pay_totextThe seller's payTo wallet from that quote; calls are refused if the live quote names another wallet.Not about requests
networktextThe x402 network name of that quote.Not about requests
canaryjsonbThe seller-written probe: method, optional query arguments and JSON body, and the expected substring or SHA-256 of a correct answer.Settings written by you or an operator. Written by the listing account and validated against a strict schema; it describes a public probe, never a caller's request or answer.Not about requests
statustextlisted, delisted (three failed probes in a row) or removed.Not about requests
failuresintegerConsecutive failed canary probes.Not about requests
delisted_attimestamp with time zoneWhen the canary rule delisted it.Not about requests
checked_attimestamp with time zoneWhen it was last probed.Not about requests
created_attimestamp with time zoneWhen the row was created.Not about requests
updated_attimestamp with time zoneWhen the row was last changed.Not about requests
webhook_deliveriesNot about requests · 14 columns · 1 reviewed

Durable event references, duplicate suppression and delivery attempt metadata without webhook bodies.

How long: Terminal records are deleted after 90 days by the enabled worker; pending records remain until attempted or cancelled. Destination removal cascades deletion. Each event has at most three recorded attempts, and the API returns the last 100 attempts.

ColumnWhat it holdsAbout a request
idtextRandom internal delivery identifier.Not about requests
destination_idtextOwned destination association.Not about requests
event_idtextStable identifier sent in the event header, shared across retries for duplicate suppression.Not about requests
eventtextFixed event type name; endpoint.check is an owner-requested connectivity notice.Not about requests
referencetextSource identifier only, such as a ledger, policy event, agreement or host id. No source body is copied.Not about requests
event_attimestamp with time zoneSource event time used for retention and ordering.Not about requests
event_statustextFixed source status at discovery, not arbitrary source text.Not about requests
attemptsintegerClaimed delivery attempt count, capped at three.Not about requests
statustextFixed delivery state: pending, delivered, blocked, failed or cancelled.Not about requests
http_statusintegerReceiver HTTP status code, never its response body.Not about requests
latency_msintegerElapsed time for the attempted send in milliseconds.Not about requests
attempted_attimestamp with time zoneWhen the most recent result was recorded.Not about requests
next_attempttimestamp with time zoneRetry lease and due time; ordinary retries wait five minutes.Not about requests
historyjsonbUp to three attempt timestamps, delivery state, HTTP status, latency and retry count.Cannot hold request content. Fixed result codes and numeric timing/count metadata only; excludes webhook bodies, receiver bodies, URL, signature headers, signing secret and exception text.Not about requests
webhook_destinationsNot about requests · 11 columns · 3 reviewed

Owner-controlled HTTPS destinations, encrypted signing credentials and subscriptions for account event notices.

How long: Until destination removal or linked Spend Watch rule deletion. Revocation erases the encrypted signing key and stops deliveries; database backups can outlive removal.

ColumnWhat it holdsAbout a request
idtextRandom destination identifier, scoped to one account.Not about requests
account_idtextAccount whose owner manages this destination.Not about requests
created_bytextAPI key hash used for visibility and authorization; never a raw API key.Not about requests
key_hashtextOptional key scope inherited from a Spend Watch rule; null is account-wide.Not about requests
rule_idtextOptional linked Spend Watch rule identifier, removed with that rule.Not about requests
url_enctextHTTPS URL encrypted under APP_SECRET; path and query can hold receiver credentials. API responses show scheme and host only.Settings written by you or an operator. Owner-supplied delivery endpoint sealed using APP_SECRET, never the caller network address. URLs can identify the receiver and carry credentials, so only scheme and host are returned.Not about requests
secret_enctextServer-generated random signing secret encrypted under APP_SECRET, null for an unsigned legacy or revoked destination. Plaintext is revealed only on creation or rotation, never in subsequent reads or delivery logs.Not about requests
revokedbooleanWhether delivery has been stopped and its signing credential removed.Not about requests
eventsjsonbSelected fixed event type identifiers.Settings written by you or an operator. Strict event names chosen by the owner, excluding arbitrary text, addresses, prompts or answers.Not about requests
scanjsonbBounded reader progress: time window, activity cursor and sweep time.Cannot hold request content. Only timestamps, pagination filter digest and event identifiers; no activity bodies, intent text, endpoint URL or credentials.Not about requests
created_attimestamp with time zoneCreation time and lower bound for event discovery.Not about requests

In your browser.

What this website keeps in your own browser. None of it is sent to us except the requests you make.

The prompt library keeps names, text, tags, pins, optional model choices and system prompts in this browser until you delete them or clear browser storage. Ordinary prompts use the anyroute-harness-prompts-v1 localStorage key without encryption. Private-mode prompts share the encrypted anyroute-private-history IndexedDB vault and its passphrase; locking or forgetting history also locks or deletes them. Where IndexedDB is unavailable, private prompts last only for this tab. The two libraries stay separate. JSON exports contain readable prompt data, including system prompts. Prompts are sent through the existing chat path only when you submit them. Prompt storage source · Encrypted storage source

  • IndexedDB (existing encrypted Chat history vault): Opt-in Chat folders keep up to 40 folder ids and names plus each saved chat's optional folderId inside the same passphrase-encrypted anyroute-private-history vault as chats and private prompts. No additional browser storage key or server table, column, Redis family or log field is created. Unlocked folder names, assignments, counts, selection and search text live in page memory; counts are derived from chats and selection/search are not persisted. A drag carries only a chat id in browser drag data. Deleting a folder removes its assignments and keeps every chat. Locking drops the decrypted folders with history; Forget deletes the vault. Without browser storage the existing memory fallback lasts only for the tab. JSON downloads expose readable chats, folder ids/names and assignments, including empty folders in a full-history export; single-chat downloads include only its folder. Import validates and merges this metadata in one encrypted write, maps colliding folder ids and keeps existing chats. Markdown exports omit folder organization. Folder operations do not upload data; ordinary inference requests are still read by the router in memory. web/lib/chat-folders.js
  • Session storage (anyroute-model-compare-v1): Up to three public model IDs selected for comparison. Clear picks removes the selection; session storage lasts until the tab closes. Blocked storage falls back to page memory until navigation. Comparison links expose selected IDs in the URL to recipients and ordinary web request handling. Public models, providers and endpoint responses are read without an account key and held in page memory. No prompts, answers, wallet addresses or account secrets are read by comparison code. No new table, column, Redis key family or log field. Ordinary Chat still sends request text that the router reads in memory. web/lib/model-compare.js
  • IndexedDB (existing encrypted Chat history vault): Each Chat folder may keep instructions of up to 4,000 characters in its optional instructions field, inside the existing passphrase-encrypted history document. There is no new browser key, server table, column, Redis family or log field. The editor draft, current folder and ordered system messages are decrypted page memory only; locking or forgetting history removes the active folder metadata and editor draft, so later requests no longer use them. System-message snapshots already attached to on-screen replies or linked summaries remain in page memory for context counting until those chats are reset or the page closes; they are not saved in history. Closing the editor drops its draft. JSON exports and imports carry readable instructions with folder metadata, including single-chat exports; matching folder names keep the existing instructions. Markdown omits this metadata. From the next message after a move or edit, inference sends the current folder instructions as the first system message before the chat prompt; the router reads request text in memory on every lane. Copy as code also contains readable instructions. Context and cost estimates read them in browser memory. Empty instructions add no request message. web/lib/folder-instructions.js
  • IndexedDB (existing encrypted Chat history vault): Optional lane branches metadata keeps message versions as parent-linked nodes and selected message ids in the existing passphrase-encrypted anyroute-private-history vault. Each node keeps user or assistant text, ids, file names, prepared input images, supported generated image links or bytes, image mode, model/provider, reported token counts and cost, latency, receipt id/lane/disclosure, reply status and errors, and tool call ids/names/arguments or tool result text. Document contents, audio and reasoning are not saved. Decrypted versions and unsaved attachments live in page memory; locking drops the vault key and decrypted history, while a conversation already on screen remains in page memory. Forget deletes the vault. Branches share the existing chat size limit, folders and saved answers; no browser storage key, server table, column, Redis family, log field or server reader is added. JSON downloads expose all versions as readable data; imports validate the optional fields and older clients can ignore them. Markdown shows the selected version. Only the selected path is sent for inference and counted in the displayed context and chat cost; earlier versions were billed when requested and switching does not refund them. The router reads ordinary inference requests in memory. Switching versions sends nothing to the router. web/lib/harness-branches.js
  • Existing passphrase-encrypted Chat history vault: Saved chats and folders may keep an optional project field (a lowercase label of 1–48 letters, digits, dots, underscores or hyphens, or null to follow the default). The chat override wins over its folder default; absent selections leave the key default to the router. Choices persist only with history enabled. The active chat choice, project editor draft, account project suggestions and budget details live in page memory; closing the editor drops its draft and suggestions. Locking history drops folder defaults from later requests; the visible chat choice stays in memory until reset or page close. Forget deletes the existing vault. JSON exports expose readable chat and folder project fields; validated imports preserve them, with existing same-name folders winning. Markdown includes only chat overrides. Copy as code contains the effective header. Every Chat send, summary, retry and continuation passes X-Anyroute-Project to existing server capture and budget checks. Anyroute can read these labels, and the router reads request text in memory on every lane. Labels do not change older charges or signed receipts. Existing owner-only project list and budget APIs supply suggestions and details using the current key; no guard is widened. No new browser store, server table, column, Redis key family, log field, address reader or body reader. web/lib/chat-projects.js
  • Existing encrypted Chat history vault and localStorage preferences: Each saved chat may keep spendingCap as a positive integer micro-dollar string in the existing passphrase-encrypted anyroute-private-history vault. Removing a cap omits the field. History must be enabled to keep a cap after closing the page; locked vaults drop decrypted history from memory and Forget deletes the vault. JSON history exports expose this readable field and validated imports retain it; Markdown exports include the cap as readable text. The existing anyroute-harness-prefs localStorage record holds defaultChatCap (a micro-dollar string or null) until changed or browser data is cleared. The default is not encrypted. Denied storage keeps the default in page memory only. Unlocked cap values, estimates, editor amounts and a held-send callback with its draft and attachments live in page memory. Editing the request or changing the chat clears the held action. A one-send override is not persisted. No new table, column, Redis family, log field, server address reader or body reader. Checks reuse chat costs and catalogue estimates in the browser and do not upload anything; ordinary inference requests still pass through the router, which reads their text in memory. This browser guard does not enforce a hard billing limit. web/lib/chat-cap.js
  • Page memory and existing Chat message handling: Highlighted assistant answer text and floating-button position stay in page memory while selected. Ask about this inserts at most 1,500 selected characters, including a truncation ellipsis, as a plain-text quote in the existing composer. There is no new storage key or separate saved selection. Once sent, quoted text is ordinary message content: it follows existing optional encrypted Chat history, exports and inference request handling. The router reads ordinary inference text in memory. No new table, column, Redis family, log field, server address reader or body reader. web/lib/ask-about-this.js
  • IndexedDB and browser memory: Continue adds text to the selected answer version in the existing opt-in, passphrase-encrypted Chat history vault and exports. Optional finish and servedModel keep the finish reason and responding model id. continuationCalls keeps browser-generated call ids for deduplicating copied comparison history, receipt ids, provider names, finish reasons and reported prompt tokens, completion tokens and dollar cost per call; the reply usage and chat cost include the additional reported charges. No full signed receipts, credentials or continuation instruction are added to saved call records. The conversation including the cut-off answer and a short user instruction is sent through the existing authenticated inference path; the router reads ordinary request text in memory. Folder instructions and system prompt still apply. No new table, column, Redis key family, log field, body reader, address reader or browser storage key. Lock and Forget use the existing vault controls. web/lib/harness-continue-history.js
  • IndexedDB: Chat history is opt-in and encrypted with the browser history passphrase in the existing anyroute-private-history vault (memory only when storage is unavailable). Alongside saved conversations, costSummary keeps microUsd as an integer decimal string and replies as a count, summed across comparison lanes from the displayed reply costs. Totals include replies omitted from saved content; failed replies add zero dollars. Totals and counts are encrypted with the conversation, not stored separately or sent to the router. Locking drops the decrypted history from memory; Forget deletes the vault. Older chats without this summary use the costs in their retained replies. web/lib/private-history.js
  • IndexedDB: The optional savedAnswers field in the existing anyroute-private-history encrypted vault holds separate copies of reply text, preceding question text, model, reported cost (or null), save date, receipt ID (or empty), chat ID, message ID and a deduplication ID. It uses the existing passphrase-derived key and serial write queue; there is no new browser database or router store. The collection is limited to 256,000 UTF-8 bytes and 1,000 entries. It survives deleting or trimming chats. Searching uses decrypted questions and answers in memory while history is unlocked. Locking discards decrypted answers; Forget deletes them with the vault. Without IndexedDB, storage lasts only for the tab. Existing history exports and imports include saved answers, including copies whose chats were deleted; downloads are readable text. Reply text excludes images, attachments, reasoning and tool results. This does not change the router's in-memory reading of requests. web/lib/saved-answers.js
  • localStorage: Getting started keeps Hide, all-steps-complete and receipt-visit booleans plus at most 100 receipt ids read from authenticated account data under anyroute-getting-started-v1:<connected key public hash>. No API key secret, balance, call text, Telegram user id or rulebook is stored. Home reads existing balance, key, agent, activity and Telegram link APIs in memory within their existing access boundaries. Opening /verify with a remembered receipt id marks only a visit, not signature validity; arbitrary public receipt ids do not count. Preferences do not sync between devices and survive until browser storage is cleared. If storage is unavailable, Hide applies to the current view only and receipt visits cannot be remembered. These stored preferences and ids are not sent to the router; the existing verify page still requests the named receipt and its privacy label. web/lib/getting-started.js
  • localStorage: Account checkup stores up to 2000 dismissed item identifiers under anyroute-account-checkup-v1:<connected key public hash>. Key and agent item identifiers include their public key hashes. No key secret, account value, network address, request text or rulebook is persisted by checkup. It composes existing authenticated key, agent, Telegram link, balance alert, security alert and notification settings reads in browser memory with their existing visibility and guards. Fix links carry a public key hash and fixed control name where needed; they open existing editors and do not save changes. Read-only keys are refused by the browser checkup reader. Dismissals are never sent to the router and remain until restored or browser storage is cleared; unavailable storage keeps dismissals in the current view only. Existing APIs do not expose counts of places using a key, so IP-list suggestions do not infer locations. No new server persistence or readers. web/lib/account-checkup.js
  • Browser and service-worker memory: Phone sharing reads title, text and URL fields into an unsent Chat draft. GET query fields may reach hosting access logs and browser history before the page removes them from its address. The installed service worker intercepts the multipart POST without forwarding it; it reads at most 48 MB plus 64 KB of framing and fields. Up to two pending shares retain capped text and up to six original image files (8 MB each), including their original metadata and names, in worker memory only. Handoffs are single-use and expire after five minutes; expired entries are removed on the next share or handoff, and browser worker termination drops all entries. A third share evicts the oldest. The page holds received original files in memory until a vision model is selected, then the existing attachment path re-encodes JPEGs with metadata stripped; navigation releases page memory. No persistent share cache, new router body or address reader, database column, Redis key or log field. Sending uses normal Chat authentication and retention; ordinary request text is read by the router in memory. web/lib/share-worker.js
  • localStorage: Appearance choice: anyroute-theme-v1 stores only light or dark until changed or browser data is cleared. Match device removes the key. The preference is never sent to the router; denied storage keeps the choice only on the current page. web/lib/theme.js
  • Cache Storage: The installable Harness keeps only the static app shell, offline page, scripts, styles, fonts and icons in a browser cache named anyroute-shell- followed by a build digest. Each cached file must match its exported SHA-256. Requests, replies, API responses and URLs with query strings are never cached. A new active app version removes older app caches; browser settings can clear them at any time. No additional data is stored by the router. web/lib/harness-sw.js
  • sessionStorage: The API key you pasted into the dashboard, for the length of the tab. It is removed when the tab closes and is never written to localStorage. web/lib/api.js
  • localStorage: The Harness favourite models and view preferences, and the Eval Lab evaluation sets you write. Eval Lab results are kept in IndexedDB. The router never receives them; only the requests you run do. web/components/Harness.jsx

The inventory is read from src/privacy. The check that keeps it true is in the repository. The full text of the file this page is built from is at /keep/inventory.json (502 KB).