product
The same protection for every way text reaches a model.
OBVELO sits between your systems and your model provider: it replaces every personal value with a token, passes the request on, and puts the real values back into the answer. An application, an agent, a file or a person typing into a chat window — one engine, one set of rules.
652
detection rules, 19 categories, 52 jurisdictions
4
API surfaces, one result
0
request content stored
EU
hosting and sub-processors
how it works
One request, three states
OBVELO swaps every personal value for a token on the way out and puts it back on the way in. The mapping travels with the request and stays with you — there is no vault on our side to leak from.
connect it
You change one field — the API address.
Two ways, the same masking. With the SDK your model key never reaches us; through the proxy you point your provider's client at the gateway and add one header.
from openai import OpenAI
from pii_gateway import PiiGateway
from pii_gateway.openai import wrap_openai
gateway = PiiGateway("https://api.obvelo.com", os.environ["OBVELO_KEY"])
client = wrap_openai(OpenAI(), gateway) # OpenAI key: yours, called directly
client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user",
"content": "Summarise the claim by Anna Kowalska."}],
)
import OpenAI from "openai";
import { PiiGateway, wrapOpenAI } from "@pii-gateway/sdk";
const gateway = new PiiGateway({
baseUrl: "https://api.obvelo.com",
apiKey: process.env.OBVELO_KEY,
});
const client = wrapOpenAI(new OpenAI(), gateway); // your OpenAI key, called directly
await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user",
content: "Summarise the claim by Anna Kowalska." }],
});
# 1. mask — only the text comes to us
curl https://api.obvelo.com/v1/mask \
-H "x-obvelo-key: $OBVELO_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Summarise the claim by Anna Kowalska." }'
# 2. send the masked text to your model with your own key
# 3. put the values back from the "map" in step 1 — locally
from openai import OpenAI
client = OpenAI(
base_url="https://api.obvelo.com/v1",
api_key=os.environ["OPENAI_API_KEY"],
default_headers={"x-obvelo-key": os.environ["OBVELO_KEY"]},
)
client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user",
"content": "Summarise the claim by Anna Kowalska."}],
)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.obvelo.com/v1",
apiKey: process.env.OPENAI_API_KEY,
defaultHeaders: { "x-obvelo-key": process.env.OBVELO_KEY },
});
await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user",
content: "Summarise the claim by Anna Kowalska." }],
});
curl https://api.obvelo.com/v1/chat/completions \
-H "x-obvelo-key: $OBVELO_KEY" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{ "role": "user",
"content": "Summarise the claim by Anna Kowalska." }
]
}'
your model key never reaches us · we see only the text we mask · the values come back in your process
one address changed · your provider key passes through, never stored · OpenAI, Anthropic, Gemini, Mistral
beyond chat
Agents, files and your own data — covered
agents
Tool calls, protected both ways
Arguments leave masked and are put back before they reach your systems. The MCP bridge applies your tool allowlist before any call goes out.
attachments
Files reported by default, masked on request
Every file in a request is named in the answer — never passed on silently. Switch file masking on in your account panel and docx, xlsx, pptx, csv and txt come back masked and still open, including authors, comments, chart labels and hidden metadata. See it on real files.
your lists
Names from your own records, recognised
Send up to 20 000 people, companies or words never to mask with a request — exported from whatever you run: a CRM, a helpdesk, an HR system, a spreadsheet. Used for that request, stored nowhere.
profiles
A rule profile for every system
Each key carries its own jurisdictions and selection of rules — support bot and legal team, each set up right.
any system
If it sends text to a model, it can go through OBVELO
A CRM, a helpdesk, an ERP, an HR system, a contract repository, an internal tool, an agent. What decides is not what the system is, but where it can be connected.
base URL
It lets you set the model's address
Point it at the gateway and add one header. No code, no new library — streaming and tool calls included.
SDK
It is your own code
TypeScript, Python or .NET — including .NET Framework add-ins. Wrap the model client you already use; your provider key never reaches us.
HTTP
It calls no model at all
An export, a ticket sync, a warehouse load: one request masks any text or JSON, with ids and cursors left intact.
MCP
It is an assistant or an agent
A connector gives any MCP client tools that mask and restore; the tool gateway masks what your own systems hand back to an agent.
browser add-on
And for the people who paste into a chat window
The gateway protects what your systems send. The browser add-on protects what a person types into Claude, ChatGPT, Gemini, Copilot, Perplexity, Mistral and five more chat sites built in — or any other you add: it shows what it found while they type, masks the prompt on the first press of Enter or the send arrow, and puts the real names back into the answer on their screen. Masking still happens on the gateway — the add-on holds no rules of its own.
included in every paid plan — enterprise, starter, standard, pro — at no extra price and with no seat count; it uses the plan's characters like any other caller

for your sector
The documents your sector writes
healthcare
The discharge letter reaches the model. The patient does not.
Patients, clinicians and their identifiers in discharge letters, referrals and lab reports. See the documents.
public administration
The decision reaches the model. The citizen does not.
Decisions, summonses, court and land-register letters in the language of the country. See the letters.
file masking
Word, Excel, PowerPoint, CSV — masked and still open
Authors, comments, chart labels and hidden metadata included. See it on real files.
measured on documents we did not write
16 324 documents and 8 839 scanned pages, checked by the product.
16 324
documents from six public corpora — clinical, legal, finance, 29 business domains
8 839
scanned pages read through OCR from 4 985 documents, 8 scan qualities
5 072
identifier forms in 52 jurisdictions, none left in clear
1 725
sentences an office writes about a person, none left in clear
documents annotated by others — MEDDOCAN, MultiGraSCCo, MAPA, TAB, Nemotron-PII, Gretel — held-out test split, never used for tuning · documents: rule layer · scans: rule layer, on Nemotron-PII documents no one had read, never used for tuning · identifier corpora checked on every engine change: a single value left in clear fails the build
integration
Works with the API you already call
OpenAI chat and responses, Anthropic messages, Gemini contents — Mistral and compatibility gateways speak the chat shape. SDKs for TypeScript, Python and .NET restore the answer on your side, streaming included.
Enterprise
tailored to your organisation
Volume, rule profiles and paperwork, agreed in writing. The same engine as every plan — the contract changes the scale, never the protection.
Self-hosting
Run the whole gateway inside your own perimeter.
Your provider, your credentials
Choose your own model provider and keep billing on your contract. Switch vendors without touching OBVELO.
A profile per system
Unlimited keys, each with its own jurisdictions and rules.
EU and EEA only
Every sub-processor is in the EU or EEA and is entered in our register of processing activities before it is used.
what is agreed
Change one field. Keep the people.
Try it free, or tell us what you need — pricing, running it in your own infrastructure, a pilot on your documents.