Sanitext

Sanitize prompts before they hit your LLM

LLM prompt sanitization strips PII from user prompts and tool inputs before they reach a model. Sanitext sits in front of your gateway, calls POST /v1/detect or /v1/redact to mask names, emails, phones, and secrets, then optionally restores values after inference. It runs on our own infra with zero per-token AI cost.

Every prompt your users send may carry names, emails, phone numbers, or API keys. Once that text reaches a third-party model, you have lost control of it. A sanitization layer fixes this: detect PII, mask it, send the clean prompt, then restore the values when the answer comes back.

Why do prompts need sanitization?

User prompts are messy. People paste support emails, contracts, logs, and chat history straight into a box. That text often holds personal data: a customer name, a phone number, a home address, sometimes an API key or token.

When you forward that prompt to a hosted model, the data leaves your boundary. It can be logged by the provider, used in ways your DPA does not cover, or leak through a downstream tool call. For agents that chain many model calls, the surface area is even larger because each tool input is another place raw PII can escape.

Sanitization means you remove or mask that data before the prompt travels. You keep the meaning the model needs while dropping the identifiers it does not need. This is data minimization applied to your AI pipeline.

What is the mask, infer, restore pattern?

The core pattern is three steps. First, mask: run the prompt through detection and replace each PII span with a placeholder token. Second, infer: send the masked prompt to your model or agent. Third, restore: swap the placeholders back to the real values in the model output, if you need them.

Sanitext supports this with two endpoints. POST /v1/detect returns entity spans with a label (FIRSTNAME, LASTNAME, EMAIL, PHONE, ADDRESS, DATE, URL, ACCOUNT, SECRET, PREFIX), byte offsets, a score, and the matched text. You build a placeholder map from those spans. POST /v1/redact returns the same text with each span already masked as [LABEL], which is the fast path when you do not need to restore.

For reversible masking, keep the map in your own memory or store for the duration of the request. The masked prompt is what goes to the model. After inference, you replace any returned placeholders with the saved values. The model never sees the real PII, and your user still gets a complete answer.

Why does Sanitext fit AI gateways and agents?

Sanitext is built to be a preprocessing layer, not another model in your stack. It is a single HTTP call you put in front of your gateway or agent loop.

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 on our side, so pricing is flat and transparent instead of metered like a hyperscaler. Your prompt data never passes through a third-party LLM to get sanitized.

We do not retain raw text. We log counts and timings only. Enterprise plans add EU data residency and a DPA. Detection works across 30+ languages, so a multilingual agent gets the same coverage without you wiring up per-language rules.

  • Zero per-token AI cost on our side, so you pay a flat fee, not metered overage to a hyperscaler
  • No raw-text retention: we log only counts and timings
  • 30+ languages covered by one model and one endpoint
  • EU data residency and DPA available on Enterprise
  • Sub-call latency low enough to sit in a live request path

How do you integrate it?

Put the sanitize call between your input handler and your model call. For a simple chatbot, redact the user message before it goes to the model. For an agent, redact each tool input and the system-assembled context, not just the first user turn.

Use /v1/redact when you only need clean text downstream and never have to show the real value again, for example logging or analytics prompts. Use /v1/detect when you need the reversible map so you can restore values in the final answer to the user.

Decide which labels matter for your case. You may want to mask EMAIL, PHONE, ADDRESS, and SECRET but keep DATE if the model needs it for reasoning. The span labels let you filter precisely. Self-serve setup is fast: sign up, add a card through Stripe, get an API key, and you are running curl in about 60 seconds.

One honest note. Sanitization is a redaction and data-minimization aid, not an anonymization or compliance guarantee. No detector catches every identifier in every phrasing. Treat it as a strong control in a layered approach, and keep human review for high-risk flows.

python

import re
import requests

API = "https://api.sanitext.app/v1"
HEADERS = {"Authorization": "Bearer pf_live_..."}

def mask(text):
    # 1) detect PII spans
    spans = requests.post(
        f"{API}/detect",
        headers=HEADERS,
        json={"text": text},
    ).json()["entities"]

    # 2) build a reversible placeholder map, replacing from the end
    #    so earlier byte offsets stay valid
    restore = {}
    masked = text
    for i, s in enumerate(sorted(spans, key=lambda x: x["start"], reverse=True)):
        token = f"[{s['label']}_{i}]"
        restore[token] = s["text"]
        masked = masked[: s["start"]] + token + masked[s["end"] :]
    return masked, restore

def restore_values(text, restore):
    for token, value in restore.items():
        text = text.replace(token, value)
    return text

# --- mask -> infer -> restore ---
user_prompt = "Email john.doe@acme.com about order 4471, call +34 600 123 456."
masked_prompt, restore_map = mask(user_prompt)

# masked_prompt now reads:
# "Email [EMAIL_0] about order [ACCOUNT_1], call [PHONE_2]."
model_reply = your_llm.generate(masked_prompt)  # real PII never leaves

final = restore_values(model_reply, restore_map)
print(final)

FAQ

What is LLM prompt sanitization?+

It is the practice of detecting and removing or masking personal data in a prompt before sending it to a language model. Names, emails, phone numbers, addresses, and secrets are replaced with placeholders, so the model gets the context it needs without the raw identifiers.

Can I get the original values back after the model responds?+

Yes. Use POST /v1/detect to get spans, build a placeholder map keyed by your own tokens, and keep that map for the request. Send the masked prompt to the model, then swap placeholders back to real values in the output. The model never sees the real PII.

Does sanitizing prompts make my AI pipeline compliant?+

No. Sanitext is a redaction and data-minimization aid, not an anonymization or compliance guarantee. It reduces exposure and supports GDPR, HIPAA, and similar goals, but no detector catches every identifier. Keep human review and other controls for high-risk flows.

Will adding a sanitization layer slow down my agent?+

It adds one HTTP call before each model or tool call. We run the model on our own Cloudflare infrastructure for low latency, so it is built to sit in a live request path. You can also redact in parallel with other setup steps to hide the cost.

Does my prompt text get sent to a third-party LLM to sanitize?+

No. Sanitext uses our own open-weights model on our own infrastructure. Your text is processed in-house, not forwarded to a hosted LLM. We do not retain raw text, and Enterprise adds EU data residency and a DPA.

Put a privacy layer in front of your model

Sign up free, get 300K characters with no card, and add prompt sanitization in about 60 seconds. Mask PII, send the clean prompt, restore values after inference.

Get your free API key