Skip to main content

Spam-likelihood prediction

A carrier spam label is expensive to remove and cheap to see coming. Once an aggregator’s analytics (Hiya, TNS, First Orion) mark one of your outbound numbers “Spam Likely”, every party you call sees the tag on their handset, answer rates collapse, and lifting the label is a weeks-long registration and dispute process. Orbit’s predictive spam-likelihood endpoint exists so you act in that window — between your own delivery-receipt data degrading and the published label landing. This page explains how the prediction is composed and when to execute the playbook it returns. The endpoint contract itself lives in Number health, warming, and carrier reputation tracking.

Why forward-looking beats reactive handling

Orbit’s number surfaces cover three different time horizons: The health endpoints tell you deliverability slipped; the reputation endpoint tells you the label already landed. Neither tells you how close you are to being labelled. The spam-likelihood score fills that gap — read it as an early-warning threshold, not another health graph.

Signal inputs

The score is a weighted blend of four signals, all derived from your own outbound delivery receipts over the lookback window (7d, 14d, or 30d, defaulting to 30 days):
  • Failure rate — failed / sent across the window. This is what carrier filters weight most heavily, so it carries the largest single component (up to 40 points).
  • Complaint-coded failure rate — rejections that came back with a spam or opt-out error code, also weighted up to 40 points. A 20% complaint rate saturates this component on its own; past that, the plain failure component keeps adding, so extreme cases still move up rather than capping out.
  • Health-trend direction — a declining trajectory from the health-trend kernel adds 15 points; improving and stable add nothing. The trend input pulls forward the same least-squares fit that powers the forecast, so a slow bleed counts even before today’s failure rate looks bad.
  • Anomaly flag — a detected step-change (the latest day dropping far below its preceding baseline) adds 5 points. This catches the “a spam flag just landed between ticks” signature a smooth slope would average away.
Low-volume handling. A score computed over a handful of sends would scare you with noise, so the endpoint refuses to score thin windows: if the window has fewer scored days than the trend kernel needs, or total sends fall under the health kernel’s minimum sample size (50 outbound messages), the response returns spam_likelihood_score: null with label unknown. The thresholds are echoed back as min_sample_size so you can render the gate honestly. Waiting for signal is a better answer than a bad answer — do not treat unknown as low.

The four label bands

The raw score (0–100, rounded to one decimal) maps onto the bands operators expect from carrier-reputation tooling: The score is strictly monotonic in risk: more failures, more complaint-coded rejections, a declining trajectory, or an anomaly all push it up. Nothing in the blend reads carrier-published labels, so it never double-counts the reputation you already see on the reputation endpoint.

The contributing-factors breakdown

The response ships an explicit per-component breakdown rather than a bare number, so you can see which lever to pull:
The four raw inputs come first, then the four *_component values in the same order as the formula. The components sum to the score, so when a number reads severe you can tell whether the driver is plain delivery failures (routing or content quality), complaint-coded rejections (registration or opt-out hygiene), a degrading trend, or a fresh anomaly — and the playbook step you take differs for each.

The ordered remediation playbook

Alongside the score, the response returns a numbered playbook — the manual front-half of the closed-loop remediation run. Automated quarantine and replacement only run safely after a human has acknowledged these steps, and the playbook is structured so a dashboard can switch on each step’s action identifier:
  1. Pause outbound (pause_outbound) — always step one, whatever the score. Stop adding new volume on the number while the signals settle.
  2. Verify registration (verify_registration) — re-check that the sender’s registered campaign (10DLC brand/campaign, toll-free verification, or the corridor’s free-entry form) is current, and close any gaps. Registration problems are the most actionable single fix; an unregistered or lapsed campaign is the carrier’s most common filter trigger.
  3. Reduce volume (reduce_volume) — included once the score reaches moderate (25+) or worse. Drop outbound volume until failure and complaint rates normalise, then re-ramp gradually.
  4. Warm a replacement (warm_replacement) — also gated to moderate-or-worse. Warm a replacement number in a warmed sender pool so inbound routes, dialer campaigns, and sender pools can migrate without a hard cutover.
When the score is still low, steps 3–4 collapse into a single monitor step: check the number daily while the trend stays within normal bounds. The playbook is a pure, ordered list of instructions — executing it is your action; the endpoint changes nothing by itself.

How prediction composes with the health-score kernel

Spam likelihood is not a separate data pipeline. The endpoint buckets the same tenant messages rows the point-in-time health score reads — outbound traffic from the specific number — into daily aggregates, then runs the health-trend kernel over those buckets to get direction and anomaly before scoring. Two consequences follow:
  • Same window semantics. failure_rate and complaint_rate in the breakdown mean exactly what they mean on the health page; a high spam-likelihood score on a number whose health tier is excellent usually means the trend/anomaly input is carrying the risk — check trend.direction before assuming the blend disagrees.
  • Same sample-honesty gates. The min_sample_size and insufficient-data behaviour are mirrored from the health kernel outright, so a number that cannot be health-scored cannot be spam-scored either.
Because the whole response is a pure read over locally-stored receipts with no carrier call, calling it is free of provider-side effects and safe to poll from a monitoring loop.

When to act

Execute the playbook before the label, on this schedule:
  • high or severe → run the playbook now. Step 1 (pause) applies while you work steps 2–4.
  • moderate → run steps 1–2 (pause, verify registration) and put the number on daily watch.
  • low → the monitor step only; re-check on your normal cadence.
  • unknown → wait for signal; a null score is a gate, not a green light.
Tie the playbook to your other guardrails: when it returns reduce_volume, lower the campaign’s pacing cap and tighten quiet-hours windows as described in send gating and quiet hours; when it returns warm_replacement, fold the number into the closed-loop reputation remediation policy (quarantine → replace → migrate → retire) early instead of after a support ticket. For the fleet-wide view of numbers already flagged, poll the reputation-alerts endpoint; the spam-likelihood score is the per-number drill-down that should surface risk before it ever reaches that list.

See also