Skip to content

Getting Started

Protect sensitive data in your AI applications. This guide gets you from zero to PII-safe AI in under 5 minutes.


Prerequisites

  • Python 3.9 or higher

Step 1: Install the SDK

pip install zotniq

Or with optional dependencies:

pip install zotniq[openai]    # OpenAI drop-in wrapper
pip install zotniq[siem]      # Splunk / Datadog / webhook forwarders
pip install zotniq[all]       # Everything

Step 2: Initialize the SDK

from zotniq import Zotniq

# Local mode — no key, zero network calls
client = Zotniq()

# Cloud mode — reads ZOTNIQ_API_KEY env var, or pass explicitly
client = Zotniq(api_key="zot_sk_...")

No API key needed to start

Local mode runs the full detection and masking pipeline on your machine with zero network calls. Cloud mode adds server-side rules and audit trail. You can start local and add a key later.


Step 3: Process Content

Basic Processing

# Process text before sending to AI
result = client.preflight.check(
    text="Contact [email protected] or call 555-123-4567",
    destination="AI_TOOL"
)

print(f"Decision: {result.decision}")
print(f"Summary: {result.summary}")
print(f"Masked: {result.masked_text}")

Output:

Decision: Decision.ALLOWED_WITH_MASKING
Summary: Content allowed after masking EMAIL, PHONE
Masked: Contact j***@example.com or call XXX-XXX-4567

What's a destination?

destination tells Zotniq where the text is headed so it can pick the right rules. Three values:

  • AI_TOOL — any LLM (OpenAI, Anthropic, Gemini, local models)
  • VENDOR — third-party SaaS or API
  • CUSTOMER — outbound to your own customers

Rules change per destination. Sending an SSN to AI_TOOL masks; sending PHI to VENDOR blocks.

Detection Only

# Just detect sensitive data
detected = client.detect("Customer SSN: 123-45-6789")

for item in detected:
    print(f"  - {item.type}: {item.count} occurrence(s)")

Masking Only

# Just mask sensitive data
masked = client.mask("Email: [email protected]")
print(masked)  # Email: j***@example.com

Step 4: Handle Decisions

Decision Types

Decision Meaning Action
ALLOWED Content is safe Proceed with original
ALLOWED_WITH_MASKING PII was redacted Use result.masked_content
BLOCKED Content violates policy Do not send

BLOCKED is a hard stop

Never forward the original content when the decision is BLOCKED. The summary field explains which rule matched. Log it, surface it to the user, or route to a human reviewer.

Example Handler

from zotniq import Zotniq, Decision

client = Zotniq()

def send_to_ai(content: str) -> str:
    """Safely send content to AI with Zotniq protection."""
    result = client.preflight.check(content, destination="AI_TOOL")

    match result.decision:
        case Decision.BLOCKED:
            raise ValueError(f"Content blocked: {result.summary}")
        case Decision.ALLOWED_WITH_MASKING:
            return call_ai_api(result.masked_text)
        case Decision.ALLOWED:
            return call_ai_api(content)

Step 5: Use LLM Wrappers (Optional)

For the simplest integration, use a drop-in replacement client:

OpenAI

from zotniq import Zotniq
from zotniq.integrations.openai import wrap_openai

# Drop-in replacement — PII automatically masked before send
client = wrap_openai(Zotniq(), api_key="sk-...")

response = client.chat.completions.create(
    model="gpt-4",
    messages=[{
        "role": "user",
        "content": "Customer email: [email protected]"
    }]
)
# OpenAI only sees: "Customer email: j***@example.com"

See the OpenAI integration guide for the full pattern including BLOCKED handling.

Anthropic, LangChain, and MCP wrappers

Shipping in v0.2. Until then, call client.preflight.check(text, destination="AI_TOOL") and forward result.masked_text yourself.


Complete Example

from zotniq import Zotniq, Decision

client = Zotniq()

# Sample content with sensitive data
content = """
Customer Support Ticket #12345

Customer: Jane Doe
Email: [email protected]
Phone: (555) 123-4567
SSN: 987-65-4321

Issue: Unable to access account. Please reset password.
"""

# Process before sending to AI assistant
result = client.preflight.check(content, destination="AI_TOOL")

print(f"Decision: {result.decision}")
print(f"Summary: {result.summary}")
print()

if result.detected:
    print("Detected sensitive data:")
    for item in result.detected:
        print(f"  - {item.type}: {item.count} found")

if result.decision == Decision.ALLOWED_WITH_MASKING:
    print("\nMasked content:")
    print(result.masked_text)

Output:

Decision: Decision.ALLOWED_WITH_MASKING
Summary: Content allowed after masking EMAIL, PHONE, SSN

Detected sensitive data:
  - EMAIL: 1 found
  - PHONE: 1 found
  - SSN: 1 found

Masked content:
Customer Support Ticket #12345

Customer: Jane Doe
Email: j***@example.com
Phone: XXX-XXX-4567
SSN: XXX-XX-4321

Issue: Unable to access account. Please reset password.


CLI Quick Start

The SDK includes a command-line tool:

# Scan for PII
zotniq check "Contact [email protected]"

# Mask PII
zotniq mask "My SSN is 123-45-6789"

# Process with policy
zotniq check "Customer data here" -d AI_TOOL

# Check version
zotniq --version

Next Steps


Troubleshooting

Import Errors

ModuleNotFoundError: No module named "zotniq"

Solutions:

  1. Ensure you're in the correct virtual environment
  2. Reinstall: pip install --upgrade zotniq
  3. Check Python version: python --version (requires 3.9+)

License Validation Failed

LicenseValidationError: Invalid or expired license key

Solutions:

  1. Verify your license key is correct
  2. Check your internet connection
  3. Use basic mode without license: client = Zotniq()