Engineering Workspace
Privacy & PII de-identification
Detect and de-identify personal data in text before it reaches a model or leaves your boundary. The text path runs locally on CPU, regex and checksum recognizers, no model weights and no GPU.
Overview
HybrIE exposes its privacy primitives as three endpoints, reachable from the Stimulir Python SDK and the stimulir CLI. The text path uses built-in regex and checksum recognizers (email, phone, SSN, IBAN, credit-card via Luhn, API keys, JWT, and more), it is pure CPU, loads no model, and needs no GPU.
De-identify never echoes raw PII. deidentify returns only the redacted text, a redaction count, and the distinct entity-type labels detected, never the matched values. Use extract when you explicitly want the spans and their text.
Endpoints
/v1/privacy/deidentify/v1/privacy/extract/v1/privacy/capabilitiesThrough the SDK (api-key plane) these are served at /api/v1/privacy/*; the CLI reaches them via the console proxy at /api/v1/hybrie/privacy/*. Either way the work runs on the HybrIE runtime, you only hold an hyb_* key.
Anonymization methods
deidentify takes a method (applied to every detected entity) and optional per-entity-type overrides. A method is a string kind, or an object with parameters.
| Parameter | Type | Description |
|---|---|---|
replace | placeholder? | Replace with a placeholder; defaults to the typed token (<EMAIL>, <IBAN>, …). |
redact | n/a | Drop the span entirely. |
mask | mask_char, keep_tail | Mask each character, keeping the last keep_tail characters visible. |
hash_sha256 / hash_sha512 | salt? (base64) | Replace with a hex digest; stable for the same input + salt. |
encrypt / decrypt | key (base64) | AES-256-GCM with a 16/24/32-byte key. Treat keys as secrets, never log them. |
keep | n/a | Leave the original text unchanged (Presidio-style passthrough). |
replace_consistent | template? | Stable numbered placeholder per value, e.g. <EMAIL_1>, <EMAIL_2>. |
Python SDK
from stimulir import StimulirClient
client = StimulirClient() # reads STIMULIR_API_KEY (hyb_*)
# Redact every detected entity with its typed placeholder
result = client.privacy.deidentify("Email me at sarah.johnson@example.com")
print(result["text"]) # "Email me at <EMAIL>"
print(result["redactions"]) # 1
print(result["entity_types"]) # ["email"]
# Pick a default method, override per entity type
client.privacy.deidentify(
"card 4111 1111 1111 1111, reach me at a@b.com",
method="redact",
overrides={"email": {"kind": "mask", "mask_char": "*", "keep_tail": 4}},
)
# Detect without de-identifying (returns the full entity list)
entities = client.privacy.extract("SSN 123-45-6789 on file")
# What the runtime supports (methods + recognizer count)
client.privacy.capabilities()Per-entity-type overrides
Keys are entity types in snake_case (email, phone_number,iban, credit_debit_card, …); any type not in overrides falls through to the top-level method.
CLI
# De-identify (default method is replace)
stimulir privacy deidentify --text "Email me at sarah.johnson@example.com"
# Mask, keeping the last 4 characters
stimulir privacy deidentify --text "card 4111 1111 1111 1111" \
--method mask --mask-char "*" --keep-tail 4
# Detect PII entities (table, or --json)
stimulir privacy extract --text "SSN 123-45-6789 on file"
# Supported methods + recognizer count
stimulir privacy capabilitiesNeed the SDK or CLI? See Python SDK and CLI Installation.