piidetectionapi.com
Home
Solutions - Fundamentals
What Is PII Detection? NER vs Regex vs Rules Accuracy, Precision & Recall PII in Test Data
Solutions - Compliance
GDPR Personal Data HIPAA PHI Detection CCPA / CPRA PCI DSS Card Data
Solutions - AI & LLM Safety
LLM Guardrails Chatbot PII Filtering RAG Pipelines
Solutions - Data Discovery & DLP
Data Loss Prevention Log File Scanning Support Tickets Email Scanning Documents & PDFs Database Discovery ETL & Streaming Pipelines
Industries - Financial
Banking Fintech Insurance
Industries - Healthcare
Healthcare Pharma & Clinical Trials Telehealth
Industries - Public Sector & Legal
Government & FOIA Law Enforcement Law Firms & eDiscovery Education (FERPA)
Industries - Technology
SaaS Platforms Cybersecurity & IR Telecommunications Gaming & Platforms
Industries - Other
HR & Recruiting Retail & E-commerce Call Centers & BPO Real Estate Travel & Hospitality Marketing & AdTech
How-to Guides - Identity & Contact
Detect Names Detect Email Addresses Detect Phone Numbers Detect Physical Addresses Detect Dates of Birth
How-to Guides - IDs & Financial
Detect SSNs Detect Passport Numbers Detect Drivers Licenses Detect Credit Card Numbers Detect Bank Accounts & IBAN
How-to Guides - Technical & Health
Detect IP & Device IDs Detect Medical Records & PHI
Resources
Pricing API Docs Supported Entities Languages About Contact Sign In Try the Live Demo Get Started
How-To Guide

How to Detect People's Names in Text

Learn how to automatically find, classify, and locate person names in text, documents, chat logs, and transcripts using PII Detection API. Context-aware AI handles titles, multicultural name formats, and lookalike words that trip up regex-based scanners.

12 min read
cURL, Python & JavaScript examples
Updated Aug 2026

Overview

A person's name is the most fundamental piece of personally identifiable information there is, and it is also the hardest one to find reliably. Names have no fixed pattern: there is no character class, no checksum, and no standard length that separates "Amara Okafor" from any other pair of capitalized words. A name can be two words, one word, or five. It can carry a title, a suffix, a hyphen, an apostrophe, or diacritics. It can also be a word that means something else entirely in another sentence — "Hunter" is a person in one support ticket and a job description in the next.

PII Detection API solves this with transformer-based named entity recognition (NER) rather than pattern matching. The model reads the surrounding sentence, so it knows that "May Johnson called yesterday" contains a person while "May sales exceeded targets" does not. When you scan text for the PERSON_NAME entity, the API returns every detected name with its exact character offsets, its matched text, and a confidence score — and, if you want it, a masked copy of the input as an optional next step.

Input text
Please forward the invoice to Priya Ramanathan. Her manager, Dr. James O'Neill-Baker, signs off on Fridays.
Detected entities
PERSON_NAME: "Priya Ramanathan" (offsets 30–46, confidence 0.97)  |  PERSON_NAME: "James O'Neill-Baker" (offsets 66–85, confidence 0.96)
60+ Languages
Names detected in English, Spanish, Chinese, Arabic, Hindi, and dozens more
Context-Aware
Transformer NER distinguishes person names from places, brands, and common words
Exact Offsets
Every match returns start/end positions and a confidence score you can act on

This guide walks through the full problem space: why name detection matters for compliance, how to call the API, which name formats and cultural conventions you need to plan for, how to keep false positives under control, and how to tune detection for your own domain. Everything shown here also works across the other 150+ entity types listed on our supported entities page.

Why Detect Names

Name detection is usually the first requirement in any data protection project, because names are the anchor that links every other data point to an identifiable human being. A leaked phone number is a nuisance; a leaked phone number next to a full name is a reportable incident. Knowing exactly where names live in your text is the precondition for redaction, access control, data mapping, and breach response.

