Skip to main content
Zespan’s PII redaction feature automatically removes sensitive values from event metadata before they leave your application. When redaction is enabled, any tag or metadata field whose key matches a configured list has its value replaced with "[REDACTED]" — the key is preserved so you can still see which field contained sensitive data, but the value never reaches Zespan servers.
PII redaction applies to tags, metadata, and stored prompt and completion text. Prompt storage is on by default — set storePrompts: false to disable it.

Default redacted keys

The SDK ships with a default list of keys that are always redacted, regardless of configuration:
password, secret, token, api_key, apikey, auth, authorization,
access_token, refresh_token, private_key, credential, ssn,
social_security, credit_card, card_number, cvv
These defaults are applied even if you do not configure redactKeys explicitly.

Adding custom keys

Pass additional key names in the redactKeys array at initialization. These are merged with the default list.
import { zespan } from "@zespan/sdk";

zespan.init({
  apiKey: process.env.ZESPAN_API_KEY!,
  redactKeys: ["email", "phone", "address", "ip_address", "dob"],
});
With this configuration, if your application sends a trace with tags: { email: "user@example.com" }, the SDK will transmit tags: { email: "[REDACTED]" } instead.

How matching works

Matching is case-insensitive and checks both exact key names and common nested-key patterns:
  • "password" matches password, Password, PASSWORD
  • "api_key" matches api_key, apiKey, API_KEY
Matching is applied to the flat key names in tags and metadata objects. Nested objects are flattened one level deep before matching.

Replacing the default key list

To use only your own list — completely replacing the defaults — set replaceDefaultRedactKeys: true:
zespan.init({
  apiKey: process.env.ZESPAN_API_KEY!,
  redactKeys: ["ssn", "account_number"],
  replaceDefaultRedactKeys: true,
});
Replacing the defaults removes protection for common sensitive field names like password and token. Only do this if you are confident your custom list covers all sensitive fields your application may produce.

Example: verifying redaction

The following example shows how redaction behaves at runtime. The email and phone fields are replaced; feature and plan pass through unchanged.
import { zespan, withLumiqtraceContext } from "@zespan/sdk";
import OpenAI from "openai";

zespan.init({
  apiKey: process.env.ZESPAN_API_KEY!,
  redactKeys: ["email", "phone"],
  debug: true, // logs redacted events to console during testing
});

const openai = zespan.wrapOpenAI(new OpenAI());

await withLumiqtraceContext(
  {
    userId: "user_123",
    tags: {
      email: "alice@example.com",   // will be redacted → "[REDACTED]"
      phone: "+1-555-0100",         // will be redacted → "[REDACTED]"
      feature: "chat",              // passes through
      plan: "pro",                  // passes through
    },
  },
  async () => {
    await openai.chat.completions.create({
      model: "gpt-4o",
      messages: [{ role: "user", content: "Hello" }],
    });
  }
);

Redaction and storePrompts

PII redaction applies to both structured fields and stored prompt text:
SettingWhat is protected
redactKeysValues in tags, metadata, and stored prompt/completion text
storePrompts: true (default)Prompt and completion text stored — PII redaction applied before transmission
storePrompts: falsePrompt and completion text never sent at all
The SDK runs redactKeys patterns against prompt and completion content before transmitting. Matched values are replaced with [REDACTED].
Configure redactKeys to cover any sensitive patterns your application produces — email addresses, phone numbers, account IDs — so they are scrubbed from stored prompts automatically.