Skip to content

Personal data stays out of the model.

Let your team use ChatGPT, Claude and Gemini without personal data leaving your control. Verifiable, not promised.

Check it yourself: signed receipts and a public trust page.

Scripted demo

Customer chat 1 / 18Illustration
AI chat in the browser
  1. You sendOn your side
    Write a short reply to our customer. Her name is Dana Levi, email dana.levi@example.com, phone +972-52-123-4567. The refund goes to IBAN GB82 WEST 1234 5698 7654 32.
  2. Masked on the way outWhat the model sees
    Write a short reply to our customer. Her name is [PERSON_01], email [EMAIL_02], phone [PHONE_03]. The refund goes to [IBAN_04].
  3. The model answers with tagsWhat the model sees
    Hi [PERSON_01], thanks for your patience. I have your email as [EMAIL_02], the refund will go to [IBAN_04], and we will call [PHONE_03] if we need anything else.
  4. Originals put backOn your side
    Hi [PERSON_01], thanks for your patience. I have your email as [EMAIL_02], the refund will go to [IBAN_04], and we will call [PHONE_03] if we need anything else.
    Hi Dana Levi, thanks for your patience. I have your email as dana.levi@example.com, the refund will go to IBAN GB82 WEST 1234 5698 7654 32, and we will call +972-52-123-4567 if we need anything else.
Your code calls the gateway
  1. You sendOn your side
    POST /v1/chat/completions
    { "ticket": 48213, "customer": { "name": "Jonathan Whitfield", "email": "jon.whitfield@example.com", "phone": "+1 (415) 555-0132" }, "message": "Charged twice on 4111 1111 1111 1111." }
  2. Masked on the way outWhat the model sees
    POST /v1/chat/completions
    { "ticket": 48213, "customer": { "name": "[PERSON_01]", "email": "[EMAIL_02]", "phone": "[PHONE_03]" }, "message": "Charged twice on [CREDIT_CARD_04]." }
  3. The model answers with tagsWhat the model sees
    HTTP 200
    Summary for [PERSON_01]: a duplicate charge on [CREDIT_CARD_04]. Refund confirmation goes to [EMAIL_02].
  4. Originals put backOn your side
    HTTP 200
    Summary for [PERSON_01]: a duplicate charge on [CREDIT_CARD_04]. Refund confirmation goes to [EMAIL_02].
    Summary for Jonathan Whitfield: a duplicate charge on 4111 1111 1111 1111. Refund confirmation goes to jon.whitfield@example.com.
Coding tool in the terminal
  1. You sendOn your side
    Why does this fail? psycopg2.connect('postgresql://svc_reports:Tr0ub4dor&3xK@db.example.com/reports')
  2. Masked on the way outWhat the model sees
    Why does this fail? psycopg2.connect('postgresql://svc_reports:[PASSWORD_01]@db.example.com/reports')
  3. The model answers with tagsWhat the model sees
    The connection string looks well formed. Check that [PASSWORD_01] is still valid and that the host is reachable from your network.
  4. Originals put backOn your side
    The connection string looks well formed. Check that [PASSWORD_01] is still valid and that the host is reachable from your network.
    The connection string looks well formed. Check that Tr0ub4dor&3xK is still valid and that the host is reachable from your network.
Email assistant
  1. You sendOn your side
    From: Maya Cohen <maya.cohen@example.com> Subject: Onboarding Hi team, please set up Daniel Rossi, Rothschild Boulevard in Tel Aviv. His national ID is 123456782 and his phone is 052-123-4567.
  2. Masked on the way outWhat the model sees
    From: [PERSON_01] <[EMAIL_02]> Subject: Onboarding Hi team, please set up [PERSON_03], [LOCATION_04] in [LOCATION_05]. His national ID is [IL_ID_06] and his phone is [PHONE_07].
  3. The model answers with tagsWhat the model sees
    [PERSON_01] asks the team to set up [PERSON_03]. Contact number [PHONE_07], reply to [EMAIL_02].
  4. Originals put backOn your side
    [PERSON_01] asks the team to set up [PERSON_03]. Contact number [PHONE_07], reply to [EMAIL_02].
    Maya Cohen asks the team to set up Daniel Rossi. Contact number 052-123-4567, reply to maya.cohen@example.com.