Regulatory Drivers

  • GDPR (EU): A natural person's name is the canonical example of personal data under Article 4. Any system that stores or processes names of EU residents falls under GDPR obligations, including data subject access requests and the right to erasure — both of which require you to first find every occurrence.
  • HIPAA (US healthcare): Names are identifier #1 on the Safe Harbor list of 18 identifiers that must be removed before health information counts as de-identified. Name detection is the entry point to any PHI de-identification pipeline.
  • CCPA/CPRA (California): "Real name" and "alias" are explicitly enumerated categories of personal information. Consumers can demand disclosure or deletion of records containing their name.
  • FERPA, GLBA, PIPEDA and others: Virtually every privacy framework worldwide treats a person's name as protected data in combination with other information.

Operational Use Cases

  • LLM guardrails: Scan prompts before they reach a third-party model so employee and customer names never leave your boundary.
  • Support and CRM analytics: Locate names in tickets and call transcripts before feeding them to analytics or training pipelines.
  • Log hygiene: Developers accidentally log names constantly — in error messages, request payloads, and debug output. Automated detection catches what code review misses.
  • Document review and eDiscovery: Flag every named individual in contracts, filings, and correspondence for privilege review or redaction.
  • Recruiting and HR: Detect candidate names in CVs and feedback notes to support blind screening and retention policies.

Detection first, redaction second. Many teams jump straight to masking, but detection output on its own — types, offsets, confidence — is what powers data inventories, DSAR search, and risk scoring. PII Detection API always returns the structured entity list; the masked text is an optional extra controlled by mask_mode.

Quick Start

One HTTPS request is all it takes. Send your text to the REST API with the PERSON_NAME entity selected, and you get back every detected name with offsets and confidence scores. Grab a free key on the get started page or try it without code in the live demo.

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": "Please forward the invoice to Priya Ramanathan. Her manager, Dr. James O'\''Neill-Baker, signs off on Fridays.",
    "entities": ["PERSON_NAME"],
    "mask_mode": "replace"
  }'
import requests

resp = requests.post(
    "https://piidetectionapi.com/api/moderate.php",
    json={
        "api_key": "YOUR_API_KEY",
        "api_type": "pii_detection",
        "text": "Please forward the invoice to Priya Ramanathan. "
                "Her manager, Dr. James O'Neill-Baker, signs off on Fridays.",
        "entities": ["PERSON_NAME"],
        "mask_mode": "replace",
    },
    timeout=30,
)
data = resp.json()
for e in data["detected_entities"]:
    print(e["type"], e["text"], e["start"], e["end"], e["confidence"])
const resp = await fetch("https://piidetectionapi.com/api/moderate.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    api_key: "YOUR_API_KEY",
    api_type: "pii_detection",
    text: "Please forward the invoice to Priya Ramanathan. Her manager, Dr. James O'Neill-Baker, signs off on Fridays.",
    entities: ["PERSON_NAME"],
    mask_mode: "replace"
  })
});
const data = await resp.json();
data.detected_entities.forEach(e =>
  console.log(e.type, e.text, e.start, e.end, e.confidence)
);

The response contains the structured entity list plus, because mask_mode was set, a masked copy of the input:

{
  "detected_entities": [
    {"type": "PERSON_NAME", "text": "Priya Ramanathan", "start": 30, "end": 46, "confidence": 0.97},
    {"type": "PERSON_NAME", "text": "James O'Neill-Baker", "start": 66, "end": 85, "confidence": 0.96}
  ],
  "anonymized_text": "Please forward the invoice to [NAME]. Her manager, Dr. [NAME], signs off on Fridays.",
  "entities_detected": 2,
  "processing_time_ms": 142,
  "mask_mode_used": "replace",
  "status": 200
}

