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¶
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 john@example.com 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 APICUSTOMER— 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: john@example.com")
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: john@example.com"
}]
)
# 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: jane.doe@example.com
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 john@example.com"
# 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¶
- SDK Installation - Detailed installation options
- SDK Quick Start - More examples and use cases
- API Reference - Full SDK documentation
- CLI Reference - Command-line tool usage
- LLM Integrations - OpenAI, Anthropic, LangChain
Troubleshooting¶
Import Errors¶
Solutions:
- Ensure you're in the correct virtual environment
- Reinstall:
pip install --upgrade zotniq - Check Python version:
python --version(requires 3.9+)
License Validation Failed¶
Solutions:
- Verify your license key is correct
- Check your internet connection
- Use basic mode without license:
client = Zotniq()