Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.zeroeval.com/llms.txt

Use this file to discover all available pages before exploring further.

ZeroEval supports opt-in source-side PII redaction in the Python and TypeScript SDKs. When enabled, sensitive values in ingested payload fields (input_data and output_data) are redacted before spans are sent by the SDK.
This is an SDK-side feature. ZeroEval does not rely on backend-side redaction for this behavior.

Enable redaction

import zeroeval as ze

ze.init(
    api_key="YOUR_API_KEY",
    redaction={"enabled": True},
)
You can also enable the default redaction toggle with:
export ZEROEVAL_REDACT_PII=true
Python uses snake_case nested keys such as redact_inputs, sensitive_keys, and custom_patterns. TypeScript uses the camelCase equivalents redactInputs, sensitiveKeys, and customPatterns.

What gets redacted

Redaction applies to ingested payload fields only:
  • input_data (the value passed to setIO / set_io)
  • output_data (the value passed to setIO / set_io)
When wrapper integrations (OpenAI, Vercel AI, LangChain) serialize prompts and tool arguments into these IO fields, those values are also redacted. Built-in detectors cover:
  • email addresses
  • phone numbers
  • SSN-style identifiers
  • PAN / credit card numbers
  • bearer tokens, JWTs, and common API key formats
  • cookie and authorization header values
  • IP addresses
Key-based detection force-redacts common sensitive fields such as email, phone, password, token, authorization, cookie, and api_key / apiKey when they appear inside ingested IO payloads.

What stays intact

All span metadata outside of input_data and output_data is preserved unchanged:
  • span names
  • trace IDs and span IDs
  • timing and status fields
  • attributes
  • tags, trace tags, and session tags
  • session identifiers and session names
  • error messages and stacks
  • token counts, model/provider metadata, and cost metadata

Placeholder behavior

Sensitive values are replaced with stable placeholders inside a single trace:
[email protected] -> [REDACTED_EMAIL_A]
[email protected]   -> [REDACTED_EMAIL_B]
[email protected] -> [REDACTED_EMAIL_A]
  • the same normalized sensitive value in one trace gets the same placeholder
  • different values in the same trace get different placeholders
  • placeholder assignment resets per trace
  • matching is exact after normalization only
  • this is not fuzzy identity resolution
That means repeated references across parent and child spans stay joinable without preserving the original value.

Normalization and limitations

TypeNormalization used for placeholder reuse
EmailTrim + lowercase
PhoneDigits only
SSN / PANDigits only
IPCanonical or lowercase string as implemented by each SDK
SecretsExact trimmed string
Important limitations:
  • there is no reversible backend token vault
  • there is no de-anonymization support
  • there is no fuzzy entity resolution across semantically related strings
  • bypassing SDK capture paths bypasses this protection

Examples

The SDK repositories include runnable examples. In both examples, only the values passed to set_io / setIO are redacted. Session metadata, tags, attributes, and error messages are sent unchanged.
From zeroeval-sdk/examples/pii_redaction.py:
import zeroeval as ze

ze.init(
    api_key="sk_ze_demo_local",
    redaction={"enabled": True},
)

with ze.span(
    name="pii-redaction-demo",
    session={"id": "[email protected]", "name": "Alice [email protected]"},
    tags={"customer_email": "[email protected]"},
) as span:
    span.set_io(
        input_data={"email": "[email protected]", "phone": "+1 (415) 555-1234"},
        output_data={"result": "Reach [email protected]"},
    )
In the resulting span:
  • input_data.email becomes [REDACTED_EMAIL_A]
  • input_data.phone becomes [REDACTED_PHONE_A]
  • output_data.result contains [REDACTED_EMAIL_A]
  • session_id, session_name, and tags.customer_email stay as-is
Repeated exact values such as the same email address reuse the same placeholder within a trace.