Clinic notes assistant
  1. You sendOn your side
    Patient: Sarah Klein, national ID 123456782, phone 054-765-4321, lives on Ben Yehuda Street in Jerusalem. Follow-up requested with Dr. Amir Peretz.
  2. Masked on the way outWhat the model sees
    Patient: [PERSON_01], national ID [IL_ID_02], phone [PHONE_03], lives on [LOCATION_04] in [LOCATION_05]. Follow-up requested with Dr. [PERSON_06].
  3. The model answers with tagsWhat the model sees
    Summary: [PERSON_01] needs a follow-up with [PERSON_06]. Contact the patient on [PHONE_03]; the record is filed under [IL_ID_02].
  4. Originals put backOn your side
    Summary: [PERSON_01] needs a follow-up with [PERSON_06]. Contact the patient on [PHONE_03]; the record is filed under [IL_ID_02].
    Summary: Sarah Klein needs a follow-up with Amir Peretz. Contact the patient on 054-765-4321; the record is filed under 123456782.
HR assistant
  1. You sendOn your side
    Performance review for Tom Becker (tom.becker@example.com). His manager is Lena Fischer at Northwind GmbH. Salary is paid to IBAN DE89 3704 0044 0532 0130 00.
  2. Masked on the way outWhat the model sees
    Performance review for [PERSON_01] ([EMAIL_02]). His manager is [PERSON_03] at [ORGANIZATION_04]. Salary is paid to IBAN [IBAN_05].
  3. The model answers with tagsWhat the model sees
    Draft: [PERSON_01] met the goals set with [PERSON_03]. Payroll details on file: [IBAN_05]. A copy goes to [EMAIL_02].
  4. Originals put backOn your side
    Draft: [PERSON_01] met the goals set with [PERSON_03]. Payroll details on file: [IBAN_05]. A copy goes to [EMAIL_02].
    Draft: Tom Becker met the goals set with Lena Fischer. Payroll details on file: DE89 3704 0044 0532 0130 00. A copy goes to tom.becker@example.com.
Contract assistant
  1. You sendOn your side
    Summarise this agreement. The client is Emily Carter, social security number 536-90-4399, email emily.carter@example.com, represented by Harbor Legal LLP.
  2. Masked on the way outWhat the model sees
    Summarise this agreement. The client is [PERSON_01], social security number [US_SSN_02], email [EMAIL_03], represented by [ORGANIZATION_04].
  3. The model answers with tagsWhat the model sees
    Summary: an agreement for [PERSON_01], identified by [US_SSN_02], with notices to [EMAIL_03].
  4. Originals put backOn your side
    Summary: an agreement for [PERSON_01], identified by [US_SSN_02], with notices to [EMAIL_03].
    Summary: an agreement for Emily Carter, identified by 536-90-4399, with notices to emily.carter@example.com.
AI chat in the browser
  1. You sendOn your side
    Draft a delivery notice for Oliver Grant, Baker Street in London, phone +44 20 7946 0958. He paid with card 5555 5555 5555 4444.
  2. Masked on the way outWhat the model sees
    Draft a delivery notice for [PERSON_01], [LOCATION_02] in [LOCATION_03], phone [PHONE_04]. He paid with card [CREDIT_CARD_05].
  3. The model answers with tagsWhat the model sees
    Dear [PERSON_01], your parcel is on its way. We will call [PHONE_04] on arrival. Payment was taken from card [CREDIT_CARD_05].
  4. Originals put backOn your side
    Dear [PERSON_01], your parcel is on its way. We will call [PHONE_04] on arrival. Payment was taken from card [CREDIT_CARD_05].
    Dear Oliver Grant, your parcel is on its way. We will call +44 20 7946 0958 on arrival. Payment was taken from card 5555 5555 5555 4444.
Coding tool in the terminal
  1. You sendOn your side
    Review this config: AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE and GITHUB_TOKEN=ghp_R2d7Kq9Lm4Xv8Bc1Nz6Yt3Wp5Sj0Hf2Gu9Ea
  2. Masked on the way outWhat the model sees
    Review this config: AWS_ACCESS_KEY_ID=[AWS_KEY_01] and [SECRET_KEY_02]
  3. The model answers with tagsWhat the model sees
    Both credentials are hard-coded in the file. Move [AWS_KEY_01] and [SECRET_KEY_02] into a secret store and rotate them.
  4. Originals put backOn your side
    Both credentials are hard-coded in the file. Move [AWS_KEY_01] and [SECRET_KEY_02] into a secret store and rotate them.
    Both credentials are hard-coded in the file. Move AKIAIOSFODNN7EXAMPLE and GITHUB_TOKEN=ghp_R2d7Kq9Lm4Xv8Bc1Nz6Yt3Wp5Sj0Hf2Gu9Ea into a secret store and rotate them.
