Data Loss Prevention

PII Detection for Data Loss Prevention

Legacy DLP rules drown security teams in false positives and still miss real leaks. Learn how to build content-aware DLP by wiring AI-powered PII detection into egress scanning, endpoint and network controls, and your policy engine — with practical alert-vs-block strategies and working code.

Explore the Guide

Why Detection Quality Decides Whether DLP Works

Every data loss prevention program stands or falls on one question: can the system correctly recognize sensitive content at the moment it moves? Encryption, access control, and egress gateways are all downstream of that decision. If the classifier flags an invoice number as a Social Security number, an analyst wastes twenty minutes triaging noise. If it misses a customer list pasted into a webmail draft, the control that was supposed to stop the breach never fires at all. In mature security operations, the DLP detection layer is reviewed and tuned more often than any other control precisely because both failure modes are expensive.

Traditional DLP products lean heavily on regular expressions, keyword dictionaries, and document fingerprinting. Those techniques catch well-formatted credit card numbers and exact copies of known files, but they collapse when data appears in natural language: a support agent typing "her social is 545 12 8934, born March 3rd 1987" into a chat window, a developer pasting a customer record into a bug tracker, or an exported CSV where names sit in a free-text notes column. Real leakage overwhelmingly looks like this — conversational, partially formatted, and context-dependent.

Modern PII detection replaces pattern matching with transformer-based named entity recognition that reads context the way a human reviewer would. The PII Detection API identifies 150+ entity types — names, national IDs, payment card data, health identifiers, credentials and secrets — across 60+ languages, and returns each finding with a type, the exact matched text, character offsets, and a confidence score. Those structured results are exactly what a DLP policy engine needs: instead of a binary "pattern matched" signal, your policies can reason about which entities appeared, how many, at what confidence, and in what combination.

This guide walks through the three dominant DLP architectures, shows where an API-based detection service fits into each, and then builds a working policy engine with alert and block actions using real code against the API. If you are evaluating detection engines first, the companion guide on what PII detection is and how it works covers the fundamentals, and NER vs regex detection techniques compares approaches in depth.

The Three DLP Architectures — and Where Detection Lives

DLP deployments differ mainly in where content is intercepted. Each interception point has different visibility, latency budgets, and enforcement powers — but all of them need the same thing at the core: an accurate content classifier.

Endpoint DLP

An agent on laptops and workstations watches file operations, clipboard activity, USB transfers, printing, and uploads. Endpoint DLP sees data before encryption and catches offline channels like removable media, but agents have tight CPU budgets, so they typically run lightweight local rules and defer ambiguous content to a cloud detection API for a verdict.

Network DLP

Proxies, secure web gateways, ICAP servers, and email gateways inspect traffic in transit — HTTP uploads, SMTP messages, file-sharing sync. Network DLP covers unmanaged devices and gives a single choke point for enforcement, but it must terminate TLS to inspect payloads and has a hard latency budget: a verdict is needed in hundreds of milliseconds, which favors a fast synchronous detection API call.

API-Based / Cloud DLP

Instead of intercepting packets, you call a detection API from the applications and platforms where data already flows: SaaS webhooks, CASB integrations, storage-bucket scans, CI pipelines, chat platforms. This is the fastest architecture to deploy — no agents, no TLS interception — and the only one that works cleanly inside your own products, where you control the code path and can scan at the exact moment data is created or shared.

Hybrid Reality

Most real programs combine all three: endpoint agents for device channels, a network gateway for email and web egress, and API-based scanning for SaaS and internal applications. The unifying layer is a shared detection service and a shared policy engine, so that a credit card number is classified identically whether it appears in an email attachment, a Slack message, or an S3 object.

Endpoint vs Network vs API-Based DLP

The right mix depends on which channels carry your riskiest data and how much operational overhead you can absorb. The table below summarizes the trade-offs security architects weigh most often.

