# Data policy

RouterPlus sits between your application and model providers. This page lists what RouterPlus
stores, for how long, and what each provider keeps.

- RouterPlus records request metadata for billing and operations.
- RouterPlus records request and response content from non-dedicated endpoints for debugging.
  It keeps these request logs in a private, encrypted storage bucket for up to 30 days.
- Request logging excludes dedicated endpoints and private installations, also when a dedicated
  endpoint falls back to a public model. It also excludes organizations that opt out.
- [Optimize](/docs/model-search) stores the eval cases and candidate answers of a search, for
  your organization only, until you delete the search.
- Each provider has its own retention policy. See
  [What providers do with your prompts](#what-providers-do-with-your-prompts).

## Request data

Request content goes only to the request log. Billing and analytics hold no content:

| Store | What it holds | Content? |
|---|---|---|
| Request log | Requests and responses from non-dedicated endpoints, with recognized credentials removed and size limits applied, for up to 30 days ([details](#request-logging)) | Yes |
| Process logs | Request id, surface, model, outcome, HTTP status. Every buyer-controlled string is sanitized first. | Never |
| Telemetry (analytics) | Ids, org and key ids, provider, deployment, model, region, attempt ordinal, outcome, error code, statuses, timestamps, latency, five token counts, request and response *byte sizes*, cost, provider request id (house routes only, see below). Also: the calling software's name, version and User-Agent header (keys and email addresses removed); the finish reason; the output limit sent and whether the gateway set it; the number and types of tools (never their names or schemas); whether the request was cancelled before the first token; and the provider's error code with its message scrubbed of content (quoted text, names you chose, values, keys and addresses removed). | Never |
| Billing ledger | One row per attempt: the prices in force, reserved maximum, settled cost, token counts, HTTP status, error code, provider request id (house routes only, see below), timestamps, route and admission context | Never |
| Rendered pages | Model directory, model pages, console, status. All render from metadata. | Never |

Details:

- **Process logs include model names**, as routing metadata. RouterPlus sanitizes the
  buyer-controlled strings in those logs: it strips control characters and caps the length.
  Request content goes to the request log as structured records.
- **Error bodies never echo your input.** Every error body is the gateway's own typed shape.
  RouterPlus never relays a provider's raw error body. When a refusal is translated across
  dialects or sent mid-stream, the gateway sends only the typed error class.
- **Telemetry records byte sizes, not bodies.** It keeps `request_bytes` and `response_bytes` to
  measure throughput.
- **Image requests follow the request-log policy.** On
  [`/v1/images/generations`](/docs/api-images), prompts, generated image content and any
  `revised_prompt` can appear in request logs, within the size limits below. Telemetry and the
  billing ledger do not hold them.
- **Video creation requests follow the request-log policy.** The prompt and creation response
  can appear in request logs. The video file streams from the provider when you download it.
  RouterPlus does not keep it.
- **The Playground keeps its chat history in your browser:** conversations in local storage and
  images in IndexedDB, filed by your sign-in, the conversation and the reply. Requests you send
  from the Playground follow the request-log policy. Deleting a chat, or **Clear all**, deletes
  the browser's copy. It does not delete a request log already recorded.
- **Playground decisions follow the request-log policy.** Their state, questions, options and
  answers can appear in request logs. Telemetry and the billing ledger keep metadata such as
  model, provider, token counts and cost.
- **Request logs exclude authentication headers.** The gateway removes recognized API-key formats
  and the request's provider credentials before it writes a record. It authenticates API keys by
  comparing a SHA-256 hash. See the redaction limits below.
- **The provider request id is kept on house routes only.** A provider gives each call this
  reference number, so you can trace a failed call with that provider. A house route runs on
  RouterPlus's own provider account. A call through a provider credential you connect (BYOK)
  never keeps the id. A provider can put the API key into that header, so the gateway drops an
  id that contains the key it sent, or any 16 characters of the key in a row. It also drops an
  id longer than 256 characters.

> [!NOTE]
> For local development, `TM_UNSAFE_LOG_BODIES=1` prints request bodies to stdout.
> The flag refuses to activate outside the `local` and `demo` regions. A production
> deployment that sets it gets a logged warning and no body logging. In every region,
> it never touches telemetry or the ledger, and it never prints an image prompt.

Tests check that content stays out of process logs, telemetry and the billing ledger. They also
check that request logging respects endpoint exclusions, opt-outs, credential redaction and size
limits.

## What we do store

To run an account, RouterPlus stores this data:

| Data | Why | Form |
|---|---|---|
| Email address | Sign-in and billing receipts | Canonicalized: lowercased, Gmail dots and `+tags` collapsed, `+tags` stripped elsewhere. Aliases share one account and one promotional-credit eligibility. |
| Members' emails | Organization membership and roles | Canonicalized the same way |
| API keys | Gateway authentication, and copying a key again from the console | SHA-256 hash plus the first 12 characters, so the console can show you *which* key. The gateway checks only the hash. Keys created since 17 October 2026 also keep an envelope-encrypted copy (AES-256-GCM, its key held outside the database), so an owner or admin of your organization can copy the key again. Each copy is recorded. Disabling a key deletes its copy. An organization can ask RouterPlus to turn copying off. RouterPlus then deletes its copies and keeps no new ones. |
| Legacy and operator-issued email-link tokens | Redeeming sign-in links issued earlier | SHA-256 hash only, single use, 30-minute expiry |
| Clerk identity and session references | Connect verified sign-ins to the same account, and sign-out | Clerk issuer, user and session ids, verified canonical email, organization id and session timestamps |
| Authentication email delivery ids | Prevent duplicate sends when the Clerk email relay is on | Message id, outcome and timestamp only. No email body, sign-in link or recipient. |
| Per-attempt metadata | Billing and the usage you read back | The ledger row described above |
| Provider credentials you connect (BYOK) | Routing through your own OpenAI, Anthropic, Azure or Bedrock account | Envelope-encrypted. No API or page returns them. A Bedrock connection stores a role ARN, never AWS keys. |
| Braintrust API key (Optimize) | Reading your evals | Encrypted. Only its last four characters are shown. |
| Optimize searches | Comparing models on your evals | The eval cases and the candidates' answers, scoped to your organization, deleted with the search |
| Video jobs | Following a render across reloads | Job id, model, length, shape, status and charge. Never the prompt or the file. |
| App attribution | Optional `HTTP-Referer` and `X-Title` headers you send | Stored as sent, in telemetry. Send them only if you want your app identified. |
| Request log | Find and fix errors on non-dedicated endpoints | Requests and responses, recognized credentials removed, size-limited, encrypted, deleted after 30 days ([details](#request-logging)) |

RouterPlus does not store passwords. Clerk handles passwords, email verification and Google
sign-in.

- Google sign-in requests basic identity information (OpenID, email and profile). It does not
  request access to Gmail, Drive or Calendar.
- RouterPlus uses the verified email to find your existing account, including accounts first
  created through an email link.
- Clerk processes authentication data under its
  [privacy policy](https://clerk.com/legal/privacy).

Resend can deliver authentication emails, including Clerk-generated email links. The relay
verifies the sender's signature. It does not log or keep the email body or sign-in link. Resend
processes delivery data under its [privacy policy](https://resend.com/legal/privacy-policy).

## Request logging

| Topic | Rule |
|---|---|
| **Which requests** | Model requests to non-dedicated endpoints: chat, messages, responses, compaction, image generation, decisions, video creation and token counting. Dedicated endpoints are excluded, also when a request is refused or falls back to a public model. Private installations and organizations that opt out are excluded too. |
| **What is stored** | The request as the gateway received it, the upstream request and response details it has, and the response returned to the caller (JSON or streamed content). Also the request metadata above, selected client headers such as `User-Agent`, and your key's first 12 characters, which the console shows too. |
| **Size** | A record is normally at most 2 MiB, and up to 16 MiB for a configured program. Large fields can be truncated. Logging is best effort, so not every request has a complete record. |
| **What is removed** | The `Authorization` and `x-api-key` headers, cookies, and headers outside the request log's allowlist. The gateway also replaces with `[REDACTED]`: keys in recognized formats (RouterPlus, OpenAI, Anthropic, AWS, Google, GitHub, Stripe, Slack and private keys) and the provider credential the request used, including one you connect (BYOK). Other secrets in your prompts can be stored as you sent them. |
| **Where, and how long** | An encrypted, non-public storage bucket in RouterPlus's AWS account. The gateway can write records but cannot read them. Records are deleted after 30 days. |
| **Why** | To investigate errors and replay requests in tests, so RouterPlus can fix their cause. RouterPlus does not train models on these records and does not share them. |
| **Opt out** | Contact support to stop request logging for your organization. This does not change the provider's own retention policy, and it does not delete records already kept. |

## Hackathons and similar programs

Requests from accounts in a hackathon or similar program are stored for up to 30
days to find and fix errors.

Program invitations show this notice. A program's logging mark has an end date. After that date,
requests to non-dedicated endpoints can still be logged under the general policy above.
Dedicated endpoints, private installations and organization opt-outs stay excluded.

## Account authentication

Public signup and sign-in use Clerk in the browser at [Sign up](https://demo.routerplus.com/signup) and
[Sign in](https://demo.routerplus.com/login). Complete the email-verification and authentication steps
there. There is no magic-link submission or programmatic signup route. Clerk connects a verified
email to the same account, so existing accounts and API keys stay as they are.

Sessions:

- After Clerk verifies a sign-in, RouterPlus issues its own seven-day signed session cookie
  (`HttpOnly`).
- **Sign out** revokes that cookie and the linked Clerk session. Other devices stay signed in.
- RouterPlus rechecks Clerk-backed sessions during authenticated requests, with cached proof for
  at most 30 seconds. After that, a revoked or expired Clerk session cannot authorize new
  requests.

The browser also stores two items beside the session cookie. Neither is a credential, and signing
out clears both:

- A sign-in hint (`tm_in`, the same expiry, readable by script) that says only "signed in".
- A display cache (`localStorage["tm-acct"]`): your email and your balance as the last page
  showed them.

They let every page draw your account menu and credits at once.

Email links issued earlier, and operator-issued links, use stored SHA-256 token hashes, so a
leaked database row is not a working link. These links are single-use and expire. They are not a
public account-creation route.

See [Authentication](/docs/authentication) for browser onboarding and API keys.

## What providers do with your prompts

The provider that serves your request has its own retention policy, apart from RouterPlus's
request logs. Every provider in the catalog declares its prompt retention in its manifest before
it can serve traffic:

```json
{
  "provider": {
    "id": "anthropic",
    "privacy_policy_url": "https://www.anthropic.com/legal/privacy",
    "prompt_logging": "retained"
  }
}
```

`prompt_logging` is `"none"` or `"retained"`. A manifest without it, or without a privacy policy
URL, fails conformance and never goes live. You can see the value in two places:

- On every **model page**. The Data policy card links to this policy and says how many of the
  model's providers offer zero data retention. The providers table has a **Retention** column
  per provider. It describes the provider, not RouterPlus's request log.
- In the catalog, per provider of each model:

```bash
curl -s https://demo.routerplus.com/api/models.json | python3 -c \
  'import json,sys; [print(m["id"], ":", [(p["id"], p["prompt_logging"]) for p in m["providers"]]) for m in json.load(sys.stdin)["models"]]'
```

Every provider in the catalog today declares `"retained"`, per their published
policies, except Fastino, Cloudflare Workers AI, Perplexity, DeepInfra (its open models) and RouterPlus.
RouterPlus reports each provider's flag as declared. The sections below give the basis for each
provider with a specific policy.

### Levanto

Levanto, which serves the decision model Sage, keeps no ordinary request. It keeps the full
request of a failed or slow one for 30 days to debug it. Levanto declares `"retained"`.

### Fastino

Fastino, which serves the decision model GLiNER-2.5-Decide, declares `"none"`.

- Fastino keeps an inference unless the request says `store: false`. The gateway sends
  `store: false` on every request.
- Fastino's terms let it train on inputs unless a team has Zero Data Retention on. Our Fastino
  team has it on.

### Cloudflare Workers AI

Cloudflare Workers AI, which serves the decision models Clef and Clef-flash,
declares `"none"`, on Cloudflare's own statements.

- Of Clef, Cloudflare says: "we don't read, store, or train on your requests or responses
  (unless you want to use our fine-tuning product)". RouterPlus does not use that product.
- Cloudflare's Workers AI data-usage page says that Cloudflare does not use a customer's content
  to train any AI model on Workers AI, or to improve any Cloudflare or third-party service,
  without the customer's explicit consent.
- The same page says that Cloudflare stores the content only if the customer uses a Cloudflare
  storage service (R2 or KV, for example) with Workers AI. RouterPlus uses none.
- The gateway calls the Workers AI REST API directly. It never sends Cloudflare's AI Gateway
  header (`cf-aig-gateway-id`), so requests do not go through AI Gateway,
  whose logs are on by default and can hold the full prompt and response. Cloudflare's replies carry none of AI
  Gateway's `cf-aig-*` headers.

### Perplexity

Perplexity, which serves the decision model Perplexity Decider v1 27B, declares `"none"`, on
Perplexity's own statements.

- Its API FAQ says: "We do not retain any query data sent through the API and do not train on
  any of your data."
- It also says that the API has zero day retention of user prompt data by default, never used
  for AI training, and that its compute is hosted on Amazon Web Services in North America.
- Perplexity keeps the usage metadata it bills from, such as the number of requests and tokens
  (its API FAQ).
- The gateway calls Perplexity's API directly, with our one Perplexity key.

### DeepInfra

DeepInfra, which serves fifteen open chat models (DeepSeek, GLM, Kimi, MiniMax, Hy4, Gemma, MiMo
and gpt-oss), declares `"none"`, on DeepInfra's own statements.

Its data-privacy page says that it does
not store the data sent to its inference APIs on disk. It holds the data in memory only while it
runs the request. It does not log request content. It records only metadata such as the request
id, the cost and the sampling parameters.

- DeepInfra does not train on API data. Its exceptions are Google's and Anthropic's models,
  which this listing does not carry.
- The gateway calls DeepInfra's OpenAI-compatible API directly, never its bulk inference API
  (which can keep data longer).

DeepInfra's second listing, `deepinfra-labs`, carries Google's and Anthropic's models: Claude
and Gemini, which DeepInfra relays to Anthropic and Google under their own data and training
policies. This listing declares `"retained"`, as the Anthropic listing does. It is Claude's
fallback after Anthropic direct.

### Morph

Morph, which serves its Fast Apply models, Kimi K3 Fast and five open models, declares
`"retained"`. Morph publishes zero data retention only for self-hosted deployments. Its hosted
API records requests for its traces dashboard. Its inference runs in the US, and DeepSeek V4.1
Flash in Japan.

### Mistral AI

Mistral AI, which serves its own models (Mistral Large, Medium, Small, Ministral and Codestral)
and is GLM 5.3's last route, declares `"retained"`. Mistral keeps API prompts and answers for 30
days to monitor abuse, unless the account has zero data retention on.

### Bespoke Labs

Bespoke Labs, which serves the decision models Bespoke Nimble v4 and v4 Max, declares
`"retained"`. Bespoke keeps API inputs, outputs and request logs for up to 30 days, to debug the
service and check for abuse, and then deletes them. It also keeps the metadata it bills from
(token counts, times, key id, status). Bespoke does not train on API content unless an
organization opts in, and ours does not.

### OpenAI

OpenAI, which serves the decision model GPT-6 Luna Decisions (deployment
`openai-decisions`), declares `"retained"`. OpenAI keeps abuse-monitoring logs of
`/v1/decisions` requests for up to 30 days. Zero Data Retention needs an eligible account and an
agreement with OpenAI, and our organization does not have it. OpenAI does not train
on API data by default. The gateway calls OpenAI's API directly, with our one OpenAI key.

### RouterPlus

RouterPlus serves its own decision models, Decider 2B and Kev 4B, and
this page is its data policy. Its GPUs run in the United States.

- The RouterPlus model service writes no request logs.
- It keeps a cache of its answers: each answer and its usage, for 600 s (10 minutes).
- The cache key is the RouterPlus API key, the model and the exact request body, byte for byte.
  Only an identical request gets a cached answer.
- A cache entry is never shared across RouterPlus keys. The gateway sends every request with
  our one RouterPlus key, so an identical request from any buyer within 600 s can get the cached
  answer, which repeats your option names.
- The cache is all it keeps, so the listing declares `"none"`.
- RouterPlus does not use your states, questions or answers for training.

On the gateway, requests to RouterPlus models follow the request-log policy above, as for every
provider.

## Reading your own metadata back

Read your billing and usage metadata with your API key:

```bash
curl -s -H "Authorization: Bearer $TM_API_KEY" https://demo-api.routerplus.com/v1/usage
curl -s -H "Authorization: Bearer $TM_API_KEY" "https://demo-api.routerplus.com/v1/generation?id=<request_id>"
```

Both endpoints read the billing ledger: balance, attempts, token counts and settled cost.
Neither returns message content. See [usage and generation](/docs/api-usage).

> [!TIP]
> To audit a request later, keep the `x-request-id` response header from the
> original call. It is the lookup key for `/v1/generation`, and the id RouterPlus
> uses if you write in about a billing dispute.

See [Errors](/docs/errors) for the error taxonomy.
