Cloud vs local¶
The SDK runs preflight in one of three modes. Understanding when to pick each is the single most important design call you'll make with Zotniq.
Mode resolution¶
client.preflight.check(text, destination, mode="auto") resolves as follows:
mode= |
client.api_key |
Result |
|---|---|---|
"auto" (default) |
set | cloud |
"auto" |
unset | local |
"local" |
any | local (never calls server) |
"cloud" |
set | cloud |
"cloud" |
unset | raises AuthError immediately |
"cloud_with_fallback" |
set | cloud first, local on NetworkError |
"cloud_with_fallback" |
unset | raises AuthError |
What each mode does¶
local¶
- Regex + Luhn/IBAN/SSN validators + PHI keyword matching
- Runs entirely in your process
- Zero network calls, zero telemetry, zero cost
- Detection surface is bounded: EMAIL, PHONE, SSN, CREDIT_CARD, API_SECRET, IBAN, PHI_KEYWORD, ADDRESS (patterns only, no context)
- Decision logic: PHI blocks, PII masks, clean passes
Right for: offline apps, air-gapped environments, dev/staging without a key, privacy-sensitive payloads you don't want in Zotniq's audit trail.
cloud¶
- POSTs
{text, destination}tohttps://api.zotniq.ai/v1/preflight/text - Server runs regex + LLM contextual pass (Team NLP rules)
- Catches ADDRESS, NAME, custom team-declared kinds (e.g.
AIR_TAIL_REG,IN_CLIENT_PII) that regex misses - Server writes decision metadata to
preflight_audit. The raw text is never persisted (original_previewis always NULL);masked_previewfollows the org'sretention_mode(FULLkeeps it,METADATAnulls it) - Response echoes
x-request-idfor cross-correlation with your Zotniq dashboard
Right for: production apps where you want the full detection surface, teams that want dashboard visibility, customers with contextual/organization-specific rules.
cloud_with_fallback¶
- Tries cloud first
- On
NetworkError(5xx, timeout, DNS failure), silently falls back tolocal - On
AuthError/ValidationError, raises — those aren't network problems
Right for: production apps where you want cloud's detection surface but can't tolerate an outage cascading into your critical path. Trade-off: some events will only have local-quality findings.
Privacy invariants¶
Under mode="local":
- No network activity. Verifiable with tcpdump.
- No content, decision, or finding leaves your process.
Under mode="cloud":
- The raw text is sent to Zotniq's server over TLS for evaluation.
- The server writes decision metadata to the audit row, never the raw text. The original_preview column is always NULL. masked_preview is written under retention_mode=FULL, nulled under METADATA.
- Findings + decision + summary are what your dashboard sees.
If your organization requires the raw text never leaves your perimeter, use mode="local" for those payloads, or self-host Zotniq via base_url=.
Per-call overrides¶
You can flip modes per call without reconstructing the client:
client = Zotniq(api_key="zot_sk_...")
# 99% of calls go to the cloud
result = client.preflight.check(payload, destination="AI_TOOL")
# This one payload contains something you'd rather not send
result = client.preflight.check(sensitive, destination="AI_TOOL", mode="local")
Self-hosted Zotniq (air-gapped)¶
Set base_url= to point at your own deployment:
All cloud-mode calls now go to your infrastructure. On-prem deployment is not a self-service tier today — reach out to sales if you have an air-gapped or in-VPC deployment requirement so we can scope the right delivery.