Sanitext

PHI de-identification API for HIPAA Safe Harbor

Sanitext is a PHI de-identification API that flags HIPAA Safe Harbor identifiers in free text. POST text to /v1/detect or /v1/redact and it returns spans or masked output for names, dates, phones, emails, URLs, addresses, and account numbers in 30+ languages. It is a redaction aid, not Safe Harbor certification.

HIPAA Safe Harbor lists 18 identifier categories you must strip before health data counts as de-identified. Sanitext is a fast API that flags and masks most of them in free text, so your team reviews less and ships faster. It is an aid, not a compliance guarantee.

Sanitext labels mapped to HIPAA Safe Harbor identifiers

Safe Harbor identifierSanitext labelCoverage
NamesFIRSTNAME, LASTNAME, PREFIXCovered
All dates (birth, admission, etc.)DATECovered, review year-only rule
Telephone and fax numbersPHONECovered
Email addressesEMAILCovered
URLs and web handlesURLCovered
Street addresses and geo subdivisionsADDRESSCovered
Medical record / health plan numbersACCOUNTPartial, confirm type
SSN, certificate, account, device IDsACCOUNT, SECRETPartial, needs review
IP addresses(none)Out of scope
Full-face photos, biometric IDs(none)Out of scope
Any other unique identifier in prose(varies)Human review required

What is the problem with manual PHI de-identification?

Clinical notes, intake forms, and chat logs are full of protected health information. The HIPAA Safe Harbor method says you must remove 18 categories of identifiers before the data is treated as de-identified.

Doing this by hand does not scale. A nurse note can hide a patient name mid-sentence, a date of admission, a phone number, and a record ID all in one line. Miss one and the record is still PHI.

Most teams reach for a hyperscaler PII service, then watch the bill climb per token and worry about sending raw patient text to a third-party model. You need to find the identifiers first, at volume, without leaking the data to do it.

How does Sanitext map to the 18 Safe Harbor identifiers?

Sanitext returns typed spans with byte offsets and a confidence score. You can detect (get the spans) or redact (get text with each span masked as [LABEL]). It covers the free-text identifiers that are hardest to catch by rule alone.

The table below maps Sanitext labels to the Safe Harbor categories. Treat 'partial' and 'needs review' rows as a human-in-the-loop step, not a finished result. Some categories, like full-face photos, biometric data, and any 'other unique identifying characteristic', are out of scope for a text API and stay your responsibility.

  • Covered well: names (FIRSTNAME, LASTNAME, PREFIX), dates (DATE), phone and fax (PHONE), email (EMAIL), URLs and web handles (URL), street addresses (ADDRESS).
  • Partial / needs review: medical record numbers, health plan and account numbers, SSNs, certificate and device IDs all surface as ACCOUNT or SECRET, so you must confirm the type and that all elements of dates (not just year) are handled.
  • Out of scope: full-face photos, biometric identifiers, IP addresses tied to a person, and any residual free-text quasi-identifier a clinician wrote in prose.

Why does Sanitext fit healthcare workloads?

We own the open-weights detection model (Apache-2.0, from the OpenAI privacy-filter family) and run it on our own Cloudflare infrastructure. There is no per-token AI tax and your text never goes to a third-party LLM like OpenAI or Anthropic.

We do not retain raw text. We log counts and timings only, so the patient note you send is not stored on our side after the response. Pricing is flat by characters, not metered per token, which makes large batch jobs predictable.

Enterprise plans add EU data residency, a signed DPA, and a BAA conversation for covered entities and business associates. That is a starting point for a compliant pipeline, not a substitute for your own risk assessment.

How do I integrate it into a de-identification pipeline?

Sign up, copy your key (it starts with pf_live_), and call the API. Use /v1/detect when you want to log or review spans before masking, and /v1/redact when you want masked text in one step.

A safe pattern: run redact for the bulk pass, then route any span labeled ACCOUNT, SECRET, or DATE to a reviewer so a human confirms record numbers and full dates. Raise the threshold for precision or lower it for recall, and always validate against a sample of your real records before production.

Max request size is 1 MiB; split long documents and use the async bulk endpoint on Scale and Enterprise. Keep your own audit log of what was redacted so you can defend the de-identification decision later.

Is this HIPAA compliance?

No. Sanitext is a data-minimization and redaction aid. It helps you find and mask identifiers faster, but it does not by itself meet the HIPAA Safe Harbor standard or the Expert Determination method, and it does not make you compliant.

Safe Harbor requires that all 18 identifier types are removed and that you have no actual knowledge the remaining data could re-identify someone. That judgment, and any Expert Determination, is yours or your qualified expert's. Use Sanitext as the first high-recall pass, then apply human review and your own controls.

python

import os, requests

API = "https://privacy-filter-api.hi-892.workers.dev"
KEY = os.environ["SANITEXT_KEY"]  # starts with pf_live_

note = (
    "Patient John Carter, DOB 1971-04-22, MRN 884213, "
    "called from +1 415 555 0132 re: follow-up."
)

# 1) Bulk pass: get masked text in one call.
redact = requests.post(
    f"{API}/v1/redact",
    headers={"Authorization": f"Bearer {KEY}"},
    json={"text": note, "threshold": 0.5},
    timeout=30,
).json()
print(redact["redacted"])
# Patient [FIRSTNAME] [LASTNAME], DOB [DATE], MRN [ACCOUNT],
# called from [PHONE] re: follow-up.

# 2) Route the risky labels to a human reviewer.
NEEDS_REVIEW = {"ACCOUNT", "SECRET", "DATE"}
for e in redact["entities"]:
    if e["label"] in NEEDS_REVIEW:
        print("review:", e["label"], repr(e["text"]), e["score"])

# Sanitext is a redaction aid, not HIPAA Safe Harbor certification.
# Confirm all 18 identifier categories are handled before release.

FAQ

Does Sanitext make my data HIPAA compliant?+

No. Sanitext is a PHI redaction aid that flags identifiers in text. It speeds up de-identification but does not by itself satisfy HIPAA Safe Harbor or the Expert Determination method. You still own the final review, your controls, and any expert sign-off.

Which HIPAA Safe Harbor identifiers does it detect?+

It detects names, dates, phone and fax numbers, emails, URLs, and street addresses directly, and surfaces medical record, account, SSN, device, and certificate numbers as ACCOUNT or SECRET for review. Full-face photos, biometrics, and IP addresses are out of scope for a text API.

Is patient text sent to a third-party LLM?+

No. Sanitext runs an open-weights model on our own Cloudflare infrastructure, so text never goes to OpenAI, Anthropic, or any external LLM. We do not retain raw text either; we log only counts and timings, and Enterprise adds EU data residency.

Can I get a BAA for healthcare use?+

A BAA and signed DPA are part of the Enterprise conversation for covered entities and business associates, along with EU data residency, SLA, and custom retention. Contact us through the Enterprise plan to scope the agreement before sending production PHI.

How should I handle dates and record numbers?+

Treat them as human-in-the-loop. Sanitext flags DATE spans and surfaces record or account numbers as ACCOUNT or SECRET, but Safe Harbor requires removing all date elements except year and confirming each ID type. Route those labels to a reviewer before release.

Start de-identifying PHI in 60 seconds

Get 300K characters free, no card. Sign up, grab an API key, and run your first /v1/redact call. Need a BAA, EU residency, or a DPA? Talk to us about Enterprise.

Get your free API key