DevOpsil

PII Scrubbing API

PII Scrubbing replaces personally identifiable information — names, emails, phone numbers, SSNs, credit cards, IP addresses — with reversible tokens or redaction markers, in a single API call.

Quick start →View DocsPOST https://devopsil.com/api/v1/pii/scrub

What is it?

PII Scrubbing replaces personally identifiable information — names, emails, phone numbers, SSNs, credit cards, IP addresses — with reversible tokens or redaction markers, in a single API call. It accepts a single JSON payload and returns a structured response in milliseconds — no agents, plugins, or background workers required. The API is designed for synchronous, real-time use: call it inline in your request handler, CI step, or event pipeline and act on the result immediately.

Why do you need it?

Problem

  • PII ends up in application logs constantly — user emails in auth logs, phone numbers in SMS delivery logs, IP addresses in access logs — often without any engineer noticing.
  • Analytics pipelines ingest raw event payloads from the frontend that contain user-entered form data, including names, addresses, and payment details.
  • Support tickets and error reports routed to third-party tools like Zendesk or Sentry contain full PII because engineers copy-paste request bodies into tickets without sanitizing.

Consequence

  • GDPR fines reach 4% of annual global revenue or €20M — whichever is higher. A single audit finding that PII was retained in logs beyond its legal basis can trigger a full investigation.
  • CCPA breach notification requirements apply to any unauthorized access to personal data — a compromised log aggregator counts as a breach even if no production database was touched.
  • Loss of customer trust from a PII exposure is hard to quantify but measurable: enterprise deals stall, SOC 2 audits flag the issue, and churn increases in the 6 months following a disclosed incident.

Solution

  • Automated, deterministic scrubbing at ingestion time — PII is removed before data reaches your log aggregator, analytics platform, or third-party tool.
  • Reversible tokenization lets you restore original values server-side for authorized lookups while everything downstream sees only tokens.
  • Covers 20+ PII categories including GDPR Article 4 personal data, CCPA personal information, and HIPAA protected health information in a single call.

Use cases

Support ticket scrubbing

Scrub PII from support tickets before routing them to a third-party helpdesk like Zendesk or Freshdesk, so your customer data never leaves your security boundary.

Node.js — scrub before helpdesk

const API_KEY = process.env.DEVOPSIL_API_KEY;

const result = await fetch('https://devopsil.com/api/v1/pii/scrub', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    text: ticketBody,
    mode: 'redact', // or 'tokenize' for reversibility
    categories: ['email', 'phone', 'full_name', 'credit_card'],
  }),
}).then(r => r.json());

await createZendeskTicket(result.scrubbed_text);

result.scrubbed_text is safe for third-party storage. result.entities lists what was found and where.

Log pipeline PII removal

Strip PII from log lines before indexing in Elasticsearch or Datadog, keeping your log data useful for debugging while eliminating personal data.

Node.js — log pipeline scrub

const API_KEY = process.env.DEVOPSIL_API_KEY;

async function scrubLogBatch(logLines: string[]) {
  const result = await fetch('https://devopsil.com/api/v1/pii/scrub', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      text: logLines.join('\n'),
      mode: 'redact',
    }),
  }).then(r => r.json());

  return result.scrubbed_text.split('\n');
}

Index result.scrubbed_text lines. Use result.entity_count for a scrub effectiveness metric in your data governance dashboard.

Analytics event scrubbing

Strip PII from analytics event payloads before sending to Mixpanel, Segment, or Amplitude so your analytics vendor never receives personal data.

Node.js — strip PII from event

const API_KEY = process.env.DEVOPSIL_API_KEY;

async function trackEvent(event: Record<string, unknown>) {
  const serialized = JSON.stringify(event);
  const result = await fetch('https://devopsil.com/api/v1/pii/scrub', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ text: serialized, mode: 'redact' }),
  }).then(r => r.json());

  const cleanEvent = JSON.parse(result.scrubbed_text);
  await mixpanel.track(event.name, cleanEvent);
}

Send cleanEvent to your analytics vendor. It contains the same structure but with PII replaced by [REDACTED] markers.

LLM input/output scrubbing

Remove PII before sending user text to an AI API (OpenAI, Anthropic, etc.) and optionally restore tokens in the AI's response if the context requires original values.

Node.js — LLM PII scrub/restore

const API_KEY = process.env.DEVOPSIL_API_KEY;

// Scrub user input before sending to AI
const scrubResult = await fetch('https://devopsil.com/api/v1/pii/scrub', {
  method: 'POST',
  headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ text: userMessage, mode: 'tokenize' }),
}).then(r => r.json());