Coding tool in the terminal
  1. You sendOn your side
    Debug this config file: OPENAI_API_KEY=sk-proj-Ab3dE5gH7jK9mN1pQ3rS5tU7vW9xY1zA
  2. Masked on the way outWhat the model sees
    Debug this config file: [SECRET_KEY_01]
  3. The model answers with tagsWhat the model sees
    Do not commit the line [SECRET_KEY_01]. Load the key from the environment instead, and rotate it if it was ever pushed.
  4. Originals put backOn your side
    Do not commit the line [SECRET_KEY_01]. Load the key from the environment instead, and rotate it if it was ever pushed.
    Do not commit the line OPENAI_API_KEY=sk-proj-Ab3dE5gH7jK9mN1pQ3rS5tU7vW9xY1zA. Load the key from the environment instead, and rotate it if it was ever pushed.
Your code calls the gateway
  1. You sendOn your side
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": "Draft a two-line reply to our customer. Her name is Priya Nair, email priya.nair@example.com. Her refund goes to account GB82 WEST 1234 5698 7654 32."} ] }
  2. Masked on the way outWhat the model sees
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": "Draft a two-line reply to our customer. Her name is [PERSON_01], email [EMAIL_02]. Her refund goes to account [IBAN_03]."} ] }
  3. The model answers with tagsWhat the model sees
    HTTP 200
    { "choices": [ {"message": {"role": "assistant", "content": "Hi [PERSON_01], your refund is on its way to [IBAN_03]. A confirmation will follow at [EMAIL_02]."}} ] }
  4. Originals put backOn your side
    HTTP 200
    { "choices": [ {"message": {"role": "assistant", "content": "Hi [PERSON_01], your refund is on its way to [IBAN_03]. A confirmation will follow at [EMAIL_02]."}} ] }
    { "choices": [ {"message": {"role": "assistant", "content": "Hi Priya Nair, your refund is on its way to GB82 WEST 1234 5698 7654 32. A confirmation will follow at priya.nair@example.com."}} ] }
Your code extracts fields
  1. You sendOn your side
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "messages": [ {"role": "system", "content": "Return name, email, iban and phone as JSON."}, {"role": "user", "content": "Order note: Tom Becker, tom.becker@example.com, account DE89 3704 0044 0532 0130 00, phone +44 20 7946 0958."} ], "response_format": {"type": "json_object"} }
  2. Masked on the way outWhat the model sees
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "messages": [ {"role": "system", "content": "Return name, email, iban and phone as JSON."}, {"role": "user", "content": "Order note: [PERSON_01], [EMAIL_02], account [IBAN_03], phone [PHONE_04]."} ], "response_format": {"type": "json_object"} }
  3. The model answers with tagsWhat the model sees
    HTTP 200 · choices[0].message.content
    { "name": "[PERSON_01]", "email": "[EMAIL_02]", "iban": "[IBAN_03]", "phone": "[PHONE_04]" }
  4. Originals put backOn your side
    HTTP 200 · choices[0].message.content
    { "name": "[PERSON_01]", "email": "[EMAIL_02]", "iban": "[IBAN_03]", "phone": "[PHONE_04]" }
    { "name": "Tom Becker", "email": "tom.becker@example.com", "iban": "DE89 3704 0044 0532 0130 00", "phone": "+44 20 7946 0958" }
Your code gets a tool call
  1. You sendOn your side
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": "Refund 49 EUR to Marcus Webb, IBAN NL91 ABNA 0417 1643 00, and email the receipt to marcus.webb@example.com."} ], "tools": [ {"type": "function", "function": {"name": "refund"}} ] }
  2. Masked on the way outWhat the model sees
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "messages": [ {"role": "user", "content": "Refund 49 EUR to [PERSON_01], IBAN [IBAN_02], and email the receipt to [EMAIL_03]."} ], "tools": [ {"type": "function", "function": {"name": "refund"}} ] }
  3. The model answers with tagsWhat the model sees
    HTTP 200 · choices[0].message.tool_calls[0].function
    { "name": "refund", "arguments": { "customer": "[PERSON_01]", "iban": "[IBAN_02]", "amount": 49, "receipt_to": "[EMAIL_03]" } }
  4. Originals put backOn your side
    HTTP 200 · choices[0].message.tool_calls[0].function
    { "name": "refund", "arguments": { "customer": "[PERSON_01]", "iban": "[IBAN_02]", "amount": 49, "receipt_to": "[EMAIL_03]" } }
    { "name": "refund", "arguments": { "customer": "Marcus Webb", "iban": "NL91 ABNA 0417 1643 00", "amount": 49, "receipt_to": "marcus.webb@example.com" } }