A few practical notes on the request contract. The text field accepts up to 50,000 characters per request, so most documents fit in a single call. If you omit entities, the API scans for all 150+ supported types at once; passing ["PERSON_NAME"] narrows the scan and shaves latency. The start and end offsets are zero-based character positions into the exact string you sent, which makes it trivial to highlight matches in a UI or splice in your own replacements.

Name Formats & Variations

The same human being can appear in your data under a dozen surface forms, and a detector that only recognizes "Firstname Lastname" will miss most of them. Before you trust any name detection pipeline, test it against the formats that actually occur in your text.

Structural Variations

  • Full names: "Sarah Mitchell", "John William Smith" — the easy case, though middle names stretch the span.
  • First name only: "Thanks, Sarah!" — extremely common in chat, email sign-offs, and support tickets, and completely invisible to surname-list approaches.
  • Surname only: "Mitchell disputed the charge" — frequent in legal and journalistic text.
  • Initials: "J. W. Smith", "S. Mitchell", or bare monograms like "JWS" in meeting minutes.
  • Hyphenated and apostrophe names: "O'Neill-Baker", "D'Angelo", "Al-Rashid" — naive tokenizers split these and detect half a name.
  • Suffixes and generational markers: "Martin Luther King Jr.", "Henry Ford III", "Robert Downey Sr." — the suffix belongs inside the entity span.
  • Possessives and inflections: "Sarah's account", "the Mitchells" — the detector must separate the name from the grammatical decoration.

Titles and Honorifics

Titles are strong contextual evidence that a name follows: "Dr.", "Mr.", "Mrs.", "Ms.", "Prof.", "Rev.", "Sen.", "Capt.", and their international equivalents ("Herr", "Señora", "Monsieur"). PII Detection API uses titles as detection signals but keeps the entity span on the name itself, so "Dr. Sarah Mitchell" yields the entity "Sarah Mitchell" and your masked output reads "Dr. [NAME]" — preserving the professional role, which is often useful analytical context. Job titles that precede names ("CFO Elena Petrova") behave the same way.

Input
Prof. Anna Kowalska-Nowak and her assistant T. J. Reyes will attend. Anna's flight lands at 9.
Masked output (mask_mode: "replace")
Prof. [NAME] and her assistant [NAME] will attend. [NAME]'s flight lands at 9.

Watch the short forms. Single-token mentions ("Sarah", "Reyes") carry less context than full names and typically score lower confidence. If you filter aggressively with a high threshold, first-name-only mentions are the matches you will lose first. Test with real samples from your own corpus before locking in a threshold.

Multicultural Names

If your users come from more than one country — and they do — your name detector must handle naming conventions that break every Western assumption. There are cultures with no surnames, cultures where the family name comes first, and cultures where a single person's legal name contains four or five components with connective particles. PII Detection API's models are trained on multilingual corpora covering 60+ languages, so these conventions are recognized natively rather than forced through an anglocentric template.

Convention Example What detection must handle
Western given-name-first Emily Carter Baseline case; middle names and initials extend the span
East Asian family-name-first Zhang Wei, Kim Min-jun, Sato Haruka Order inversion; two-character given names; romanized and native-script forms of the same person
Spanish / Portuguese compound surnames María García Rodríguez, João Souza dos Santos Two family names (paternal + maternal); particles like "de", "dos", "da" inside the span
Arabic patronymic chains Mohammed bin Rashid Al Maktoum Connectives "bin"/"ibn"/"bint", definite article "Al-", long multi-part spans
Icelandic patronymics Björk Guðmundsdóttir No inherited surname; "-son"/"-dóttir" endings; diacritics (ð, þ, ö)
Indian conventions Ravichandran Ashwin, A. R. Rahman Initial-heavy South Indian forms; village or father's name used as prefix; honorifics like "Shri"
Mononyms Sukarno, Dewi Single-token legal names common in Indonesia and elsewhere; no second token to confirm
Slavic gendered surnames Ivan Petrov / Anna Petrova Same family, different surname endings; patronymic middle names ("Sergeyevich")

