Skip to main content

AI Brand-Safety Scan

The policy scanner runs on every outbound message and on every keystroke in the compose dialog. It is deterministic — keyword lists, heuristics, and checksums — so it catches exactly the classes you can express as a rule: TCPA quiet hours, SHAFT keywords, missing opt-out text, spam keywords, DLP patterns. The AI brand-safety scan is an optional LLM pass layered on top of that keyword baseline. It catches the classes a rule can’t express, where the violation lives in the meaning of the copy rather than in any single word. A phishing message that harvests credentials can contain zero flagged keywords; an LLM reads it the way a carrier review team would. All endpoints below are rooted at https://api.orbit.devotel.io.
The AI brand-safety scan is a tenant-owned control that you invoke per request. Nothing runs it on your traffic unless you opt in (ai: true on the lint endpoint) or until your organization reaches a campaign launch. Orbit never uses it to gate your traffic globally. This page is not legal advice — confirm your regulatory obligations with counsel.

Why an LLM pass complements the keyword scanner

Keyword scanning is the always-on baseline because it is synchronous and free to run on every send and every keystroke. But the violations that produce carrier filtering and the largest regulatory settlements are semantic:
  • “Your Wells Fargo account is locked — verify at this link” contains no keyword on any block list, yet it impersonates a bank.
  • “Guaranteed 15% return, withdraw anytime” trips no spam keyword, yet it is regulated-finances language a carrier will filter.
  • Coercive urgency (“Final notice: pay within 30 minutes to avoid legal action”) pattern-matches as ordinary promotional copy, yet it is a dark pattern that A2P reviewers reject.
Where a keyword pass returns pass, the AI pass can still return warn or block. The two runs together produce a single merged violations list — same shape, same verdict roll-up, same enforcement mode (see How the verdict is enforced).

Posture: opt-in, warn by default

The scan has two enforcement surfaces, and both start from the same default your policy scan mode already has: warn — findings are recorded and surfaced, nothing is held. brand_name and industry are optional hints you pass on the lint request. They ground the verdict: a pharmacy mentioning prescriptions is legitimate, a generic retailer mentioning prescriptions is suspicious; a message is checked for whether it plausibly comes from your brand or impersonates a third party. When your organization’s policy mode is strict, every violation the AI pass returns is upgraded from warn to block — the same severity promotion the keyword scanner applies in strict mode. A block from either scanner then holds the send with POLICY_VIOLATION and a launch with a rejected campaign. In warn mode the same findings are recorded and returned in the response headers but the send proceeds. In off mode the keyword scan is skipped entirely; the AI pass at lint still runs when you explicitly pass ai: true (you asked for it), and violations stay advisory.
The campaign launch gate is a content gate only. It never reroutes or holds carrier termination itself — it rejects or annotates the launch, and the normal send path applies the same verdicts per recipient afterward.

The risk classes it catches

Each violation carries one of seven categories: The model is instructed to flag only clear violations — false positives erode the trust that makes an advisory finding worth acting on. Every violation comes back with confidence on a 0–1 scale so you can sort marginal flags from certain ones.

Cost, latency, and why it fails open

One scan is a single LLM call on a small class model:
  • Cost — on the order of $0.0001 per scan (~200 input tokens, ~150 output tokens, 512 max tokens out). At the campaign launch gate that is once per launch; at /messages/lint, only on requests where you passed ai: true.
  • Latency — P95 under 1.5 seconds; bounded by a 6-second hard abort, so a slow model response can never hold a compose request or a launch handler past the ingress window.
  • Rate limiting — the lint endpoint is generously rate-limited (120 requests per minute per organization) to support as-you-type debounce; the AI pass consumes the same budget, so invoking it on every keystroke is the misuse it was designed to survive but not encourage.
Fail-open is deliberate. On any scanner error — model timeout, abort, schema mismatch, upstream outage — the scan returns pass with failedOpen: true and the send or launch proceeds on the keyword baseline alone. The rationale: the keyword scanner already covers the deterministic compliance classes, so an AI outage degrades you to the pre-LLM behaviour rather than to a traffic halt. A brand-safety outage must never block legitimate sends, and this module never gets the right to. When a scan fails open, the response says so — treat failed_open: true as “advisory layer unavailable,” not as “content was clean.”

Where the scan runs in the send lifecycle

The same scanner appears at three points, earliest first:
  1. Compose-time lintPOST /messages/lint with ai: true. Read-only; nothing is sent or recorded against a message. The dashboard compose dialog surfaces the verdict inline before you commit. Lint with ai: true during drafting, not on every debounce.
  2. Campaign launch gate — runs automatically when a campaign launches, once over the body-only content (recipient-dependent rules like quiet hours still run per recipient afterward). In strict mode a block verdict rejects the launch; in warn mode the findings are attached to the launch response headers.
  3. Send-time lint — the per-message policy scan on the actual send path stays keyword-only by default; the AI-verdict surface you saw at lint and launch uses the same violations shape, so what you previewed is what the send path would have enforced in strict mode.

Audit and evidence

Where a scan runs, what it decided is recorded in the customer’s own vocabulary rather than hidden in a model response:
  • Lint response — the ai_brand_safety block carries the verdict, the full violations list with confidence, failed_open, and the model identifier.
  • Launch response — AI findings are merged with keyword findings into one violations list, returned in the X-Policy-Violations response header and, on a strict-mode block, in the error details.
  • Evidence binder — compliance scan posture (your policy mode, and the gates that run along your send path) is part of what the evidence binder compiles into the audit pack you hand to an auditor. Generate it when you need the posture on paper, not per send.

Worked example

Lint a draft with the AI pass and your grounding hints:
200
In warn mode the keyword verdict was pass, the AI verdict was block, and blocked is false — the findings are advisory. Had the organization been in strict mode, both AI violations would have been promoted to block severity, blocked would be true, and the same content on a campaign launch would have been rejected with POLICY_VIOLATION until the copy was remediated along the suggestions above.