Your code streams the reply
  1. You sendOn your side
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "stream": true, "messages": [ {"role": "user", "content": "Write a short delivery notice for Hannah Weiss. Her phone is +1 (646) 555-0199 and her email is hannah.weiss@example.com."} ] }
  2. Masked on the way outWhat the model sees
    POST /v1/chat/completions
    { "model": "gpt-4o-mini", "stream": true, "messages": [ {"role": "user", "content": "Write a short delivery notice for [PERSON_01]. Her phone is [PHONE_02] and her email is [EMAIL_03]."} ] }
  3. The model answers with tagsWhat the model sees
    HTTP 200 · text/event-stream
    data: {"choices":[{"delta":{"content":"Dear "}}]}
    data: {"choices":[{"delta":{"content":"[PERSON_01]"}}]}
    data: {"choices":[{"delta":{"content":", we email "}}]}
    data: {"choices":[{"delta":{"content":"[EMAIL_03]"}}]}
    data: {"choices":[{"delta":{"content":" and call "}}]}
    data: {"choices":[{"delta":{"content":"[PHONE_02]"}}]}
    data: {"choices":[{"delta":{"content":" on arrival."}}]}
    data: [DONE]
  4. Originals put backOn your side
    HTTP 200 · text/event-stream
    Dear [PERSON_01], we email [EMAIL_03] and call [PHONE_02] on arrival.
    Dear Hannah Weiss, we email hannah.weiss@example.com and call +1 (646) 555-0199 on arrival.
AI chat in the browser
  1. You sendOn your side
    כתבו תשובה קצרה ללקוחה שלנו. קוראים לה נועה שפירא, האימייל noa.shapira@example.com, הטלפון 052-765-4321. ההחזר יועבר ל-IBAN GB82 WEST 1234 5698 7654 32.
  2. Masked on the way outWhat the model sees
    כתבו תשובה קצרה ללקוחה שלנו. קוראים לה [PERSON_01], האימייל [EMAIL_02], הטלפון [PHONE_03]. ההחזר יועבר ל-IBAN [IBAN_04].
  3. The model answers with tagsWhat the model sees
    שלום [PERSON_01], תודה על הסבלנות. רשמתי את האימייל [EMAIL_02], ההחזר יישלח אל [IBAN_04], ונחזור אליך בטלפון [PHONE_03].
  4. Originals put backOn your side
    שלום [PERSON_01], תודה על הסבלנות. רשמתי את האימייל [EMAIL_02], ההחזר יישלח אל [IBAN_04], ונחזור אליך בטלפון [PHONE_03].
    שלום נועה שפירא, תודה על הסבלנות. רשמתי את האימייל noa.shapira@example.com, ההחזר יישלח אל GB82 WEST 1234 5698 7654 32, ונחזור אליך בטלפון 052-765-4321.
AI chat in the browser
  1. You sendOn your side
    Escribe una respuesta breve para nuestra clienta. Se llama Lucía Fernández, correo lucia.fernandez@example.com, teléfono +34 612 345 678. El reembolso va al IBAN ES91 2100 0418 4502 0005 1332.
  2. Masked on the way outWhat the model sees
    Escribe una respuesta breve para nuestra clienta. Se llama [PERSON_01], correo [EMAIL_02], teléfono [PHONE_03]. El reembolso va al IBAN [IBAN_04].
  3. The model answers with tagsWhat the model sees
    Hola [PERSON_01], gracias por su paciencia. Anoté su correo [EMAIL_02], el reembolso irá a [IBAN_04] y le llamaremos al [PHONE_03].
  4. Originals put backOn your side
    Hola [PERSON_01], gracias por su paciencia. Anoté su correo [EMAIL_02], el reembolso irá a [IBAN_04] y le llamaremos al [PHONE_03].
    Hola Lucía Fernández, gracias por su paciencia. Anoté su correo lucia.fernandez@example.com, el reembolso irá a ES91 2100 0418 4502 0005 1332 y le llamaremos al +34 612 345 678.
HR assistant
  1. You sendOn your side
    Resume esta nota de recursos humanos: la empleada Marta Gil (marta.gil@example.com), teléfono +34 611 222 333, cobra en la cuenta ES91 2100 0418 4502 0005 1332. Su responsable es Pablo Navarro.
  2. Masked on the way outWhat the model sees
    Resume esta nota de recursos humanos: la empleada [PERSON_01] ([EMAIL_02]), teléfono [PHONE_03], cobra en la cuenta [IBAN_04]. Su responsable es [PERSON_05].
  3. The model answers with tagsWhat the model sees
    Resumen: [PERSON_01] cobra en la cuenta [IBAN_04]; su responsable es [PERSON_05]. Contacto: [EMAIL_02] o [PHONE_03].
  4. Originals put backOn your side
    Resumen: [PERSON_01] cobra en la cuenta [IBAN_04]; su responsable es [PERSON_05]. Contacto: [EMAIL_02] o [PHONE_03].
    Resumen: Marta Gil cobra en la cuenta ES91 2100 0418 4502 0005 1332; su responsable es Pablo Navarro. Contacto: marta.gil@example.com o +34 611 222 333.
