Data protection and GDPR
What odnoga stores, where it goes, how long it stays, and how to answer a request from one of your users.
odnoga is a processor. You — the workspace owner — are the controller for the prompts you send and the end users you identify. The model vendors you route to are sub-processors. Nothing on this page is legal advice; it is a description of what the platform actually does, so your own assessment has something factual to stand on.
What is stored
| Data | Stored | Notes |
|---|---|---|
| Request metadata | always | Model, vendor, tokens, cost, latency, status, region, your app/function labels, your end-user id. |
| Prompt and response bodies | only if you turn on raw capture | Off by default. When on, kept for the TTL you set — 24 hours by default — then deleted. |
| End-user identifier | when you send one | Your opaque id. See the pseudonymisation rule below. |
| End-user contact details | only if you pass them | email, name, phone on a billing call. Encrypted at rest. |
| API keys, Stripe secrets, webhook secrets | always | In a dedicated secrets vault, never returned by any endpoint. |
odnoga never trains on your data and never shares it between workspaces.
Pseudonymisation is enforced, not requested
Send an opaque id in x-odnoga-end-user — your primary key, not an email. If the value looks like an email
address or a phone number, odnoga replaces it with a stable pii_<digest> hash before storing it. Attribution,
metering and A/B stickiness keep working on the hash; the raw value is discarded and never written.
The identifier is also never forwarded to the model vendor. The OpenAI-compatible user field is stripped from
the upstream payload, so your users are not identifiable to OpenAI, Anthropic, Google or anyone else through odnoga.
Retention
| Setting | Default | Where |
|---|---|---|
| Request log retention | 90 days | Organisation → Defaults |
| Raw capture | off | Settings → Raw capture |
| Raw payload TTL | 24 hours when capture is on | Settings → Raw capture |
| Retention mode | full | full, metadata_only, or none |
metadata_only keeps the billing and analytics record and stores no bodies. none goes further. Both can be set
per workspace, and a single request can ask for something stricter than the workspace setting with the
x-airouter-retention header — never looser.
Where processing happens
odnoga's own data lives in the EU. Model inference happens wherever the vendor endpoint you are routed to lives, which you control:
x-airouter-region: eu | us | globalper request, or a workspace default (globalunless you change it).- Residency mode is
preferredby default — odnoga uses a regional endpoint when the vendor has one and falls back when it does not. Set it tostrictand a request that cannot be served in-region is refused rather than routed elsewhere. - Every response carries
x-airouter-region-honored, which is1only when the call actually left through a regional endpoint. It is evidence, not an intention — log it if you need to demonstrate residency later.
Sub-processors
Model vendors receive your prompt content when you route to them. They receive no end-user identifier.
Infrastructure: Supabase (hosting, database, secrets — EU region) · Stripe (payments) · Resend (transactional email).
Model vendors, when you route to them: OpenAI · Anthropic · Google · xAI · Mistral · Perplexity · DeepSeek · Groq · Cerebras · Fireworks · Together · DeepInfra.
You control which of these are reachable: an allow-list of models per workspace means a vendor you have not allowed never receives anything. A vendor odnoga holds no key for is never called at all.
Each vendor's own retention and training terms apply to what they receive — several offer zero-retention or no-training tiers, and choosing a model is choosing those terms. Check the vendor's policy for the models you enable.
Answering a request from one of your users
Both work on the id you send in x-odnoga-end-user, or on an email address on file.
Access / portability (Articles 15 and 20). Workspace → Privacy, or the MCP tool end_users.export. Returns the
profile, whether an email / name / phone is on file, and the request history attributed to that user. It reports
whether contact details exist rather than printing them, so an export is safe to hand over.
Erasure (Article 17). Workspace → Privacy → Erase. It deletes stored payloads for that user, strips the identifier from historic request records while leaving the billing totals intact, clears their contact details, and removes their payment-provider linkage. It is written to an audit log your tenant admins can read.
Erasure requires a fresh step-up authentication and is deliberately not available over the API or MCP. It cannot
be undone, and an irreversible deletion of another person's data should not be one tool call away from an automated
agent. end_users.export says so when an agent reaches for it.
Security posture
- Tenant isolation is enforced in the database, not in application code.
- Secrets live in a dedicated vault, separate from the data that references them; they are never returned by any endpoint, and logs show a prefix only.
- odnoga holds no unrestricted credential for your Stripe account. Connecting Stripe takes a restricted key with five permissions — create customers, create checkout sessions, create billing-portal sessions, read subscriptions, send meter events. odnoga cannot charge, refund, read your balance or move money, and an unrestricted key is refused. Your Stripe account, customers and payouts remain entirely yours; revoke odnoga at any time by deleting that key in your own Stripe dashboard.
- Contact details are encrypted at rest under a key held separately, and searchable only through a keyed hash.
- Every administrative change — key rotation, settings, erasure — is written to an audit log visible to tenant admins.
- Two-factor authentication is available and can be required organisation-wide.
See also: Security for the key and token model.
Data processing agreement
If your procurement or DPO needs a signed DPA, a sub-processor notification commitment, or answers to a security questionnaire, contact us — these are handled per customer rather than as a click-through.