Dimension Endpoint DLP Network DLP API-Based DLP
Interception point Agent on the device (files, clipboard, USB, print) Gateway/proxy in the traffic path (SMTP, HTTP, ICAP) Application code, webhooks, SaaS APIs, storage scans
Visibility Pre-encryption, offline channels, local files All egress from the network, unmanaged apps Exact data at creation/share time, full app context
Blind spots Unmanaged/BYOD devices, servers without agents Certificate-pinned apps, remote workers off-VPN Channels with no integration hook
Enforcement Block copy/upload/print at the OS level Drop, quarantine, or rewrite in transit Reject, mask, or queue for review in-app
Latency budget Milliseconds locally; async for deep scans Strict: 100–500 ms per verdict Flexible: inline (~200 ms) or asynchronous batch
Deployment effort High: agent rollout, OS compatibility, updates High: TLS interception, PKI, network changes Low: an HTTPS call from existing code
Detection quality driver Limited local rules; API escalation for accuracy Gateway engine or external detection API Full ML detection on every scanned payload
Rule of thumb: start API-based where you control the code (your product, your SaaS webhooks, your data stores) because it ships in days, then extend to network email/web egress, and reserve endpoint agents for regulated teams handling the most sensitive data. Every layer should call the same detection service so verdicts — and audit evidence — stay consistent.

Egress Scanning: Catching Data at the Moment It Leaves

Egress scanning is the discipline of inspecting content at every point where it crosses a trust boundary: outbound email, HTTP uploads to external domains, file-sharing links, API responses served to third parties, support replies, and exports downloaded by users. The defining property of egress events is that they are irreversible — once the message is delivered or the file is downloaded, no retention policy or access revocation brings it back. That is why egress is where detection accuracy matters most and where most organizations concentrate their blocking rules.

A practical egress scanning pipeline has four stages. First, interception: the gateway, milter, proxy, or application middleware obtains the outbound payload before delivery. Second, normalization: attachments are unpacked, documents converted to text, encodings unified — the detector should always receive plain text (for file formats see the guide to document and PDF PII scanning). Third, detection: the text is sent to the API, which returns typed entities with offsets and confidence scores. Fourth, disposition: the policy engine maps the findings to an action — deliver, deliver-with-masking, hold for review, or block — and writes an audit record either way.

Two design decisions dominate egress performance. Chunking: the API accepts up to 50,000 characters per request, so large payloads should be split on paragraph boundaries and scanned in parallel, then the offsets recombined. Scoping: you rarely need all 150+ entity types on every channel. An engineering file-share might scan only for credentials (API_KEY, AWS_CREDENTIALS, PRIVATE_KEY), while outbound customer email scans for identity and payment entities. Narrower entity lists mean faster responses and fewer irrelevant hits.

Finally, treat internal-to-external boundaries inside SaaS tools as egress too. A public Slack channel shared with a vendor, a Zendesk reply, a Google Drive link switched to "anyone with the link" — these are egress events that network gateways never see, and they are precisely the events an API-based integration catches naturally. The guides on email PII scanning and support ticket PII detection cover two of these channels in detail.

Alerting vs Blocking: Choosing the Right Response

The single most consequential DLP policy decision is not what to detect but what to do when detection fires. Alert-only (also called monitor mode) lets the transfer proceed and raises an event for the security team. Blocking stops the transfer inline. Between them sit graduated responses: warning the user and asking for a justification, automatically masking the detected entities and letting the sanitized version through, or quarantining the message for human review before delivery.

Blocking is seductive — it is the only response that actually prevents the loss — but a block on a false positive stops legitimate business. Block a sales contract because a customer's own address appeared in it, and the DLP program loses political capital it may never recover; users route around controls they do not trust, usually via channels you cannot see. The industry-standard rollout is therefore staged: run every new policy in alert-only mode for two to four weeks, measure the false-positive rate on real traffic, tune entity scopes and thresholds, and only then promote the policy to warn, then mask, then block for the narrowest, highest-confidence cases.

Confidence scores make graduated response practical. Because every entity the API returns carries a confidence value between 0 and 1, your policy can block only when a critical entity (say SSN or CREDIT_CARD_NUMBER) is detected above 0.85, warn between 0.6 and 0.85, and merely log below that. Severity should also be combinatorial: one email address in an outbound message is routine; two hundred email addresses plus names and dates of birth is an exfiltrated customer table. Counting entities per type — which the structured response makes trivial — is how you distinguish the two.

Anti-pattern: enabling blocking on day one with default rules. Nearly every failed DLP rollout follows this script: broad regex rules, immediate enforcement, a flood of blocked legitimate work in week one, and an executive order to switch the system off in week three. Alert first, measure, tune, then enforce.

