Carrier Deactivation (Churn) Scrub: List Hygiene Against Carrier Disconnects
The carrier deactivation scrub answers one question before you re-contact a recipient: did the subscriber’s carrier deactivate this number since you last had a valid relationship with them? Numbering carriers publish a daily feed of subscriber numbers that were deactivated or disconnected — the subscriber cancelled the line, ported away and let it lapse, or the carrier reclaimed the number. Scrubbing against that feed keeps churned numbers out of your lists before they cost you throughput or deliver to a stranger. This page is the end-to-end picture: what the scrub is, how to turn it on, how to pre-flight one number or a whole list, how the automatic pre-send guards enforce it on SMS/MMS, voice, and Verify/OTP, and what the fail-open caveat means. For the other scrub layers this complements — the FCC Reassigned Numbers Database and Do-Not-Call registries — see the comparison table below and Send Gates. All endpoints below are rooted athttps://api.orbit.devotel.io/api/v1/compliance/deactivations.
When the deactivation scrub matters
Continuing to text or call a deactivated number has two costs a sender pays either way:- Wrong-recipient delivery. Once a carrier deactivates a number, it can be reassigned to a new subscriber. Messaging it after the disconnect risks delivering marketing texts or even one-time codes to a stranger — a 47 U.S.C. § 227 (TCPA) exposure for US traffic, and reputational exposure everywhere.
- Dead-number burn. Every send to a disconnected number still consumes A2P throughput and counts against your sender reputation with the carrier.
- The DNC scrub answers “did the person ask to stop?” — federal, state, TCR, and international registries plus your own suppression layer.
- The RND check answers the TCPA safe-harbor question “was this number permanently disconnected after my consent date?” — a per-number legal gate against reassignment.
Enable the tenant toggle
The scrub endpoints and the automatic send-path guards are off by default per organization. Until you opt in, the check and scrub endpoints return403 DEACTIVATION_SCRUB_NOT_ENABLED and the send-path guards skip.
The opt-in is the deactivation_scrub_enabled setting on your
organization’s compliance settings; any authenticated member can read it,
while only an org owner or admin can change it.
feed_synced field is read-only: it reports whether a carrier
deactivation snapshot is actually loaded. Until one is synced, every
verdict stays no_data — see the fail-open caveat.
One flip enables both the API surface and the automatic pre-send guards;
the write is auditable in the compliance audit log.
Check a single number
GET /deactivations/check reports whether one E.164 number was deactivated
by the subscriber’s carrier. Supply last_seen — the date you last
validated the number had a live relationship with the subscriber — to
ignore deactivations that predate the current relationship.
status— one ofdeactivated(carrier churn on record — scrub it),active(no relevant deactivation on record — keep it), orno_data(no feed synced — no verdict can be asserted; keep, at your own risk).should_scrub— true only whenstatusisdeactivated. A hygiene gate never scrubs a number the feed has not positively flagged.last_deactivation_date— the most-recent carrier deactivation on record for the number, ornullwhen there is none.last_seen_date— the filter date you supplied, echoed back.feed_synced— false until a carrier snapshot is loaded. While false, every verdict isno_data.reason— a human-readable explanation, suitable for audit review.
last_seen means any deactivation record on file scrubs the
number — the conservative default. With a last_seen date, deactivations
strictly before it are ignored (the current subscriber relationship postdates
them).
Scrub a batch before a campaign
POST /deactivations/scrub runs the same verdict against up to 1,000
numbers per request — the list-hygiene step before a campaign. A top-level
last_seen applies to every number unless a per-number last_seen
overrides it.
should_scrub: true rows from the audience before launching.
For larger lists, page the batch in chunks of 1,000 numbers. Both endpoints
are read-only — no send is performed.
How the send path enforces it
Opting in does more than unlock the API surface: the same feed powers automatic pre-send guards, so enforcement does not depend on someone remembering to pre-flight.- SMS / MMS sends. Before dispatch, the message pipeline looks up your
most-recent prior-express consent date for the recipient (unlike the
manual endpoint, which defaults to any-record). A deactivation on or after
that date refuses the send with
MESSAGING_NUMBER_DEACTIVATED(HTTP 422). A deactivation that predates your consent does not block a legitimately consented send. Campaign bulk-sends route through the same send pipeline, so the guard applies there too. - Voice / dialer. The dialer evaluates the same carrier deactivation verdict before originating a call to a NANP (+1) destination — the carrier deactivation feed today covers NANP numbers, so non-NANP destinations are skipped rather than mis-gated.
- Verify / OTP. A one-time code sent on a phone channel (SMS, MMS,
voice, or flashcall) is refused with
VERIFY_NUMBER_DEACTIVATED(HTTP 422) whenever any deactivation record is on file. There is no consent ledger for a login code, so the guard uses a strict disconnect-presence model — any carrier record means the code could reach a reassigned stranger, and verification must ask the user to confirm the number another way.
The fail-open caveat
That fail-open posture means you must readfeed_synced on every response
before acting on a clear verdict:
Until a carrier deactivation snapshot is synced, every query returnsTwo operational rules follow:no_dataand clear (should_scrub: false) — for every number.
- Treat a clear verdict as “no disconnect seen so far,” never as
safe-harbor. A
no_dataresult means the platform cannot assert the number is churned or clean — the algorithm deliberately degrades to default-keep rather than claim a clean verdict it could not back. - A scrub that skipped still counts as scrubbed-only-if-checkable. On
the SaaS platform the feed is synced centrally; on self-hosted
deployments the operator configures the carrier snapshot. Either way,
weigh
feed_syncedbefore relying on a US campaign pre-flight.
Recover after a block
A deactivated verdict is recoverable, but only through the recipient — not by retrying:- Drop the destination from active lists until you re-verify the number with the subscriber.
- A send-path block clears when a new consent grant (prior express) is
recorded that is dated after the carrier’s
last_deactivation_date— the consent-date filter then treats the current relationship as newer than the disconnect. - For Verify/OTP, the block persists as long as any deactivation record is on file; confirm the number belongs to the user through another channel before re-attempting.
Deactivation vs. RND vs. DNC
Run all three on a campaign audience and prune on any hit — they answer
orthogonal questions. See Send Gates for how the
send-time chain layers them, and
Troubleshooting Verify OTP for recovering
from a
VERIFY_NUMBER_DEACTIVATED refusal.
See also:
- DNC Scrubbing — the registries-plus-suppression layer that complements the deactivation scrub.
- Send Gates — the quiet-hours / DNC / RND / deactivation send-time gates and emergency stop.
- Troubleshooting Verify OTP — diagnosing a refused verification, including carrier-deactivation blocks.
- Error Codes — the full
MESSAGING_NUMBER_DEACTIVATEDandVERIFY_NUMBER_DEACTIVATEDreference rows. - Your Tenant Compliance Posture — the
toggle map, including the
deactivation_scrub_enabledrow.