PII Anonymization
Protect sensitive data with automatic PII detection and anonymization. Perfect for GDPR compliance and privacy-first applications.
How It Works
Detect
Your text is analyzed to detect PII like emails, phones, names, etc.
Replace
PII is replaced with tokens like {{EMAIL_1}}, {{PHONE_1}}
Restore
After LLM processing, tokens are replaced back with original values
Before (with PII)
Contact john.doe@email.com or call +33 6 12 34 56 78After (anonymized)
Contact {{EMAIL_1}} or call {{PHONE_1}}Supported PII Types
| Type | Token Format | Examples |
|---|---|---|
| {{EMAIL_1}} | john@example.com | |
| Phone | {{PHONE_1}} | +33 6 12 34 56 78 |
| IBAN | {{IBAN_1}} | FR76 1234 5678 9012 3456 7890 123 |
| Credit Card | {{CREDIT_CARD_1}} | 4111 1111 1111 1111 |
| French SSN | {{SSN_FRENCH_1}} | 1 85 12 75 108 123 45 |
| Address | {{ADDRESS_1}} | 123 rue de la Paix |
| Date | {{DATE_1}} | 15/03/1990 |
| Age | {{AGE_1}} | 35 ans |
| API Key | {{API_KEY_1}} | sk_live_abc123xyz |
Usage Examples
1. Simple Anonymization
Just anonymize text without LLM processing:
import requests
response = requests.post(
"https://citadelis.eu/api/v1/anonymize",
headers={"Authorization": "Bearer citadel_sk_xxx"},
json={
"text": "Contact john@example.com about order #12345"
}
)
result = response.json()
print(result["anonymized_text"])
# Output: "Contact {{EMAIL_1}} about order #12345"
print(result["mapping"])
# Output: {"{{EMAIL_1}}": "john@example.com"}2. Chat Completions with Anonymization
Anonymize before sending to LLM, then deanonymize the response:
from openai import OpenAI
client = OpenAI(
base_url="https://citadelis.eu/api/v1",
api_key="citadel_sk_xxx"
)
# The anonymize option handles everything automatically
response = client.chat.completions.create(
model="Meta-Llama-3_3-70B-Instruct",
messages=[
{
"role": "user",
"content": "Write a follow-up email to john@example.com about the meeting"
}
],
extra_body={"anonymize": True}
)
# Access the original content (with {{EMAIL_1}} tokens)
raw_response = response.choices[0].message.content
# Access the deanonymized content (with real email restored)
deanonymized = response.citadelis.anonymization.deanonymized_content
# Access the mapping for your own processing
mapping = response.citadelis.anonymization.mapping
# {"{{EMAIL_1}}": "john@example.com"}3. Full Pipeline with /v1/anonymize
Use the dedicated anonymization endpoint for more control:
import requests
# Step 1: Anonymize and process with LLM in one call
response = requests.post(
"https://citadelis.eu/api/v1/anonymize",
headers={"Authorization": "Bearer citadel_sk_xxx"},
json={
"text": "Draft a contract for John Doe, email john@company.com, at 123 Main Street",
"process_with_llm": True,
"model": "Meta-Llama-3_3-70B-Instruct",
"system_prompt": "You are a legal assistant. Draft professional contracts."
}
)
result = response.json()
# Get all the pieces:
print("Anonymized Input:", result["anonymized_text"])
print("PII Types Found:", result["pii_types"])
print("Mapping:", result["mapping"])
print("LLM Response (raw):", result["llm_response"]["raw_content"])
print("LLM Response (deanonymized):", result["llm_response"]["deanonymized_content"])4. Manual Restore
Restore anonymized text later using the mapping:
import requests
# If you stored the mapping and need to restore later
response = requests.put(
"https://citadelis.eu/api/v1/anonymize",
headers={"Authorization": "Bearer citadel_sk_xxx"},
json={
"text": "Dear {{NAME_1}}, please confirm your email {{EMAIL_1}}",
"mapping": {
"{{NAME_1}}": "John Doe",
"{{EMAIL_1}}": "john@example.com"
}
}
)
result = response.json()
print(result["restored_text"])
# Output: "Dear John Doe, please confirm your email john@example.com"Privacy Guarantees
No Data Storage
We never store the content of your requests or responses. Only usage metrics are recorded.
EU Data Residency
Open-source models run on servers in France. Your data never leaves the EU.
Mapping Stays Client-Side
The token-to-value mapping is returned to you. Store it securely in your system if needed.
Best Practices
1. Use EU Models for Sensitive Data
For maximum privacy, use EU-hosted models (Llama, Mistral, Qwen) which process data entirely within France.
2. Extend Existing Mappings
When processing multiple messages in a conversation, pass the existing mapping to maintain consistent tokens.
3. Store Mappings Securely
If you need to restore data later, store the mapping encrypted. The mapping contains the original PII values.
Limitations
Anonymization uses pattern matching and may not detect all PII. Names without context (like "John" alone) may not be detected. Always review outputs for sensitive applications.
Try It Now
Test the anonymization feature in our interactive playground.
Open Playground