Whatever the disposition, log the full detection result — entity types, counts, confidence, policy matched, action taken — but consider logging the masked text rather than the raw payload, so your DLP audit trail does not itself become a PII store. The API's mask_mode option returns a redacted rendering of the input in the same call, which is exactly what belongs in the incident ticket. See measuring detection accuracy for how to quantify precision and recall before you flip a policy to block.

Integrating Detection into a DLP Policy Engine

A DLP policy engine is, at heart, a function from (channel, sender, destination, detection result) to (action, severity). The detection API supplies the fourth input as structured JSON, which means policies become straightforward data-driven rules instead of brittle pattern lists. A well-shaped policy record defines: the channels it applies to, the entity types in scope, per-entity minimum confidence, count thresholds, combination rules ("name + national ID together escalates severity"), and the action ladder from log to block.

The integration itself is a single HTTPS call per scanned payload. You send the text along with the entity scope and threshold that the matched policy prescribes; the API answers with detected_entities, a count, a masked version of the text, and processing time. A minimal egress check for an outbound message looks like this:

# Scan an outbound message against a payment-data egress policy
curl -X POST https://piidetectionapi.com/api/moderate.php \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "YOUR_API_KEY",
    "api_type": "pii_detection",
    "text": "Hi, card 4111 1111 1111 1234 exp 04/27 cvv 812 for John Doe, SSN 545-12-8934.",
    "entities": ["CREDIT_CARD_NUMBER", "CREDIT_CARD_EXPIRATION_DATE",
                 "CVV_NUMBER", "SSN", "PERSON_NAME"],
    "threshold": 0.6,
    "mask_mode": "replace"
  }'
cURL — egress scan request

The response gives the policy engine everything it needs to reach a verdict, including a sanitized rendering it can substitute for the original if the policy action is "mask and deliver":

{
  "detected_entities": [
    {"type": "CREDIT_CARD_NUMBER", "text": "4111 1111 1111 1234",
     "start": 9, "end": 28, "confidence": 0.99},
    {"type": "CVV_NUMBER", "text": "812", "start": 42, "end": 45, "confidence": 0.93},
    {"type": "PERSON_NAME", "text": "John Doe", "start": 50, "end": 58, "confidence": 0.97},
    {"type": "SSN", "text": "545-12-8934", "start": 64, "end": 75, "confidence": 0.98}
  ],
  "anonymized_text": "Hi, card [CREDIT_CARD_NUMBER] exp [CREDIT_CARD_EXPIRATION_DATE] cvv [CVV_NUMBER] for [NAME], SSN [SSN].",
  "entities_detected": 5,
  "processing_time_ms": 174,
  "mask_mode_used": "replace",
  "status": 200
}
JSON — detection response

Note the custom_instruction field, which accepts natural-language exclusions such as "ignore our own company address and support phone number" — a far more maintainable way to suppress known-benign matches than maintaining regex exception lists inside every policy.

A Working Policy Engine in Python and Node.js

The Python example below implements the graduated-response model described above: it scans an outbound payload, evaluates the findings against a policy table with per-entity confidence floors and count thresholds, and returns one of allow, mask, or block together with the sanitized text to forward when masking.

import requests

API_URL = "https://piidetectionapi.com/api/moderate.php"
API_KEY = "YOUR_API_KEY"

# Policy: entity scope, min confidence, and count that triggers a block
POLICY = {
    "CREDIT_CARD_NUMBER": {"min_conf": 0.85, "block_at": 1},
    "CVV_NUMBER":         {"min_conf": 0.85, "block_at": 1},
    "SSN":                {"min_conf": 0.85, "block_at": 1},
    "PERSON_NAME":        {"min_conf": 0.70, "block_at": 50},
    "EMAIL_ADDRESS":      {"min_conf": 0.70, "block_at": 50},
}

def evaluate_egress(text):
    resp = requests.post(API_URL, json={
        "api_key": API_KEY,
        "api_type": "pii_detection",
        "text": text,
        "entities": list(POLICY.keys()),
        "threshold": 0.5,
        "mask_mode": "replace",
    }, timeout=30)
    data = resp.json()

    counts = {}
    for e in data["detected_entities"]:
        rule = POLICY.get(e["type"])
        if rule and e["confidence"] >= rule["min_conf"]:
            counts[e["type"]] = counts.get(e["type"], 0) + 1

    if any(counts.get(t, 0) >= r["block_at"] for t, r in POLICY.items()):
        return {"action": "block", "counts": counts}
    if counts:
        return {"action": "mask", "counts": counts,
                "safe_text": data["anonymized_text"]}
    return {"action": "allow", "counts": {}}

