RND Safe-Harbor Pre-Contact Number Scrubbing
An RND scrub answers one question before a campaign leaves the building: is this destination number still assigned to the person who consented? Under the TCPA, consent follows the subscriber, not the number — when a carrier re-assigns a number to a new subscriber, your consent for the old subscriber stops covering that destination. The FCC’s Reassigned Numbers Database (RND — reassigned.us, 47 CFR § 64.1200(m)) exists to answer one specific question: was this number permanently disconnected after my consent date? Orbit exposes the FCC safe-harbor evaluation as a read-only lookup:GET /compliance/rnd/check— one E.164 number plus the date you obtained (or last verified) prior-express consent, returning an FCC RND verdict and whether the safe harbor applies.
https://api.orbit.devotel.io/api/v1/compliance.
How RND differs from the other scrubs
DNC, litigator, suppression, and carrier-deactivation scrubs all answer “did they opt out / is the destination still a live line?” RND answers the orthogonal question: “is this destination still the person who consented?”
Run RND alongside the DNC scrub, not instead of it — a number can be
reassigned without ever touching a registry, and registry-listed without
reassignment getting involved. See DNC Scrubbing
and Phone Deactivation Scrubbing for
those checks; this guide covers the RND leg.
Enable the per-org toggle
The endpoint is gated behind your organization’s RND-scrub opt-in —organizations.settings.rnd_scrub_enabled, default off. While the
flag is off, every /rnd/check returns HTTP 403:
DEVOTEL_RND_FEED_FILE / DEVOTEL_RND_FEED_URL once
the subscription is provisioned. Until that ingestion has succeeded,
turning the toggle on is refused with HTTP 409
RND_FEED_NOT_CONFIGURED — the control is only offered once the feed is
ingested, so a tenant cannot switch on an inert compliance control.
(Company-operated configuration; you cannot enable it yourself while
feed_synced is false.) Disabling is always allowed. The PUT is
owner/admin-only: flipping it requires an owner or admin on your team.
Check the gate state without scrubbing anything:
PUT /compliance/rnd/settings with body
{ "enabled": true }. A single setting change takes effect immediately.
Check
feed_synced before you check numbers. It reports whether an
RND disconnect snapshot is loaded; while no feed is configured, every
/rnd/check verdict is no_data. A waiting-for-feed 409 on enable is
the gate protecting you from enabling an inert control — it is the
correct state, not an error to retry.Feed status — feed_synced on every verdict
Every /rnd/check response carries feed_synced. Read it before trusting
a verdict:
true— the ingested RND snapshot backed this verdict (real data).false— no feed is loaded, or the feed lookup itself failed. Verdict degrades tono_dataon every number, andsafe_harborisfalse— we cannot claim a sync we did not complete. Never treat afalseresponse as a real “not reassigned” answer; treat it as UNKNOWN and gate the send.
Single-number check
phone— E.164 destination (leading+, 7-15 digits).consent_date— ISO calendar date (YYYY-MM-DD) you obtained or last verified prior-express consent.
status verdict has three values:
last_disconnect_date (ISO-8601, or null) is the most-recent permanent
disconnect on record — the date the safe-harbor comparison ran against.
reason is a one-sentence explanation suitable for an audit log.
Every scrub is audit-logged with the verdict,
safe_harbor, and consent
date, so a compliance review can prove the pre-contact check ran. Phone
numbers are truncated in the audit details (first 5 digits → ****).Pre-campaign batch pattern
There is no batch endpoint — batching is a loop over the single check. Run it between building the audience and launching the campaign:- Build your segment with the audiences/CDP tools as usual.
- Resolve a consent date per recipient — the date you obtained (or last verified) prior-express consent. One date per segment, or per contact if consent ages diverge.
- Check the gate —
GET /compliance/rnd/settings. Ifenabledorfeed_syncedis false, fix that first (above). - Loop the segment and call
/rnd/checkper number. The endpoint shares the standard authenticated-read budget (120 requests/minute per organization). Chunk the audience and call sequentially with a small pause (~500 ms) per request; a loop that fires in a tight burst hits HTTP 429 and pauses. - Route the verdicts out of the send audience:
yes→ suppress the destination (and log it under your suppression layer so future segments exclude it up front). Do not attempt to send.no_data→ treat as UNKNOWN: either hold until the feed is synced or send under your own risk policy — it is not a safe-harbor pass.no→ eligible for the campaign (safe harbor covers it).
- Launch against the scrubbed audience — see Outbound dialer campaigns and Campaign end-to-end.
- Re-scrub stale audiences. The RND is updated by carriers continuously, so re-run before each send for an audience held more than a couple of days. The verdict you ran at audience-build time ages out as disconnect records move.
Failure modes and per-number handling
The check never throws at the route level — a scrub gate degrades to a conservativeno_data instead of breaking your flow. Per-number realities:
- Bad
phone/ badconsent_date→ HTTP 422 with the failing field(s) indetails. Fix the shape and retry; the verdict layer never sees it. - Feed lookup fails or no feed is loaded →
status: "no_data",safe_harbor: false,feed_synced: false, andlast_disconnect_date: null. Routeno_dataper your own risk policy — it is never a safe-harbor pass. - Unparseable consent date at the verdict layer →
no_datawith a specific reason; the controller’sYYYY-MM-DDregex keeps this from reaching the verdict in normal use, but an old SDK that skips validation gets the same safe degradation. - HTTP 403
RND_SCRUB_NOT_ENABLEDon every call → the per-org opt-in is off; the dashboard’s scrub card greys or enables the action up front viaGET /compliance/rnd/settings. - HTTP 409
RND_FEED_NOT_CONFIGUREDon enable → the FCC feed is not ingested; the toggle cannot turn on yet. This is the gate at work, not a failed call.
/rnd/settings and /rnd/check against the standard
authenticated-read budget (120/min per org); writes (PUT /rnd/settings)
are 20/min, owner/admin only.
Audit and logging caution
Every scrub is written to the audit chain (with the phone truncated to its first five digits) so a compliance review can show the pre-contact ran before the send went out. That record exists to show your side of the TCPA exposure. The goal of running a scrub is not to produce a textual “clear” verdict —safe_harbor: true only follows status: "no". A clean run of no_data
verdicts is a signal the screen did not run, and you gated the send on
“unknown” data; feed it back to your suppression layer, not to a send
queue.
See also:
- DNC Scrubbing — the opt-out registry layer.
- Phone Deactivation Scrubbing — the carrier disconnect/churn layer, including the scrub-vs-send-gate comparison table above.
- Send Gates — the quiet-hours / DNC / RND / RMD gates that run at send time.
- Opt-Out & Suppression Lists — the
layer a
yesverdict routes onto. - Your Tenant Compliance Posture — the toggle map, including the RND-scrub row.
- API Reference → Compliance — full request/response schemas.