Quick Start¶
Prereqs: Python 3.9+ · Time to first call: ~30 seconds
Install, detect, mask, block. Six patterns; each one runs standalone.
Install¶
Optional extras: zotniq[openai] for the OpenAI drop-in wrapper,
zotniq[siem] for Splunk/Datadog/webhook forwarders, zotniq[all] for
everything.
1. Local-first — no key needed¶
from zotniq import Zotniq
client = Zotniq()
# Detect
findings = client.detect("Contact bob@example.com about SSN 123-45-6789")
for f in findings:
print(f.type, f.count)
# EMAIL 1
# SSN 1
# Mask
print(client.mask("SSN 123-45-6789"))
# SSN XXX-XX-6789
# Full preflight (decision + findings + masked_text)
result = client.preflight.check(
text="patient diagnosis and mrn on file",
destination="AI_TOOL",
mode="local",
)
print(result.decision) # Decision.BLOCKED
print(result.summary) # Blocked (PHI_KEYWORD).
What you should see¶
EMAIL 1andSSN 1on the detect pass.SSN XXX-XX-6789on the mask pass.Decision.BLOCKEDandBlocked (PHI_KEYWORD).on the preflight pass, because the text contains PHI keywords.
Zero network calls in this section. Everything runs in-process against the local detector.
2. Cloud-augmented — server LLM contextual pass¶
import os
from zotniq import Zotniq
# Reads ZOTNIQ_API_KEY env var
client = Zotniq(api_key=os.environ["ZOTNIQ_API_KEY"])
result = client.preflight.check(
text="Trade P&L for ODIN account 4123 was $2.3M yesterday",
destination="AI_TOOL",
)
print(result.decision) # Decision.BLOCKED (team's NLP rule caught IN_CLIENT_PII)
print(result.mode_used) # cloud
print(result.request_id) # req_srv_abc123 — correlates with server audit row
3. Per-call privacy override¶
# Cloud key set, but this specific payload stays local
result = client.preflight.check(
text=sensitive_prompt,
destination="AI_TOOL",
mode="local", # forces local — zero network calls
)
4. Drop-in OpenAI wrapper¶
from zotniq import Zotniq
from zotniq.integrations.openai import wrap_openai
openai_client = wrap_openai(Zotniq(api_key="zot_sk_..."), api_key="sk-...")
response = openai_client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "my ssn is 123-45-6789"}],
)
# SSN masked before OpenAI ever sees the prompt.
# On BLOCKED, returns a synthetic refusal — no OpenAI call made.
Install with pip install zotniq[openai].
5. SIEM forwarding¶
Every preflight decision emits an event to your SIEM (async, non-blocking, decision metadata only — never raw content).
from zotniq import Zotniq
from zotniq.siem import SplunkForwarder
client = Zotniq(
api_key="zot_sk_...",
on_decision=SplunkForwarder(
url="https://splunk.acme.com:8088/services/collector",
token="hec-token",
),
)
# Every preflight.check() call fires an async POST to Splunk.
result = client.preflight.check("...", destination="AI_TOOL")
Install with pip install zotniq[siem]. See SIEM forwarding for Datadog, webhook, file, and custom forwarders.
6. Async¶
from zotniq import AsyncZotniq
async with AsyncZotniq(api_key="zot_sk_...") as client:
result = await client.preflight.check(
text="my ssn is 123-45-6789",
destination="AI_TOOL",
)
Same API as Zotniq, awaitable calls.
What's next¶
- Cloud vs local modes — when to pick which
- SIEM forwarding — full guide
- OpenAI integration — deeper OpenAI patterns
- CLI —
zotniq check/zotniq maskfor shell workflows - API reference — every public symbol, auto-generated from docstrings