Two consequences follow for your integration. First, never post-process detected names with assumptions like "the last token is the surname" — that is wrong for a third of the planet. Treat the text span the API returns as the complete name unit. Second, expect the same person to appear in multiple scripts (for example "村上春樹" and "Haruki Murakami") within a bilingual document; the API detects both, but they are separate entity occurrences with separate offsets.

Language support: The full list of supported languages is on our supported languages page. You do not need to declare the language in the request — detection is language-agnostic and handles mixed-language text in a single call.

False Positives and How to Control Them

The hardest part of name detection is not finding names — it is not finding things that merely look like names. English is full of words that moonlight as first names, and the corporate world is full of organizations named after their founders. A detector that flags every capitalized pair destroys data utility: masking "Morgan Stanley" in a finance ticket or "Paris" in a travel itinerary makes the text useless.

The Classic Confusions

  • Organizations named after people: "Morgan Stanley", "Wells Fargo", "McKinsey", "Johnson & Johnson". These contain genuine surnames but refer to companies. Context ("shares of Morgan Stanley rose") tells the model it is an organization, so it is not flagged as PERSON_NAME.
  • Place names that are also person names: "Paris", "Austin", "Jordan", "Chelsea", "Victoria". "Flights to Austin" and "Austin approved the PR" require opposite decisions on the same token.
  • Common nouns used as names: "Rose", "Hunter", "Grace", "Mark", "Bill", "Summer", "Dawn". "Bill sent the bill" is the canonical stress test.
  • Product and brand names: "Tesla", "Mercedes", "Alexa", "Siri". A support log about "asking Alexa" should not trigger a person match.
  • Months and verbs: "April", "May", "June", "Will", "Chase" — capitalized at sentence start, these fool casing heuristics completely.
Context decides — same tokens, different entities
Jordan visited Jordan in May. May Chen and her banker at Chase approved the wire.
PERSON_NAME detections only
"Jordan" (person, offset 0) and "May Chen" — the country, the month, and the bank are correctly left alone.

Because the model reads full sentence context, these distinctions come built in. Your remaining levers are the threshold parameter, which suppresses low-confidence borderline matches, and custom_instruction, which lets you declare domain-specific exclusions in plain English — both covered in the next sections. When you do encounter a systematic false positive in your domain (say, an internal project codenamed "Rebecca"), a one-line custom instruction fixes it without retraining anything.

Why Regex Fails for Names — and What Works

Teams routinely start with a regex like [A-Z][a-z]+ [A-Z][a-z]+ plus a dictionary of common first names. It fails in both directions at once. It misses "bell hooks" (lowercase by choice), "LeBron" (mid-word capital), "O'Neill-Baker" (punctuation), "Zhang Wei" written as "ZHANG Wei" (academic convention), every mononym, and every name absent from the dictionary — which disproportionately means non-Anglo names, turning your privacy tool into a bias generator. Simultaneously it flags "New York", "Best Buy", "Happy Monday", and every capitalized sentence opener.

Dictionary lookups cannot fix this, because the set of human names is open-ended and overlaps heavily with the set of everything else. What works is what the NLP field converged on: transformer-based NER models that classify each token using bidirectional sentence context. The verb next door ("May reviewed the file" vs "in May"), the presence of a title, agreement with pronouns later in the sentence — all of it feeds the decision. That is the architecture behind PII Detection API, and it is why the service ships confidence scores: the model's certainty is real information you can route on, rather than a binary regex hit. For a deeper comparison of the approaches, see our guide NER vs Regex vs Rules.

Hybrid by design: For pattern-shaped entities like SSNs or credit cards, deterministic structure checks add value — and the API uses them where they help. Names have no structure to check, which is why they are the entity type where AI-based detection outperforms rules by the widest margin.

Tuning: Thresholds and Custom Instructions

