Sanitext

Redact PII from call and chat transcripts

Sanitext redacts PII from call and chat transcripts with one API call. Send the raw transcript from Deepgram, AssemblyAI, Whisper or your chat logs to POST /v1/redact. It returns the text with names, phones, emails, addresses and card numbers masked as [LABEL] before you store or QA it.

Voice and chat transcripts are full of personal data. Customers read out card numbers, spell their email, and confirm their home address. Before that text lands in your data warehouse, your QA tool, or an analytics dashboard, you can strip the PII. Sanitext does it in one request, on our own infrastructure, with no per-token cost.

Where Sanitext sits in a transcript pipeline

StageWhat you haveWhat Sanitext does
TranscriptionRaw text from Deepgram, AssemblyAI or WhisperNothing yet
Redaction stepRaw transcript or utterancePOST /v1/redact returns [LABEL]-masked text
Storage / warehouseMasked transcriptPII already removed before it lands
QA and analyticsMasked transcriptReviewers see redacted text, not card numbers
Detection-only pathNeed spans, not maskingPOST /v1/detect returns labels and byte offsets

Why are raw call and chat transcripts a PII problem?

Speech-to-text engines like Deepgram, AssemblyAI and Whisper transcribe everything that was said. So do live chat and support tools. That includes the parts you never wanted to keep: a caller reading their 16-digit card number, an agent repeating a phone number back, a customer giving their full name and street address.

Once that transcript is saved, the PII spreads. It gets copied into conversation-intelligence tools, training datasets, QA scorecards, BI dashboards and backups. Each copy is a new place a name or card number can leak. Contact centers handle thousands of these per day, so the data minimization problem scales fast.

Keeping raw transcripts also raises your exposure under GDPR and similar rules. The less identifying data you store, the smaller your risk surface. Redacting before storage is the cleanest point to cut it.

  • Card and account numbers spoken aloud during payment flows
  • Caller and agent names, including titles like Dr.
  • Phone numbers and email addresses repeated for confirmation
  • Postal addresses and dates of birth used for identity checks

What is the pattern for redacting a transcript?

The pattern is a single processing step between transcription and storage. Your speech-to-text or chat pipeline produces text, you pass that text to Sanitext POST /v1/redact, and you store the redacted version instead of the raw one.

Send the full transcript, or send it utterance by utterance if you process a live stream. Sanitext finds the spans, replaces each with its label, and returns the masked text plus an entities list with byte offsets and scores. You can store the masked transcript for analytics and keep raw audio under tighter access control, or drop the raw text entirely.

If you need the entity locations without changing the text, call POST /v1/detect instead. Same input, but you get back spans only, so you can highlight, route, or apply your own masking rules.

  • Transcribe with Deepgram, AssemblyAI, Whisper or your chat tool
  • Pass each transcript or utterance to /v1/redact
  • Store the [LABEL]-masked text, not the raw transcript
  • Use /v1/detect when you only need spans, not masking

Why does Sanitext fit contact-center and conversation-intelligence pipelines?

We own the open-weights model (Apache-2.0, from the OpenAI privacy-filter family) and run it on our own Cloudflare infrastructure. That means zero per-token AI cost, so pricing is flat and you can redact every transcript without watching a meter. Contact centers run high volume, so this matters.

Your transcript text never goes to a third-party LLM. We log counts and timings only, with no raw-text retention. Enterprise plans add EU data residency and a DPA. For conversation-intelligence vendors handling other companies' data, that subprocessor story is short and clean.

Detection covers 30+ languages and the labels you see most in calls: FIRSTNAME, LASTNAME, EMAIL, PHONE, ADDRESS, DATE, URL, ACCOUNT, SECRET and PREFIX. Short utterances come back in under a second.

Honest note: redaction is a data-minimization aid, not an anonymization or compliance guarantee. Spoken transcripts have errors and odd spellings, so verify recall against your own data and keep raw audio access controlled.

How do you integrate it with Deepgram, AssemblyAI or Whisper?

Sign up, copy your key from the dashboard, and call the API. Authenticate with a Bearer token (pf_live_...) on every request. The base path is /v1/redact for masked text and /v1/detect for spans.

Body is { "text": "...", "threshold": 0.5 }. Lower the threshold to catch more, raise it to cut false positives. The response gives you redacted text, the entities array, a count and an ms timing. Max request size is 1 MiB, so split very long transcripts into chunks or per-speaker turns. Going over your plan quota returns a 429.

For batch jobs, loop over finished transcripts after transcription. For live streams, redact each finalized utterance as it arrives. Either way it is a single function in your pipeline. On Scale and Enterprise, use the async bulk endpoint for large back-catalog jobs.

python

import os, requests

SANITEXT_KEY = os.environ["SANITEXT_KEY"]
BASE = "https://api.sanitext.app"

def redact_transcript(text: str, threshold: float = 0.5) -> dict:
    r = requests.post(
        f"{BASE}/v1/redact",
        headers={"Authorization": f"Bearer {SANITEXT_KEY}"},
        json={"text": text, "threshold": threshold},
        timeout=30,
    )
    r.raise_for_status()
    return r.json()

# Example: a Deepgram/Whisper transcript turn
utterance = (
    "Agent: Thanks Dr. Sarah Jones. I have your card ending "
    "4111 1111 1111 1111 and email sarah.jones@acme.com."
)

result = redact_transcript(utterance)
print(result["redacted"])
# Agent: Thanks [PREFIX] [FIRSTNAME] [LASTNAME]. I have your card
# ending [ACCOUNT] and email [EMAIL].
print(result["count"], "entities in", result["ms"], "ms")

# Store result["redacted"], not the raw utterance.
# For a full call, loop over finalized turns and join them.

FAQ

Can I redact transcripts from Deepgram, AssemblyAI or Whisper?+

Yes. Sanitext takes plain text, so it works with any speech-to-text engine. After transcription, send the text to POST /v1/redact and store the masked result. For live streams, redact each finalized utterance as it arrives.

Does Sanitext detect card and account numbers spoken in calls?+

Yes. It detects ACCOUNT (card and bank numbers), plus PHONE, EMAIL, ADDRESS, DATE, names and SECRET tokens. Spoken numbers can be transcribed oddly, so test recall on your own transcripts and tune the threshold.

Does my transcript data go to a third-party LLM?+

No. Sanitext runs an open-weights model on our own Cloudflare infrastructure. Your text never reaches a third-party LLM. We log counts and timings only, with no raw-text retention. Enterprise adds EU data residency and a DPA.

How much does it cost to redact high call volume?+

Pricing is flat by characters, not metered per token, because we own the model and pay no per-token AI cost. Hobby is $29/mo for 12M chars, Pro $149/mo for 120M, Scale $499/mo for 450M, with overage at $0.35 to $0.60 per 1M chars.

Is a redacted transcript fully anonymized?+

No. Redaction is a data-minimization aid, not an anonymization or compliance guarantee. It removes detected identifiers but can miss misspelled or unusual entities. Verify against your data and keep raw audio under access control.

Start redacting transcripts in 60 seconds

Sign up free for a one-time 300K characters, no card needed. Grab your API key and pipe your first Deepgram or Whisper transcript through /v1/redact. Try it live in the playground or read the docs.

Get your free API key