A practical guide to finding and classifying California personal information at scale: PI categories, sensitive PI under CPRA, consumer rights requests, data mapping, and service-provider obligations — all powered by automated PII detection.
Explore the GuideThe California Consumer Privacy Act (CCPA) took effect in January 2020 and gave California residents a set of enforceable rights over the personal information that businesses collect about them. The California Privacy Rights Act (CPRA), approved by ballot initiative in November 2020 and fully operative since January 2023, amended and significantly expanded the CCPA. Together they form the most consequential privacy regime in the United States, enforced by the California Privacy Protection Agency (CPPA) and the state Attorney General, with administrative fines of up to $2,500 per unintentional violation and $7,500 per intentional violation or violation involving minors — assessed per consumer, per incident.
The law applies to for-profit businesses that do business in California and meet any one of three thresholds: annual gross revenue above $25 million; buying, selling, or sharing the personal information of 100,000 or more California consumers or households per year; or deriving 50 percent or more of annual revenue from selling or sharing personal information. Because the thresholds attach to doing business in California rather than being located there, most SaaS companies, retailers, publishers, and data-driven businesses with a national customer base fall within scope whether or not they have a single office in the state.
What makes CCPA/CPRA operationally hard is not the legal text — it is the fact that every obligation presupposes that you know where personal information lives. You cannot honor a deletion request against data you cannot find. You cannot produce an accurate response to a request to know if half of the consumer's data sits in free-text support tickets, call transcripts, and log files that your inventory never covered. You cannot limit the use of sensitive personal information you never classified as sensitive. Automated PII detection turns those unknowns into structured, queryable facts.
This guide walks through the statutory categories of personal information and sensitive personal information, shows how each maps to concrete detectable entity types, and demonstrates — with working code against our PII Detection API — how to build the discovery, request-fulfillment, and minimization workflows the law expects.
CCPA defines personal information as any information that identifies, relates to, describes, or could reasonably be linked with a particular consumer or household. Civil Code section 1798.140(v) enumerates eleven broad categories — far wider than classic "PII" lists.
Real names, aliases, postal addresses, unique personal identifiers, online identifiers, IP addresses, email addresses, account names, Social Security numbers, driver's license numbers, and passport numbers. This is the category most people picture when they hear "PII," and it is the category consumers cite most often in access and deletion requests.
Records of products purchased or considered, purchasing histories and tendencies, plus the customer-records categories incorporated from California's earlier data-breach statute: bank account numbers, credit and debit card numbers, insurance policy numbers, and financial account credentials. These appear constantly in order systems, refunds, and support conversations.
Browsing history, search history, interactions with websites, applications, and advertisements, plus precise geolocation data. Device identifiers, cookies, user-agent strings, and GPS coordinates buried in analytics events and clickstream logs all fall here — a category regex-era compliance tooling routinely misses.
Employment history, education records, biometric information, audio and visual data such as call recordings and CCTV, and — critically — inferences drawn from any of the above to build a profile reflecting preferences, characteristics, or behavior. Inferences are personal information in their own right and must be disclosed in response to a request to know.
CPRA created an entirely new sub-class of data — sensitive personal information (SPI) — with its own disclosure obligations and its own consumer right: the right to limit the use and disclosure of sensitive personal information to what is necessary to perform the services the consumer requested. If your business collects SPI and uses it beyond those narrow purposes, you must offer a "Limit the Use of My Sensitive Personal Information" link and honor it, alongside the familiar "Do Not Sell or Share" link.
SPI includes government identifiers (Social Security, driver's license, state ID, and passport numbers); account log-in credentials, or financial account, debit, or credit card numbers combined with any required access code or password; precise geolocation within a radius of 1,850 feet; racial or ethnic origin, religious or philosophical beliefs, and union membership; the contents of mail, email, and text messages where the business is not the intended recipient; genetic data; biometric information processed to identify a consumer; health data; and information about sex life or sexual orientation.
The operational challenge is that SPI rarely arrives labeled. A support agent's note that a customer "mentioned she's fasting for Ramadan and needs delivery after sunset" contains an inference about religious observance. A chat transcript in which a user pastes their online-banking password alongside their account number is SPI of the highest order. Detection systems built only on pattern matching find the card number but miss the religion, the sexual-orientation reference, and the health disclosure, because those are expressed in ordinary language rather than in formatted tokens.
Our API addresses exactly this gap: transformer-based, context-aware models detect entity types such as ETHNIC_GROUP, RELIGION, SEXUAL_ORIENTATION, MEDICAL_DATA, BIOMETRIC_DATA, and PASSWORD in free text across 60+ languages, returning character offsets and confidence scores you can route into your SPI inventory and limitation workflows.
The table below maps the statutory categories to the entity types the API detects out of the box. Use it to build the entities parameter for category-scoped scans, or omit the parameter to detect all 150+ types. The full catalog is on our entities page.
| Statutory category | CPRA sensitive? | API entity types | Typical hiding places |
|---|---|---|---|
| Identifiers (§1798.140(v)(1)(A)) | Partially (government IDs) | PERSON_NAME, EMAIL_ADDRESS, PHONE_NUMBER, ADDRESS, SSN, DRIVERS_LICENSE_NUMBER, PASSPORT_NUMBER, IP_ADDRESS |
CRM records, support tickets, sign-up forms, server logs |
| Customer records / financial (§1798.140(v)(1)(B)) | Yes, with credentials | CREDIT_CARD_NUMBER, CVV_NUMBER, FINANCIAL_ACCOUNT_NUMBER, IBAN_CODE, ROUTING_NUMBER, PASSWORD |
Payment notes, chat transcripts, emailed invoices, refunds |
| Protected classifications (§1798.140(v)(1)(C)) | Yes (race, religion, union) | ETHNIC_GROUP, RELIGION, GENDER, AGE, MARITAL_STATUS, SEXUAL_ORIENTATION |
Free-text survey answers, HR files, agent notes |
| Internet / network activity (§1798.140(v)(1)(F)) | No | IP_ADDRESS, MAC_ADDRESS, DEVICE_ID, COOKIE, USER_AGENT, URL |
Clickstream events, analytics payloads, application logs |
| Geolocation (§1798.140(v)(1)(G)) | Yes, if precise | GPS_COORDINATES, ADDRESS, ZIP_CODE, CITY |
Mobile telemetry, delivery apps, photo EXIF exports |
| Biometric, health, genetic (§1798.140(ae)(2)) | Yes | BIOMETRIC_DATA, MEDICAL_DATA, DIAGNOSIS, PRESCRIPTION, HEALTH_INSURANCE_ID, BLOOD_TYPE |
Wellness-program records, insurance claims, call transcripts |
| Professional / employment (§1798.140(v)(1)(I)) | No | EMPLOYMENT, PERSON_NAME, TAX_ID |
Applicant-tracking systems, references, B2B contact data |
Notice how many "typical hiding places" are unstructured: tickets, transcripts, notes, and logs. Structured databases are the easy 40 percent of a CCPA data map. The remaining 60 percent — the text your people and systems generate every day — is where detection accuracy decides whether your compliance program is real or aspirational. Try it against your own sample text in the live demo.
CCPA/CPRA grants consumers a bundle of rights, each with a 45-day response clock (extendable once by 45 days). Every one of them depends on your ability to locate a specific person's information across every store you operate.
Consumers may request the categories and specific pieces of personal information collected about them, the sources, the business purposes, and the third parties it was disclosed to. A defensible response requires scanning unstructured stores — tickets, emails, notes — for the requester's identifiers, then reporting the entity categories found. Detection output (type, matched text, offsets) doubles as the evidence trail for what you disclosed and why.
Deletion must reach every copy that is not covered by a statutory exception — including the consumer's phone number pasted into a Slack-synced support thread three years ago. Detection with mask_mode lets you redact the requester's PII from shared documents where wholesale deletion would destroy business records you are entitled to keep, satisfying the request while preserving the surrounding context.
New under CPRA: consumers can demand correction of inaccurate personal information. Correction is only possible if you can enumerate where the inaccurate value appears. Entity-level detection with character offsets gives you the exact positions of every occurrence of, say, an outdated address, so corrections can be applied programmatically and consistently across systems rather than field by field in one CRM.
The right to opt out of sale/sharing and the right to limit SPI use both require knowing which downstream flows carry which categories. Scanning the payloads you send to ad-tech partners, analytics vendors, and data brokers tells you definitively whether opted-out consumers' identifiers — or anyone's SPI — are leaving the building, and lets you strip them in-flight rather than renegotiating every integration.
Both the CPRA regulations and the CPPA's audit expectations assume a current, accurate data inventory: what personal information you hold, in which categories, in which systems, for what purposes, with what retention, and shared with whom. Most organizations begin with interviews and spreadsheets. That approach captures what teams believe they store — and misses what their systems actually store. The gap between the two is where enforcement actions live.
A detection-driven inventory inverts the process. Instead of asking owners what a system contains, you sample it: pull representative records from each table, bucket, topic, and mailbox; run the text through the detection API; and aggregate the results into a per-system category profile. A database column named notes that turns out to contain Social Security numbers in 2 percent of rows is exactly the finding that interviews never surface and auditors always ask about.
Sampling strategy matters more than volume. For structured stores, scan a random sample of rows per free-text column plus every column whose name suggests contact or identity data. For object storage and document systems, stratify by file type and age. For streaming systems, tap a fraction of live traffic. Re-run on a schedule — monthly for high-churn systems, quarterly elsewhere — because a data map is a snapshot, and CPRA's annual privacy-policy disclosure requires you to describe categories collected in the preceding 12 months.
Each scan result carries entity types, confidence scores, and counts, which roll up naturally into the disclosure tables your privacy policy needs and the records-of-processing documentation your assessments need. Teams typically automate this in a nightly job; see our database PII discovery guide for schema-level patterns, and pricing for volume tiers suited to full-corpus sweeps.
CPRA formalized three roles — service provider, contractor, and third party — and put real obligations on the first two. If you process personal information on behalf of business customers, these duties are yours; if you engage vendors, verifying these duties is yours.
A service provider may process personal information only for the business purposes specified in a written contract, and may not sell it, share it, or combine it with data from other sources except as permitted. Scanning the data you actually receive from each customer lets you demonstrate that what flows in matches what the contract says should flow in — and flag over-collection back to the customer.
Service providers must assist businesses in responding to consumer requests, including deleting personal information when instructed. That means you need the same search-and-redact machinery as the business itself: given a consumer's identifiers, find and remove or mask their data across your copies, then attest to completion within the business's response window.
CPRA added a duty to implement reasonable security procedures, and the private right of action for breaches of unencrypted, unredacted personal information puts a dollar figure ($100–$750 per consumer per incident) on failure. Continuous PII detection in logs, tickets, and internal tools shrinks the blast radius of any breach by ensuring sensitive values are masked wherever they are not strictly needed.
Contracts must flow the same obligations down to subprocessors, and businesses gain rights to audit compliance. Being able to produce entity-level scan reports — which categories of PI you hold per customer, where, and how it is protected — turns an audit from a two-week fire drill into an export. On-premise deployment of the detection engine keeps even the scanning step inside your boundary.
The examples below use the production endpoint and the canonical request contract. The first scans a support-ticket excerpt for the identifier and financial categories; the second sweeps free-text database fields and aggregates category counts for your data map; the third masks SPI before an event is forwarded to analytics. Full parameter reference lives in the API documentation.
1. cURL — category-scoped scan of a support ticket
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": "Customer Maria Gonzalez ([email protected], 415-555-0182) asked us to update the card on file ending 4111 1111 1111 1111 and mentioned her new address: 2210 Mission St, San Francisco, CA 94110.",
"entities": ["PERSON_NAME", "EMAIL_ADDRESS", "PHONE_NUMBER",
"CREDIT_CARD_NUMBER", "ADDRESS"],
"mask_mode": "replace",
"threshold": 0.5
}'
2. Python — inventory sweep with category aggregation
import requests
from collections import Counter
# Map detected entity types to CCPA statutory categories
CCPA_CATEGORY = {
"PERSON_NAME": "Identifiers", "EMAIL_ADDRESS": "Identifiers",
"SSN": "Identifiers (sensitive)",
"CREDIT_CARD_NUMBER": "Customer records (sensitive)",
"GPS_COORDINATES": "Geolocation (sensitive)",
"RELIGION": "Protected classifications (sensitive)",
"IP_ADDRESS": "Internet activity",
}
def scan_field(text):
resp = requests.post(
"https://piidetectionapi.com/api/moderate.php",
json={
"api_key": "YOUR_API_KEY",
"api_type": "pii_detection",
"text": text, # all entity types (default)
"threshold": 0.6,
},
timeout=30,
)
resp.raise_for_status()
return resp.json()["detected_entities"]
def profile_rows(rows):
"""rows: iterable of free-text values sampled from one column."""
counts = Counter()
for text in rows:
for e in scan_field(text):
category = CCPA_CATEGORY.get(e["type"], "Other PI")
counts[(e["type"], category)] += 1
return counts
# Example: profile the 'notes' column of the CRM
for (etype, cat), n in profile_rows(sample_notes).most_common():
print(f"{etype:24} {cat:36} {n} hits")
3. JavaScript (Node) — strip SPI before events reach analytics
const SPI_ENTITIES = [
"SSN", "PASSPORT_NUMBER", "DRIVERS_LICENSE_NUMBER",
"CREDIT_CARD_NUMBER", "PASSWORD", "GPS_COORDINATES",
"RELIGION", "ETHNIC_GROUP", "SEXUAL_ORIENTATION",
"MEDICAL_DATA", "BIOMETRIC_DATA"
];
async function stripSpi(eventText) {
const res = 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: eventText,
entities: SPI_ENTITIES,
mask_mode: "hash" // consistent hashes keep analytics joins intact
})
});
const data = await res.json();
return {
safeText: data.anonymized_text,
spiFound: data.entities_detected > 0,
types: data.detected_entities.map(e => e.type)
};
}
// Gate the analytics pipeline
const { safeText, spiFound, types } = await stripSpi(rawEvent.body);
if (spiFound) auditLog.record({ event: rawEvent.id, spi: types });
analytics.track({ ...rawEvent, body: safeText });
The hash mask mode deserves a note: it replaces each value with a consistent token, so the same email always hashes to the same placeholder. Counts, funnels, and joins keep working in analytics while the raw identifier never leaves your trust boundary — a clean answer to the CPRA question "is this disclosure necessary to perform the service?"
Detection is a capability, not a checkbox. These practices separate programs that survive a CPPA inquiry from ones that merely look complete in a slide deck.
Data maps decay. New SaaS tools, new event fields, and new agent habits introduce PI into systems that were clean at the last audit. Wire detection into ingestion points — ticket creation, log shipping, ETL jobs — so classification happens as data arrives, and schedule periodic full sweeps to catch what slipped through. The 45-day request clock is survivable only when discovery is already done before the request lands.
A rights-request search wants high recall: lower the threshold to 0.3–0.4 and accept manual review of borderline hits, because missing a consumer's record is the expensive failure. An automated redaction pipeline wants precision: raise the threshold and scope entities to the categories at issue so you do not mask harmless text. One API, two configurations — document both in your procedures.
Every scan, request fulfillment, and redaction should leave an audit record: what was scanned, what categories were found, what action was taken, when, and by which system. Retain the metadata and the masked output — never a duplicate of the raw PI. When the CPPA asks how you verified a deletion request was fully honored, the answer is a query over this evidence store, delivered in minutes.
Scan tickets, logs, databases, and documents for all CCPA/CPRA categories — including sensitive PI — with one API call. Try it on your own text in seconds, no signup required.
Try the Live Demo View Pricing