Redact PII From Support Tickets
Sanitext detects and masks customer PII in support tickets with one API call. POST ticket text to /v1/redact and get back clean text with names, emails, phones, and addresses replaced by labels like [EMAIL]. It runs on our own model, so per-ticket cost stays flat and raw text never goes to a third-party LLM.
Support inboxes collect customer PII by the thread: names, emails, phones, addresses, order and card numbers. This page shows how to strip that data from Zendesk, Intercom, or Help Scout tickets before it reaches analytics, training data, or vendors, using one Sanitext API call in bulk or inline.
Bulk vs inline ticket redaction
| Approach | When it runs | Best for | Endpoint |
|---|---|---|---|
| Bulk job | Nightly or one-time backfill | Analytics exports, training sets, archives | /v1/redact |
| Inline webhook | On ticket created or updated | Real-time masking before storage | /v1/redact |
| Detect only | On demand for review | Highlighting or auditing found PII | /v1/detect |
What problem do support tickets create?
Support tickets are full of customer PII. People paste their full name, email, phone number, home address, order numbers, and sometimes card digits or account secrets right into the message. A single ticket thread can hold all of it.
That PII sits in Zendesk, Intercom, or Help Scout, and then it leaks out the side doors. You export tickets into a data warehouse for analytics. You fine-tune a support model on past conversations. You send a sample to a BPO or a tooling vendor. Each path moves raw customer data somewhere it does not belong.
Doing this by hand does not scale. Regex catches emails but misses names and addresses. Asking agents to scrub tickets is slow and they forget. You need an automatic step that runs on every ticket before it leaves the help desk.
- —Analytics and BI exports that should not carry names or emails
- —Training data for support copilots and reply suggestions
- —Sharing samples with outsourced teams or third-party vendors
- —Backups and long-term archives that retain raw customer text
What is the pattern for redacting tickets?
The pattern is a redaction step between the help desk and wherever the text is going. You pull ticket text, send it to Sanitext, and store or forward the masked version instead of the raw one.
Two modes cover most needs. Bulk: run a nightly or backfill job that reads tickets from the Zendesk, Intercom, or Help Scout API, redacts each one, and writes clean text to your warehouse or training set. Inline: redact in real time inside a webhook or middleware as tickets are created or updated, so the masked copy exists from the start.
Use /v1/detect when you need the entity spans (label, byte offsets, score, matched text) to highlight or review what was found. Use /v1/redact when you just want clean text back with each match swapped for [LABEL] like [FIRSTNAME], [EMAIL], or [PHONE].
Why does Sanitext fit ticket redaction?
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 predictable instead of metered per ticket. A spiky support week does not spike your bill.
Your ticket text never goes to a third-party LLM. We log counts and timings only, not raw text, so there is no retained copy of your customers' messages on our side. Enterprise plans add EU data residency and a DPA.
Detection covers 30+ languages, which matters for support inboxes that handle multiple regions. It catches first and last names, emails, phone numbers, postal addresses, dates, URLs, account and card numbers, and secrets like API keys or tokens that customers paste into bug reports.
- —Flat pricing: Hobby $29/mo (12M chars), Pro $149/mo (120M), Scale $499/mo (450M)
- —Overage $0.35-0.60 per 1M chars, up to about 2x cheaper than AWS or Azure
- —No raw-text retention; counts and timings only
- —Multilingual detection for global support inboxes
How do you integrate it with a help desk?
For bulk backfill, page through the help desk API, batch the ticket bodies, and call /v1/redact for each. Store the masked text in your warehouse table or training file and keep the original only inside the help desk where access is already controlled.
For inline redaction, register a webhook on ticket created or updated, redact the body in your handler, and write the masked version to the destination system. Keep your API key server-side in an environment variable.
Run redaction on every text field that can hold PII: subject, body, internal notes, and custom fields. Customers put PII in odd places, so do not redact the body alone and call it done.
Is redaction the same as compliance?
No. Sanitext is a redaction and data-minimization aid, not an anonymization or compliance guarantee. It removes the obvious direct identifiers it detects, which sharply lowers exposure, but it does not by itself make text anonymous or compliant under GDPR, HIPAA, or any other rule.
Models miss things and rare formats slip through. For high-risk uses like sharing data externally or training models, keep a review step, set access controls, and treat redaction as one layer of a broader program rather than the whole answer.
python
import os
import requests
SANITEXT_KEY = os.environ["SANITEXT_API_KEY"]
ZENDESK_TOKEN = os.environ["ZENDESK_TOKEN"]
ZENDESK_DOMAIN = "yourco.zendesk.com"
def redact(text: str) -> str:
resp = requests.post(
"https://api.sanitext.app/v1/redact",
headers={"Authorization": f"Bearer {SANITEXT_KEY}"},
json={"text": text},
timeout=30,
)
resp.raise_for_status()
return resp.json()["text"]
def fetch_tickets(page_url: str):
# Page through the Zendesk Tickets API
while page_url:
r = requests.get(page_url, auth=("email/token", ZENDESK_TOKEN), timeout=30)
r.raise_for_status()
data = r.json()
yield from data["tickets"]
page_url = data.get("next_page")
start = f"https://{ZENDESK_DOMAIN}/api/v2/tickets.json"
for ticket in fetch_tickets(start):
clean_subject = redact(ticket.get("subject") or "")
clean_body = redact(ticket.get("description") or "")
# 'Hi, I'm Maria Lopez (maria@gmail.com), order 88421...'
# -> 'Hi, I'm [FIRSTNAME] [LASTNAME] ([EMAIL]), order [ACCOUNT]...'
warehouse_write(
ticket_id=ticket["id"],
subject=clean_subject,
body=clean_body,
) FAQ
Can I redact tickets in bulk and in real time?+
Yes. For bulk, page through your help desk API and call /v1/redact on each ticket in a backfill or nightly job. For inline, redact the body inside a ticket-created webhook so only the masked copy is stored downstream. Both use the same endpoint.
Does my ticket text get sent to a third-party LLM?+
No. Sanitext runs an open-weights model on our own Cloudflare infrastructure, so your text never goes to an outside LLM provider. We log counts and timings only, never raw text. Enterprise plans add EU data residency and a DPA.
Which PII does it find in tickets?+
It detects first and last names, emails, phone numbers, postal addresses, dates, URLs, account and card numbers, and secrets like API keys or tokens. Detection works across 30+ languages, which helps support inboxes that handle multiple regions.
Does redacting tickets make my data GDPR or HIPAA compliant?+
No. Sanitext is a redaction and data-minimization aid, not an anonymization or compliance guarantee. It lowers exposure by masking detected identifiers, but models can miss things. Keep review steps and access controls for high-risk uses like vendor sharing or model training.
How is pricing handled for high ticket volume?+
Pricing is flat by characters, not metered per token, because we run our own model at zero per-token AI cost. Plans run from Hobby $29/mo (12M chars) to Scale $499/mo (450M chars), with overage at $0.35-0.60 per 1M chars.
Clean tickets in 60 seconds
Sign up free, get an API key, and redact your first support tickets with one curl. 300K characters free, no card. Try it in the playground or read the docs.
Get your free API key