Every detected entity carries a confidence between 0 and 1, and the request-level threshold parameter (default 0.5) filters what the API returns. Where you set it is a precision/recall trade-off that should follow from your use case, not from a default.

  • Compliance redaction (recall matters): keep the threshold low, around 0.3–0.4. A missed name is a compliance failure; an over-masked common word is a nuisance.
  • Analytics and search (precision matters): raise it to 0.7–0.85 so borderline tokens don't pollute your entity index.
  • Human-in-the-loop review: run a low threshold but route matches below ~0.7 to a review queue using the per-entity scores.
# High-recall scan for a redaction pipeline
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": "Rose from accounting said Hunter Willis already signed.",
    "entities": ["PERSON_NAME"],
    "threshold": 0.35
  }'
import requests

# Low threshold: catch short, ambiguous mentions; review the borderline ones
resp = requests.post(
    "https://piidetectionapi.com/api/moderate.php",
    json={
        "api_key": "YOUR_API_KEY",
        "api_type": "pii_detection",
        "text": "Rose from accounting said Hunter Willis already signed.",
        "entities": ["PERSON_NAME"],
        "threshold": 0.35,
    },
    timeout=30,
)
for e in resp.json()["detected_entities"]:
    bucket = "auto-mask" if e["confidence"] >= 0.7 else "review"
    print(bucket, e["text"], e["confidence"])
const resp = await fetch("https://piidetectionapi.com/api/moderate.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    api_key: "YOUR_API_KEY",
    api_type: "pii_detection",
    text: "Rose from accounting said Hunter Willis already signed.",
    entities: ["PERSON_NAME"],
    threshold: 0.35
  })
});
const { detected_entities } = await resp.json();
const toReview = detected_entities.filter(e => e.confidence < 0.7);

Custom Instructions in Plain English

The custom_instruction field (up to 500 characters) lets you steer detection with natural language — no allow-list files, no model retraining. Typical uses for names: excluding public figures quoted in news content, keeping author bylines intact, or ignoring your own staff signatures in outbound email templates.

resp = requests.post(
    "https://piidetectionapi.com/api/moderate.php",
    json={
        "api_key": "YOUR_API_KEY",
        "api_type": "pii_detection",
        "text": article_text,
        "entities": ["PERSON_NAME"],
        "custom_instruction": "Do not flag names of public figures or "
                              "politicians quoted in the article, and keep "
                              "the author byline at the top untouched.",
        "mask_mode": "replace",
    },
    timeout=30,
)
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": "Senator Maria Cantwell praised the ruling. Our reader Tom Bailey disagreed by email.",
    "entities": ["PERSON_NAME"],
    "custom_instruction": "Do not flag names of public figures or politicians; only flag private individuals.",
    "mask_mode": "replace"
  }'

In the cURL example above, only "Tom Bailey" is returned as an entity — the senator is recognized as a public figure and excluded per the instruction. This is the fastest way to encode editorial policy that pure entity selection cannot express.

Repeated Mentions and Coreference

Real documents mention the same person many times and in shrinking forms: "Dr. Sarah Mitchell" in paragraph one becomes "Sarah" in paragraph three, "Dr. Mitchell" in paragraph five, and "she" everywhere in between. For detection purposes, each named mention is returned as its own entity occurrence with its own offsets — which is exactly what you want for redaction, since every surface form must be found and handled.

Where the linkage matters is downstream analysis. If you need to know that three mentions refer to one individual — counting distinct people in a dataset, or tracking one customer through a long thread — use mask_mode: "hash". Hash mode replaces each detected name with a consistent, irreversible token, so identical names map to identical placeholders throughout the text. The narrative structure survives ("PERSON_a7f3 emailed PERSON_c21b, then PERSON_a7f3 called back") while the identities do not.

Input
Sarah Mitchell opened the ticket. Devon Cole replied, and Sarah Mitchell confirmed the fix.
mask_mode: "hash"
[NAME_9f27] opened the ticket. [NAME_4b81] replied, and [NAME_9f27] confirmed the fix.

