Citadelis Logo

Citadelis

/API Docs/Anonymization
Back to Documentation

PII Anonymization

Protect sensitive data with automatic PII detection and anonymization. Perfect for GDPR compliance and privacy-first applications.

How It Works

1

Detect

Your text is analyzed to detect PII like emails, phones, names, etc.

2

Replace

PII is replaced with tokens like {{EMAIL_1}}, {{PHONE_1}}

3

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 78

After (anonymized)

Contact {{EMAIL_1}} or call {{PHONE_1}}

Supported PII Types

TypeToken FormatExamples
Email{{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