const aiResponse = await callOpenAI(scrubResult.scrubbed_text);

// Restore tokens in AI response for display to the original user
const restoreResult = await fetch('https://devopsil.com/api/v1/pii/restore', {
  method: 'POST',
  headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ text: aiResponse, token_map: scrubResult.token_map }),
}).then(r => r.json());

Display restoreResult.restored_text to the user. The AI never saw real PII; the user sees a coherent response with their original values.

Database migration prep

Scrub a production data dump before loading it into a staging or development environment, so developers can test with realistic data shapes without real PII.

Node.js — scrub DB dump

const API_KEY = process.env.DEVOPSIL_API_KEY;
const fs = require('fs');

const dump = fs.readFileSync('prod_dump.sql', 'utf8');

// Process in chunks to stay under 1MB limit
for (const chunk of splitIntoChunks(dump, 900_000)) {
  const result = await fetch('https://devopsil.com/api/v1/pii/scrub', {
    method: 'POST',
    headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ text: chunk, mode: 'redact' }),
  }).then(r => r.json());

  fs.appendFileSync('staging_dump.sql', result.scrubbed_text);
}

Load staging_dump.sql into your dev DB. All PII is replaced with consistent redaction markers — email@[REDACTED].com format preserves structure.

Error report scrubbing

Strip PII from exception stack traces and request bodies before sending to Sentry or Bugsnag, so your error tracking tool never ingests personal data.

Node.js — Sentry beforeSend hook

const API_KEY = process.env.DEVOPSIL_API_KEY;

// In your Sentry init config
Sentry.init({
  beforeSend: async (event) => {
    const raw = JSON.stringify(event);
    const result = await fetch('https://devopsil.com/api/v1/pii/scrub', {
      method: 'POST',
      headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
      body: JSON.stringify({ text: raw, mode: 'redact' }),
    }).then(r => r.json());

    return JSON.parse(result.scrubbed_text);
  },
});

Sentry receives a clean event. Error messages and request bodies are scrubbed; the stack trace structure is preserved for debugging.

PII categories detected

CategoryExamplesDefault action
Full name"John Smith", "María García"Redact
Email address[email protected]Redact
Phone number+1-555-123-4567, (555) 123-4567Redact
SSN / NIN123-45-6789, AB 123456 CRedact
Credit card number4111 1111 1111 1111Redact
IP address192.168.1.1, 2001:db8::1Redact
Passport numberA12345678Redact
Date of birth1990-03-15, March 15, 1990Redact
Physical address"123 Main St, Springfield"Redact

How the API works

All requests use Bearer authentication. Your API key starts with pii_. Get one at /dashboard/api-keys.

Request

{
  "text": "Contact Alice Johnson at [email protected] or call +1-415-555-0192. Her SSN is 123-45-6789.",
  "mode": "redact",
  "categories": ["full_name", "email", "phone", "ssn"]
}

Response

{
  "scrub_id": "scr_7pq3mz9a",
  "scrubbed_text": "Contact [NAME] at [EMAIL] or call [PHONE]. Her SSN is [SSN].",
  "entities": [
    { "type": "full_name",     "original": "Alice Johnson",          "position": [8, 21],   "confidence": 0.97 },
    { "type": "email",         "original": "[email protected]", "position": [25, 47],  "confidence": 0.99 },
    { "type": "phone",         "original": "+1-415-555-0192",        "position": [57, 73],  "confidence": 0.98 },
    { "type": "ssn",           "original": "123-45-6789",            "position": [83, 94],  "confidence": 0.99 }
  ],
  "entity_count": 4,
  "mode": "redact",
  "processing_ms": 22
}

Quick start

1

Get your API key

Create a free account and generate a key at /dashboard/api-keys. Your key starts with pii_.

2

Make your first call

Node.js

const API_KEY = process.env.DEVOPSIL_API_KEY; // starts with pii_

const result = await fetch('https://devopsil.com/api/v1/pii/scrub', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    text: 'Call Alice at [email protected] or 555-123-4567.',
    mode: 'redact',
  }),
}).then(r => r.json());

console.log(result.scrubbed_text);
// "Call [NAME] at [EMAIL] or [PHONE]."
3

Act on the result

Node.js — handle response

if (result.entity_count > 0) {
  // Use the scrubbed version for storage / forwarding
  await storeOrForward(result.scrubbed_text);
  console.log(`Scrubbed ${result.entity_count} PII entities in ${result.processing_ms}ms`);
} else {
  // No PII found — safe to use original
  await storeOrForward(originalText);
}

Frequently asked questions

Ready to integrate?

Free tier included. No credit card required.