verdict = evaluate_egress("Refund to card 4111 1111 1111 1234, cvv 812.")
print(verdict["action"])   # -> "block"
Python — graduated-response policy engine

The same logic drops into a Node.js gateway or middleware. This version is written as an async function suitable for an Express handler or an SMTP milter bridge, and demonstrates alert-mode logging with the masked text in the audit record:

// Node.js 18+ (native fetch) — egress check with alert-mode logging
async function scanEgress(text, channel) {
  const resp = await fetch("https://piidetectionapi.com/api/moderate.php", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      api_key: process.env.PII_API_KEY,
      api_type: "pii_detection",
      text: text,
      entities: ["CREDIT_CARD_NUMBER", "SSN", "PERSON_NAME",
                 "EMAIL_ADDRESS", "API_KEY", "AWS_CREDENTIALS"],
      threshold: 0.6,
      mask_mode: "replace"
    })
  });
  const data = await resp.json();

  const critical = data.detected_entities.filter(e =>
    ["CREDIT_CARD_NUMBER", "SSN", "AWS_CREDENTIALS", "API_KEY"]
      .includes(e.type) && e.confidence >= 0.85);

  if (data.entities_detected > 0) {
    // Audit record stores the MASKED text, never the raw payload
    console.log(JSON.stringify({
      event: "dlp_detection", channel,
      entityCounts: data.entities_detected,
      types: [...new Set(data.detected_entities.map(e => e.type))],
      preview: data.anonymized_text.slice(0, 200),
      action: critical.length ? "block" : "alert"
    }));
  }
  return critical.length ? { allow: false } : { allow: true };
}
JavaScript — Node.js egress middleware

Both examples finish in a single round trip of roughly 150–250 ms, which fits inline enforcement on email gateways and application middleware. For very large files, run detection asynchronously: accept the transfer into a quarantine area, scan in the background, and release or hold based on the verdict. Try the exact payloads above in the interactive demo before wiring them into a gateway.

Tuning Thresholds and Taming False Positives

DLP tuning is an exercise in moving along the precision-recall curve deliberately instead of accidentally. Raising the threshold parameter suppresses low-confidence matches and improves precision at some cost to recall; lowering it does the reverse. The right operating point differs per action: blocking rules should sit at high thresholds (0.8–0.9) because the cost of a false positive is stopped business, while alert-only monitoring can afford 0.5 because an analyst, not an automated block, absorbs the noise.

Beyond the global threshold, three levers matter most in production. Entity scoping: only request the entity types the policy actually acts on — scanning an engineering channel for MEDICAL_DATA produces nothing but noise. Exclusions: use exclude_entities to drop types that are pervasive and benign in a given channel (URLs and user agents in web logs, for instance), and custom_instruction to whitelist your own organization's public contact details. Combination rules: escalate on co-occurrence rather than single hits — a lone phone number is weak evidence, but a phone number adjacent to a name and a date of birth is a customer record.

Measure before and after every tuning change. Keep a labeled corpus of a few hundred real (or realistic) egress samples — true leaks, near-misses, and clean traffic — and score each policy revision against it. Precision below roughly 90% on a blocking rule generates enough friction that users start working around the control; recall gaps tell you which leak shapes your entity scope is missing. The methodology, including how to build the corpus and compute F1 per entity type, is covered step by step in Measuring PII Detection Accuracy.

Tip: tune per channel, not globally. The same policy that is perfectly quiet on outbound email may be deafening on an internal wiki where employee names legitimately appear in every document. Channel-specific entity scopes and thresholds — all just parameters on the API call — keep each control at its own optimal operating point.

DLP Deployment Best Practices

Programs that survive their first year follow a recognizable playbook: start where the risk is, prove value in monitor mode, and make enforcement precise before making it broad.

Start with the Riskiest Channels

