AI features

Three assistants, one rule: AI is never load-bearing. No model sits in the delivery path, no AI output goes anywhere without you confirming it, and every feature works fine if you ignore the ✨ entirely.

✨ Draft (composer)

Describe the notification — “remind free users their trial ends in 3 days” — and get title + body + two variants. The prompt carries the physical constraints (iOS lock-screen truncation at ~60 title chars, Android body collapse at ~150), so drafts come out shippable, not just pretty.

✨ Build audience (English → filter)

“pro users in Nepal active this week” becomes a real filter — and here's why you can trust it where other tools' AI targeting is a gamble:

  1. The model only sees your property catalog — it cannot reference attributes you don't have.
  2. Its output must survive the actual filter parser and compiler — a hallucinated attribute or invalid operator is rejected and retried, and a twice-bad answer returns an error, never a wrong filter.
  3. You see the compiled filter with its live count before anything sends. The AI proposes; you confirm.

✨ Explain (delivery failures)

Any failed delivery → one click → meaning, likely cause, and the fix, grounded on the error taxonomy and the raw provider response. Cached per error class.

Bring your own model — never metered

Dashboard → Setup → AI: connect an Anthropic or OpenAI key, or any OpenAI-compatible endpoint (vLLM, Ollama behind TLS, Together, …). With a BYO key:

UsageUncapped. We never meter your own key.
DataYour briefs, catalogs, and error payloads go to your provider account — not a shared pool.
StorageThe key is sealed in the same encrypted store as your APNs credentials.

Custom endpoints must be public HTTPS hostnames — literal IPs, localhost, and internal names are rejected (that restriction protects the platform, and it's not negotiable).

Pooled usage & limits

No key connected? Features run on the platform pool with daily limits: free 25, pro 500, scale 5000 calls/day. Hitting the ceiling returns a clear message — connect a BYO key for unlimited.

Trust rules (the fine print, plainly)

When models are calledOnly on your explicit click — never in background jobs.
Output handlingSchema-validated, one retry, then a graceful error. Invalid output is discarded, not "best-effort" used.
Delivery pathZero model calls between “send” and “delivered”. Ever.