Pronouns ("she", "her") are deliberately not treated as PERSON_NAME entities — masking every pronoun would shred readability while adding little privacy, since a pronoun with no name nearby identifies no one. If your risk model requires it, pronoun context is usually neutralized automatically once all names, email addresses, and phone numbers around them are gone.

Best Practices

1. Scan for Names Alongside Related Identifiers

A name rarely travels alone. Emails embed names ("priya.ramanathan@..."), signatures stack name, phone, and address together, and a redacted name next to an intact email is no privacy at all. Request the whole cluster in one call:

resp = requests.post(
    "https://piidetectionapi.com/api/moderate.php",
    json={
        "api_key": "YOUR_API_KEY",
        "api_type": "pii_detection",
        "text": signature_block,
        "entities": ["PERSON_NAME", "EMAIL_ADDRESS",
                     "PHONE_NUMBER", "ADDRESS"],
    },
    timeout=30,
)

2. Validate on Your Own Corpus

Benchmark accuracy numbers are computed on news text; your data is support tickets, medical notes, or chat slang. Sample a few hundred real records, run them through the interactive demo or the API, and hand-check the misses and the false alarms before choosing a threshold. Measure precision and recall separately — they fail in different directions and demand different fixes.

3. Use Offsets, Not String Search

When applying your own downstream logic, always use the returned start/end offsets instead of re-searching for the matched text. String search breaks when the same word appears both as a name and as a common noun ("Bill" the person vs "bill" the invoice) — the offsets are unambiguous.

4. Keep Humans in the Loop for Irreversible Actions

Detection feeding a search index can run fully automated. Detection feeding permanent redaction of legal originals should route sub-0.7-confidence matches through review. The confidence score exists precisely so you can automate the easy 95% and escalate the rest.

5. Monitor Drift

New products, new hires, and new slang change your text over time. Re-run your validation sample quarterly, and encode any recurring domain exceptions with custom_instruction rather than post-processing hacks. Volume pricing for continuous scanning workloads is on our pricing page.

Frequently Asked Questions

How accurate is person name detection?

On mixed real-world benchmarks the PERSON_NAME model operates in the high-90s F1 range, with full names scoring higher than isolated single-token mentions. Accuracy varies by language and domain, which is why every match carries a confidence score — you can hold automated actions to a stricter standard than review queues. Our guide to measuring detection accuracy explains how to run your own evaluation.

Which languages are supported?

Names are detected in 60+ languages, including languages without capitalization (Chinese, Japanese, Arabic, Hebrew) where casing heuristics are useless and context is the only signal. Mixed-language documents work in a single request with no language parameter needed.

Will company names like "Morgan Stanley" be flagged as people?

No — context-aware NER classifies "Morgan Stanley" as an organization when the sentence treats it as one, so it is not returned under PERSON_NAME. If a specific ambiguous term in your domain keeps getting misclassified, add a one-line custom_instruction to exclude it.

Are fictional or historical names detected?

Yes. The model flags anything functioning as a person name in context, whether the person is real, historical, or fictional. If you want public or historical figures excluded — common in media and publishing pipelines — say so in custom_instruction and only private individuals will be returned.

Can I detect just first names or just last names?

PERSON_NAME returns the complete name span as it appears in text, whether that is a full name, a lone first name, or an initialed form. Given the diversity of global name structures, splitting spans into "first" and "last" components reliably is not possible in general — if your workflow needs partial masking, use the returned span and apply your own formatting to it.

How do I track one person across many mentions without keeping their name?

Use mask_mode: "hash". Identical names map to identical irreversible placeholders, so counts, threads, and relationships survive masking while the actual identity is removed. This is the standard pattern for analytics on anonymized support and chat data.

Start Detecting Names Today

Test the PERSON_NAME detector on your own text in the live demo, or grab an API key and integrate in minutes.

Try the Live Demo View Pricing