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
On your side
AI chat in the browserWhat the model sees
AI chat in the browser- You sendOn your sideWrite 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.
- Masked on the way outWhat the model seesWrite a short reply to our customer. Her name is [PERSON_01], email [EMAIL_02], phone [PHONE_03]. The refund goes to [IBAN_04].
- The model answers with tagsWhat the model seesHi [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.
- Originals put backOn your sideHi [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.
On your side
Your code calls the gatewayWhat the model sees
Your code calls the gateway- You sendOn your sidePOST /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." }
- Masked on the way outWhat the model seesPOST /v1/chat/completions{ "ticket": 48213, "customer": { "name": "[PERSON_01]", "email": "[EMAIL_02]", "phone": "[PHONE_03]" }, "message": "Charged twice on [CREDIT_CARD_04]." }
- The model answers with tagsWhat the model seesHTTP 200Summary for [PERSON_01]: a duplicate charge on [CREDIT_CARD_04]. Refund confirmation goes to [EMAIL_02].
- Originals put backOn your sideHTTP 200Summary 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.
On your side
Coding tool in the terminalWhat the model sees
Coding tool in the terminal- You sendOn your sideWhy does this fail? psycopg2.connect('postgresql://svc_reports:Tr0ub4dor&3xK@db.example.com/reports')
- Masked on the way outWhat the model seesWhy does this fail? psycopg2.connect('postgresql://svc_reports:[PASSWORD_01]@db.example.com/reports')
- The model answers with tagsWhat the model seesThe connection string looks well formed. Check that [PASSWORD_01] is still valid and that the host is reachable from your network.
- Originals put backOn your sideThe 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.
On your side
Email assistantWhat the model sees
Email assistant- You sendOn your sideFrom: 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.
- Masked on the way outWhat the model seesFrom: [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].
- 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].
- 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.
On your side
Clinic notes assistantWhat the model sees
Clinic notes assistant- You sendOn your sidePatient: Sarah Klein, national ID 123456782, phone 054-765-4321, lives on Ben Yehuda Street in Jerusalem. Follow-up requested with Dr. Amir Peretz.
- Masked on the way outWhat the model seesPatient: [PERSON_01], national ID [IL_ID_02], phone [PHONE_03], lives on [LOCATION_04] in [LOCATION_05]. Follow-up requested with Dr. [PERSON_06].
- The model answers with tagsWhat the model seesSummary: [PERSON_01] needs a follow-up with [PERSON_06]. Contact the patient on [PHONE_03]; the record is filed under [IL_ID_02].
- Originals put backOn your sideSummary: [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.
On your side
HR assistantWhat the model sees
HR assistant- You sendOn your sidePerformance 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.
- Masked on the way outWhat the model seesPerformance review for [PERSON_01] ([EMAIL_02]). His manager is [PERSON_03] at [ORGANIZATION_04]. Salary is paid to IBAN [IBAN_05].
- The model answers with tagsWhat the model seesDraft: [PERSON_01] met the goals set with [PERSON_03]. Payroll details on file: [IBAN_05]. A copy goes to [EMAIL_02].
- Originals put backOn your sideDraft: [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.
On your side
Contract assistantWhat the model sees
Contract assistant- You sendOn your sideSummarise this agreement. The client is Emily Carter, social security number 536-90-4399, email emily.carter@example.com, represented by Harbor Legal LLP.
- Masked on the way outWhat the model seesSummarise this agreement. The client is [PERSON_01], social security number [US_SSN_02], email [EMAIL_03], represented by [ORGANIZATION_04].
- The model answers with tagsWhat the model seesSummary: an agreement for [PERSON_01], identified by [US_SSN_02], with notices to [EMAIL_03].
- Originals put backOn your sideSummary: 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.
On your side
AI chat in the browserWhat the model sees
AI chat in the browser- You sendOn your sideDraft a delivery notice for Oliver Grant, Baker Street in London, phone +44 20 7946 0958. He paid with card 5555 5555 5555 4444.
- Masked on the way outWhat the model seesDraft a delivery notice for [PERSON_01], [LOCATION_02] in [LOCATION_03], phone [PHONE_04]. He paid with card [CREDIT_CARD_05].
- The model answers with tagsWhat the model seesDear [PERSON_01], your parcel is on its way. We will call [PHONE_04] on arrival. Payment was taken from card [CREDIT_CARD_05].
- Originals put backOn your sideDear [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.
On your side
Coding tool in the terminalWhat the model sees
Coding tool in the terminal- You sendOn your sideReview this config: AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE and GITHUB_TOKEN=ghp_R2d7Kq9Lm4Xv8Bc1Nz6Yt3Wp5Sj0Hf2Gu9Ea
- Masked on the way outWhat the model seesReview this config: AWS_ACCESS_KEY_ID=[AWS_KEY_01] and [SECRET_KEY_02]
- The model answers with tagsWhat the model seesBoth credentials are hard-coded in the file. Move [AWS_KEY_01] and [SECRET_KEY_02] into a secret store and rotate them.
- Originals put backOn your sideBoth 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.
On your side
Coding tool in the terminalWhat the model sees
Coding tool in the terminal- You sendOn your sideDebug this config file: OPENAI_API_KEY=sk-proj-Ab3dE5gH7jK9mN1pQ3rS5tU7vW9xY1zA
- Masked on the way outWhat the model seesDebug this config file: [SECRET_KEY_01]
- The model answers with tagsWhat the model seesDo not commit the line [SECRET_KEY_01]. Load the key from the environment instead, and rotate it if it was ever pushed.
- Originals put backOn your sideDo 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.
On your side
Your code calls the gatewayWhat the model sees
Your code calls the gateway- You sendOn your sidePOST /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."} ] }
- Masked on the way outWhat the model seesPOST /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]."} ] }
- The model answers with tagsWhat the model seesHTTP 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]."}} ] }
- Originals put backOn your sideHTTP 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."}} ] }
On your side
Your code extracts fieldsWhat the model sees
Your code extracts fields- You sendOn your sidePOST /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"} }
- Masked on the way outWhat the model seesPOST /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"} }
- The model answers with tagsWhat the model seesHTTP 200 · choices[0].message.content{ "name": "[PERSON_01]", "email": "[EMAIL_02]", "iban": "[IBAN_03]", "phone": "[PHONE_04]" }
- Originals put backOn your sideHTTP 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" }
On your side
Your code gets a tool callWhat the model sees
Your code gets a tool call- You sendOn your sidePOST /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"}} ] }
- Masked on the way outWhat the model seesPOST /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"}} ] }
- The model answers with tagsWhat the model seesHTTP 200 · choices[0].message.tool_calls[0].function{ "name": "refund", "arguments": { "customer": "[PERSON_01]", "iban": "[IBAN_02]", "amount": 49, "receipt_to": "[EMAIL_03]" } }
- Originals put backOn your sideHTTP 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" } }
On your side
Your code streams the replyWhat the model sees
Your code streams the reply- You sendOn your sidePOST /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."} ] }
- Masked on the way outWhat the model seesPOST /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]."} ] }
- The model answers with tagsWhat the model seesHTTP 200 · text/event-streamdata: {"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]
- Originals put backOn your sideHTTP 200 · text/event-streamDear [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.
On your side
AI chat in the browserWhat the model sees
AI chat in the browser- You sendOn your sideכתבו תשובה קצרה ללקוחה שלנו. קוראים לה נועה שפירא, האימייל noa.shapira@example.com, הטלפון 052-765-4321. ההחזר יועבר ל-IBAN GB82 WEST 1234 5698 7654 32.
- Masked on the way outWhat the model seesכתבו תשובה קצרה ללקוחה שלנו. קוראים לה [PERSON_01], האימייל [EMAIL_02], הטלפון [PHONE_03]. ההחזר יועבר ל-IBAN [IBAN_04].
- The model answers with tagsWhat the model seesשלום [PERSON_01], תודה על הסבלנות. רשמתי את האימייל [EMAIL_02], ההחזר יישלח אל [IBAN_04], ונחזור אליך בטלפון [PHONE_03].
- 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.
On your side
AI chat in the browserWhat the model sees
AI chat in the browser- You sendOn your sideEscribe 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.
- Masked on the way outWhat the model seesEscribe una respuesta breve para nuestra clienta. Se llama [PERSON_01], correo [EMAIL_02], teléfono [PHONE_03]. El reembolso va al IBAN [IBAN_04].
- The model answers with tagsWhat the model seesHola [PERSON_01], gracias por su paciencia. Anoté su correo [EMAIL_02], el reembolso irá a [IBAN_04] y le llamaremos al [PHONE_03].
- Originals put backOn your sideHola [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.
On your side
HR assistantWhat the model sees
HR assistant- You sendOn your sideResume 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.
- Masked on the way outWhat the model seesResume 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].
- The model answers with tagsWhat the model seesResumen: [PERSON_01] cobra en la cuenta [IBAN_04]; su responsable es [PERSON_05]. Contacto: [EMAIL_02] o [PHONE_03].
- Originals put backOn your sideResumen: [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.
On your side
Support assistantWhat the model sees
Support assistant- You sendOn your sideסכמו את הפנייה: הלקוח משה אלון, ת.ז. 123456782, טלפון 054-111-2222, דוא"ל moshe.alon@example.com.
- Masked on the way outWhat the model seesסכמו את הפנייה: הלקוח [PERSON_01], ת.ז. [IL_ID_02], טלפון [PHONE_03], דוא"ל [EMAIL_04].
- The model answers with tagsWhat the model seesסיכום: פנייה של [PERSON_01], מזהה [IL_ID_02], ליצירת קשר [PHONE_03] או [EMAIL_04].
- 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 demoHow 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.
from openai import OpenAI
client = OpenAI(
base_url="https://api.zer0pii.com/v1",
api_key="zpii_...",
default_headers={"X-zer0pii-Upstream-Key": "sk-..."},
)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.
X-zer0pii-Redacted-Count: 3X-zer0pii-Request-ID: req_sample_9f2a1cX-zer0pii-Attestation: t=1758901234;kid=ed25519-a1b2c3d4;raw=sha256:8f14e45f...;sanitized=sha256:2c624232...;status=purged;sig=ed25519:MEUCIQDx9k2FvQ8w3ZbPz
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.