Map where regulated data actually moves before deploying anything. For most organizations the top three egress channels by incident volume are outbound email, support/ticketing replies, and file-sharing links. Instrument those first with API-based scanning, demonstrate detections on real traffic within the first sprint, and use that evidence to prioritize the rest of the roadmap.

  • Inventory channels and rank by data sensitivity and volume
  • Ship the first integration in days, not quarters
  • Report real findings early to sustain sponsorship

Alert First, Block Later

Promote each policy through a fixed ladder — log, alert, warn-with-justification, mask, block — and require measured precision at each rung before advancing. Keep blocking reserved for high-confidence detections of critical entities on irreversible channels. Every block should carry a clear user-facing explanation and a fast appeal path, or users will defect to invisible channels.

  • Two-to-four-week monitor period per new policy
  • Confidence-tiered actions using per-entity scores
  • Self-service override with audit trail for edge cases

Keep the Audit Trail Clean

DLP systems routinely commit the irony of copying sensitive data into their own alert queues. Store masked text and entity metadata in incidents, restrict raw-payload access to a break-glass workflow, and set retention on DLP events just as you would on the data they describe. Consistent, structured detection results make regulator-ready reporting — who detected what, where, and what happened next — a query instead of a project.

  • Log anonymized_text, not raw payloads
  • Record entity types, counts, confidence, and action taken
  • Align event retention with your data-retention policy

Frequently Asked Questions

Can an API-based detector really run inline on an email gateway?
Yes. Typical detection latency is 150–250 ms per request, well within the several-second budget SMTP gateways tolerate before delivery. For bulk mail or very large attachments, the standard pattern is asynchronous: accept the message into a short-lived quarantine, scan, then release, hold, or mask. Web-proxy (ICAP) integrations use the same pattern with a tighter synchronous budget, which is why entity scoping — requesting only the types the policy needs — matters for those channels.
How is ML-based detection better than the regex rules in my existing DLP product?
Regex handles rigidly formatted identifiers but fails on natural language: names, addresses, health information, and any identifier typed with unusual spacing or embedded in prose. Transformer-based NER reads context, so "call Jordan at extension 4111" is not a credit card and "her social is 545 12 8934" is an SSN despite the nonstandard format. In practice teams see both fewer false positives and materially higher recall. The full comparison, with test cases, is in our NER vs regex guide.
Should DLP policies block or just alert?
Both, applied selectively. Block only high-confidence detections of critical entities (payment card data, national IDs, credentials) on irreversible egress channels, after a monitor-mode period has proven the policy's precision. Everything else should alert, warn, or auto-mask. Programs that block broadly from day one generate user revolt and get switched off; programs that only ever alert never prevent anything. The graduated ladder — log, alert, warn, mask, block — is the sustainable middle path.
What happens with content larger than the 50,000-character request limit?
Split the content on paragraph or sentence boundaries into chunks under the limit, scan chunks in parallel, and merge the results, adding each chunk's base offset to the returned entity positions. Splitting on natural boundaries rather than fixed byte counts avoids cutting an entity in half at a chunk edge. For file formats such as PDF or DOCX, extract text first — the workflow is covered in the document scanning guide.
Does sending content to a detection API create its own data-protection risk?
The detection call is processing like any other and should be covered by your processor agreements. The API transmits over TLS, is operated under GDPR-native controls, and does not need to persist scanned content to return a verdict. For environments where content may not leave the network at all — defense, some healthcare and banking deployments — the same detection engine is available as an on-premise deployment, so the DLP architecture stays identical while the data path stays internal. Details are on the API overview page.
Can detection also catch secrets like API keys, not just personal data?
Yes — credentials are first-class entity types: API_KEY, AUTH_TOKEN, PASSWORD, AWS_CREDENTIALS, GCP_CREDENTIALS, SSH_KEY, PRIVATE_KEY, and DATABASE_CONNECTION_STRING among others. Many teams run a dedicated "secrets egress" policy on developer channels (git pushes to public repos, pastebins, chat) scoped to exactly these types with a low threshold, since a leaked credential is damaging at any confidence level. The complete list is on the entities page.

Put Real Detection at the Core of Your DLP

Scan your first egress payload in minutes: 150+ entity types, confidence scores, offsets, and built-in masking from a single API call. Try it live, then pick a plan that fits your volume.

Try the Live Demo View Pricing