Support assistant
  1. You sendOn your side
    סכמו את הפנייה: הלקוח משה אלון, ת.ז. 123456782, טלפון 054-111-2222, דוא"ל moshe.alon@example.com.
  2. Masked on the way outWhat the model sees
    סכמו את הפנייה: הלקוח [PERSON_01], ת.ז. [IL_ID_02], טלפון [PHONE_03], דוא"ל [EMAIL_04].
  3. The model answers with tagsWhat the model sees
    סיכום: פנייה של [PERSON_01], מזהה [IL_ID_02], ליצירת קשר [PHONE_03] או [EMAIL_04].
  4. Originals put backOn your side
    סיכום: פנייה של [PERSON_01], מזהה [IL_ID_02], ליצירת קשר [PHONE_03] או [EMAIL_04].
    סיכום: פנייה של משה אלון, מזהה 123456782, ליצירת קשר 054-111-2222 או moshe.alon@example.com.

A scripted illustration: each sample was run once through the real detection, and nothing here processes what you type. Detection is not complete; check it on your own data.

Try your own text in the demo

How it works

Three steps on every request, in the gateway or in the browser extension. No code path writes your text to disk or keeps a copy of it on our side. In the extension, the last masked message is held in that tab's memory only, so you can look at it, and it is cleared when you send again or leave the page.

Mask

Emails, phone numbers, national IDs, cards, IBANs, credentials, names, organisations and places are replaced with placeholder tags before the request leaves.

Model

The masked request goes to the provider you chose, with your own provider key. The provider sees tags in place of the values.

Restore

The reply comes back through the gateway and the tags are swapped for the originals.

Built for the teams that handle other people's data

HR

Candidate CVs, employee questions and reviews drafted with an assistant, with names, ID numbers, emails and account numbers replaced by tags before anything leaves.

Finance

Invoices, bank details and card numbers in reconciliation prompts are masked before the model reads them.

Legal

Contracts and correspondence summarised with client names, ID numbers and emails replaced by tags.

Customer support

Tickets, chat transcripts and call notes summarised or answered with an assistant, with customer names, phone numbers, emails and card numbers replaced by tags before anything leaves.

Engineering

Logs, config files and stack traces pasted into a coding assistant, with emails, API keys and passwords replaced by tags. The code itself is left as it is.

Healthcare

Visit notes and referral letters summarised with an assistant, with patient names, ID numbers, phone numbers and emails replaced by tags.

For developers

Keep your SDK. Change one line: the base URL. Your provider key travels in a header or is held by the gateway; your code receives the restored values, not placeholders.

Python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.zer0pii.com/v1",
    api_key="zpii_...",
    default_headers={"X-zer0pii-Upstream-Key": "sk-..."},
)
Node
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.zer0pii.com/v1",
  apiKey: "zpii_...",
  defaultHeaders: { "X-zer0pii-Upstream-Key": "sk-..." },
});

Evidence you can check

Three things you can inspect yourself, taken from the gateway and its documentation.

Every response carries this header, signed with the gateway's Ed25519 key over the hashes of the raw and the masked request. Verify it yourself against the published public key.

Sample values below, not a real request. Shape and field names are exact.
X-zer0pii-Redacted-Count: 3
X-zer0pii-Request-ID: req_sample_9f2a1c
X-zer0pii-Attestation: t=1758901234;kid=ed25519-a1b2c3d4;raw=sha256:8f14e45f...;sanitized=sha256:2c624232...;status=purged;sig=ed25519:MEUCIQDx9k2FvQ8w3ZbPz
Read the verify guide

Accuracy, stated plainly

Detection is not complete. Check it on your own data before you rely on it. How accurate it is, measured in detail, is in the security-review document that customers receive.

Zero-data-retention scope

“Cryptographic receipt: the X-zer0pii-Attestation header is Ed25519-signed over the input and output hashes, independently verifiable against the JWKS. The receipt attests to the hashes and to the overwrite of the buffers the application controls.”

From our zero-data-retention scope document, section 1, item 4.

Start with the free plan

Bring your own provider keys, invite the whole team, and watch the audit log fill with counts of what was masked. It holds no text at all.

Check it yourself: signed receipts and a public trust page.