How to Redact PII from OpenAI API Calls
Stop sending names, emails, and secrets to OpenAI. Learn how to redact PII from every OpenAI API call using a proxy-level security layer — no code changes required.
The problem: PII leaking through OpenAI API calls
Every chat.completions.create call sends your prompt to OpenAI's servers. If that prompt contains user-submitted text — support tickets, form inputs, CRM data, medical records — there's a good chance it includes names, emails, phone numbers, and other personally identifiable information.
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{
role: "user",
content: `Summarize this support ticket:
From: Sarah Chen <sarah.chen@acme.com>
Phone: (415) 555-0142
Account: 4532-8891-2201-6644
SSN: 521-44-8832
My order #38291 hasn't arrived. I live at
742 Evergreen Terrace, Springfield, IL 62704.
Please help — my API key is sk-abc123secret.`,
},
],
});
That single request just sent a name, email, phone number, credit card number, SSN, home address, and an API key to an external service. Under GDPR, CCPA, and HIPAA, that's a compliance incident.
What PII looks like in OpenAI payloads
OpenAI's API accepts freeform text in the messages array. Any field your users can type into is a vector for PII leakage:
- Names and emails in support contexts
- Phone numbers and addresses from CRM data
- Credit card numbers from payment-related prompts
- SSNs and tax IDs in financial or HR workflows
- API keys and tokens accidentally pasted by developers
- Source code with hardcoded credentials
The Authorization: Bearer sk-... header itself is safe — it's your OpenAI key and it's needed. The problem is what's inside the request body.
The solution: proxy-level redaction with Grepture
Grepture is an open-source security proxy that sits between your application and OpenAI. Every request is scanned for PII, secrets, and sensitive patterns before it leaves your infrastructure. Sensitive data is masked with reversible tokens — and restored in the response so your application works normally.
Your code doesn't change. Your prompts stay useful. The model never sees real PII.
Setup in 3 minutes
1. Install the SDK
npm install @grepture/sdk
2. Get your API key
Sign up at grepture.com/en/pricing — the free plan includes 1,000 requests/month. Copy your API key from the dashboard.
3. Wrap your OpenAI client
import OpenAI from "openai";
import { Grepture } from "@grepture/sdk";
const grepture = new Grepture({
apiKey: process.env.GREPTURE_API_KEY!,
proxyUrl: "https://proxy.grepture.com",
});
const openai = new OpenAI({
...grepture.clientOptions({
apiKey: process.env.OPENAI_API_KEY!,
baseURL: "https://api.openai.com/v1",
}),
});
// Every request is now scanned and protected
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: userInput }],
});
That's it. clientOptions() returns a configuration object that reroutes traffic through the Grepture proxy. Your OpenAI key is forwarded securely via the X-Grepture-Auth-Forward header — OpenAI still authenticates your requests normally.
What gets detected
Grepture ships with 50+ detection patterns on the free tier and 80+ on Pro, covering:
| Category | Examples | Tier |
|---|---|---|
| Personal identifiers | Names, emails, phone numbers, SSNs, dates of birth | Free (regex), Pro (AI) |
| Financial data | Credit card numbers, IBANs, routing numbers | Free |
| Credentials | API keys, bearer tokens, passwords, connection strings | Free |
| Network identifiers | IP addresses, MAC addresses | Free |
| Freeform PII | Names, organizations, and addresses in unstructured text | Pro (local AI models) |
| Adversarial inputs | Prompt injection attempts | Business |
All detection runs on Grepture infrastructure — no data is forwarded to additional third parties.
Mask and restore: reversible redaction
Grepture doesn't just strip PII — it can replace sensitive values with tokens, send the sanitized prompt to OpenAI, and then restore the original values in the response.
What OpenAI sees:
Summarize this support ticket:
From: [PERSON_1] <[EMAIL_1]>
Phone: [PHONE_1]
Account: [CREDIT_CARD_1]
...
What your app gets back:
The customer Sarah Chen (sarah.chen@acme.com) is
asking about order #38291 which hasn't been delivered
to 742 Evergreen Terrace, Springfield, IL 62704.
The model processes clean data. Your application receives the full, personalized response. No PII ever reaches OpenAI.
Streaming support
Grepture handles OpenAI's Server-Sent Events natively. When you use stream: true, the proxy detokenizes chunks in real time — no buffering the entire response, no latency hit.
const stream = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: userInput }],
stream: true,
});
for await (const chunk of stream) {
// Tokens are restored in real time
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
Next steps
- View pricing — free for up to 1,000 requests/month
- Read the docs — SDK reference, configuration, and dashboard guide
- See how it works — architecture, detection rules, and zero-data mode