> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# The Reassigned Numbers Database (RND): how the safe-harbor scrub works end to end

> What the FCC Reassigned Numbers Database is, how Orbit's date-comparison verdict (most-recent disconnect date vs. your consent date) is produced, where the dialer and API both consume it, and what evidence the scrub leaves for compliance reviews.

# The Reassigned Numbers Database (RND)

A US telephone number you collected consent on can be **permanently
disconnected** — the carrier retired it — and later handed to a new
subscriber. A call or SMS placed to that number now reaches a stranger who
never consented, and every such contact is individual TCPA exposure. The
FCC's [Reassigned Numbers Database](https://www.reassigned.us) (47 CFR
§ 64.1200(m)) is the registry providers report permanent disconnects to.
Orbit's RND scrub is the pre-contact gate that answers one question: *was
this number disconnected after the date you got consent?* If the registry
says "no," the FCC safe harbor shields your outbound even if a reassignment
slipped through; "yes" or "no data" means contact at your own risk.

This page is the end-to-end explanation behind the "RND safe-harbor check"
you see on send gates. The two gate pages —
[Send gates](/compliance/send-gates) and
[Country requirements](/compliance/country-requirements) — stay the
wiring reference; read this page when you need to reason about what the
verdict actually evaluates and where it fires.

## The verdict is a date comparison, not a membership test

Unlike the DNC registers (a number is either listed or not), the RND query
carries your **consent date** and the answer is computed each time. Orbit
produces the same three verdicts the FCC database defines:

| Verdict   | Condition                                                                                        | Safe harbor                       |
| --------- | ------------------------------------------------------------------------------------------------ | --------------------------------- |
| `no`      | The most-recent permanent disconnect on record is **on or before** your consent date.            | **Applies.** Safe to contact.     |
| `yes`     | The most-recent disconnect is **after** your consent date — the number may have been reassigned. | Denied. Do not contact.           |
| `no_data` | No disconnect record for the number — the registry never saw a permanent disconnect for it.      | Denied. Proceed at your own risk. |

The date arithmetic is pure (no lookup side effects) and defensive: an
unparseable consent date evaluates as `no_data`, because a gate cannot
assert a safe harbor it cannot evaluate.

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "status": "no",
      "safe_harbor": true,
      "last_disconnect_date": "2026-03-14",
      "consent_date": "2026-06-01",
      "feed_synced": true,
      "reason": "No permanent disconnect after the consent date; the FCC reassigned-number safe harbor applies — safe to contact."
    },
    "meta": {
      "request_id": "req_01J9A7XK4M",
      "timestamp": "2026-09-15T11:30:00Z"
    }
  }
  ```
</ResponseExample>

Three fields drive your integration:

* **`status`** — `yes` / `no` / `no_data` exactly as above.
* **`safe_harbor`** — `true` only for `status: "no"`. Branch on this one
  boolean; treat anything else as "stop."
* **`feed_synced`** — `false` means no RND snapshot is loaded in the
  deployment, so every verdict degrades to `no_data`. The platform never
  asserts a safe harbor it has not actually queried — always read this
  field before trusting a `no` verdict.

## Where the snapshot comes from and how it loads

Real RND query access is a **paid subscription** with the database
administrator (reassigned.us / SomosGov), provisioned out of band by
Devotel for the deployment. The snapshot ingests once at process start:
a disconnected-number → date index is built from the configured feed
location, and every later scrub is an in-process index lookup — there is no
per-check network call. A snapshot that fails to ingest is logged and the
gate degrades open: no data rather than a broken dialer.

This has one operational consequence down below:
[the tenant toggle](#the-tenant-operated-toggle) refuses to turn RND on
until a snapshot is actually loaded.

## The tenant-operated toggle

RND scrubbing is **your organization's posture**, not a platform default —
compliance posture belongs to the tenant, and Orbit carries the setting.
The flag lives behind the settings pair under `/api/v1/compliance`:

<RequestExample>
  ```bash theme={null}
  curl -X PUT https://api.orbit.devotel.io/api/v1/compliance/rnd/settings \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{"enabled": true}'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "enabled": true,
      "feed_synced": true
    },
    "meta": {
      "request_id": "req_01J9A8XK5N",
      "timestamp": "2026-09-15T11:35:00Z"
    }
  }
  ```
</ResponseExample>

* **Read** the flag with `GET /api/v1/compliance/rnd/settings` — the
  response's `feed_synced` tells you whether a snapshot is loaded before
  you decide to enable.
* **Write** it with `PUT /api/v1/compliance/rnd/settings`
  (`{ "enabled": true|false }`). Owner or admin only; an `enabled: true`
  write while no snapshot is loaded is refused with
  `409 RND_FEED_NOT_CONFIGURED` — enabling an empty gate would present an
  inert control as operational protection. Disabling is always permitted.
* **Check a destination** with

```
GET /api/v1/compliance/rnd/check?phone=<e164>&consent_date=<YYYY-MM-DD>
```

once enabled; while the flag is off the endpoint refuses with
`403 RND_SCRUB_NOT_ENABLED`.

Wire the full gate surface through
[Send gates](/compliance/send-gates) and the per-country attachment rules
in [Country requirements](/compliance/country-requirements) — those pages
own the endpoint wiring; this page owns the model.

## The two surfaces that consume the verdict

One flag flips the scrub on in both places at once:

* **The predictive dialer.** Every paced dial and callback re-checks
  destination admissibility right before the call originates (see
  [Dialer pacing](/concepts/dialer-pacing-model)). With a snapshot loaded
  and your flag on, a `yes` verdict blocks the dial with reason
  `rnd_reassigned`. This is the **automatic** gate — no per-call endpoint
  request needed.
* **The API pre-send gate** —
  `GET /api/v1/compliance/rnd/check`. Any authenticated role can read this
  on demand: pre-flight a single destination before its own send, or batch
  a list ahead of a campaign. It is the **manual** counterpart of the
  dialer's automatic gate, and the scrub it applies is identical.

Both surfaces read the same flag and the same snapshot, agree verdict-for-
verdict, and share the same fail-open posture: a scrub evaluation that
cannot complete (unparseable date, unreadable flag, index error) declines
to block — the RND layer adds safe-harbor protection on top of the
existing scrub gates and never becomes a new way to deadlock sends.

### Implementation note: the two-process duplication (not operator contract)

The API and the automated-call worker each ingest the same configured
snapshot at their own boot and apply the same pure date comparison. That
duplication is deliberate: the worker and the API are separate processes
that cannot share an in-memory feed index, and the worker must stand on
its own — the same reason the DNC parser has a worker-side copy. The
snapshot config and the verdict both live in deployment configuration
shared across the fleet, so a divergence between the two copies is an
operational bug to fix centrally, not a tenant-facing contract.

This is an **implementation note only** — operators integrate against the
endpoints and the verdict semantics above; the process layout below is
subject to change without notice.

## RND vs. DNC vs. deactivation scrub — three orthogonal answers

Operators often conflate the destination-hygiene brands. Each gate
answers a different question about the same number:

| Gate                   | Question it answers                                             | Verdict shape                                   |
| ---------------------- | --------------------------------------------------------------- | ----------------------------------------------- |
| **RND scrub**          | Was this number **disconnected after your consent date**?       | Date comparison — `yes` / `no` / `no_data`.     |
| **DNC registers**      | Is this number on a national Do-Not-Call register?              | Membership — listed blocks; not listed allows.  |
| **Deactivation scrub** | Is this number still reachable on any carrier, or did it churn? | Reachability — a death-flag, no date semantics. |

DNC is a hard fail-closed blocklist layered over the whole send path; RND
and deactivation scrubbing are opt-in protections layered **on top of**
that. Deep links:
[Deactivation scrubbing](/compliance/deactivation-scrub) (full matrix and
the deactivation gate),
[Send gates](/compliance/send-gates),
[Country requirements](/compliance/country-requirements), and
[Consent and suppression](/concepts/consent-and-suppression-model) for
the DNC side of the register family.

## Evidence: what the scrub leaves for counsel and audits

Every RND interaction writes to your audit log, so the scrub is provable:

* **Every check call** — each `/rnd/check` evaluation (and every denied
  attempt while the flag is off) lands an audit entry carrying the verdict,
  the consent date it was evaluated against, and the actor. The phone
  number is truncated in the entry to avoid stamping full PII into the
  chain.
* **Every toggle change** — flag flips land an audit entry with the new
  state; an enable blocked by the missing snapshot `409` is audited as
  such, so reviews see blocked attempts as well as allowed ones.
* **Every blocked dial** — a dialer block on `rnd_reassigned` is logged
  alongside the rest of the send-gate chain, so a scrubbed batch has a
  per-contact reason rather than a silent drop.

`GET /rnd/settings` plus the audit entries for the evaluations you relied
on are the complete evidence bundle for a given send. That bundle is
ordinary audit data — import it into your broader evidence work per the
[audit ledger model](/concepts/audit-ledger-model). If a legal hold
arrives, treat the audit log the same way recordings and threads are
treated: the
[legal holds guide](/guides/compliance-legal-hold) explains which records
your counsel-driven hold covers — verify RND audit entries are inside the
hold's scope rather than relying on a generic retention exemption.

<Note>
  The RND scrub is a safe-harbor **support** control, not a compliance
  guarantee. The FCC safe harbor applies only when you query the database
  in good faith and the database answers "no"; a `no_data` verdict, or an
  unsynced feed, never protected you. Confirm your TCPA obligations with
  counsel — this page is not legal advice.
</Note>

## See also

* [Send gates](/compliance/send-gates) — the endpoint wiring surface and
  the rest of the gate stack
* [Country requirements](/compliance/country-requirements) — per-country
  compliance attachment rules
* [Deactivation scrubbing](/compliance/deactivation-scrub) — the
  carrier-churn hygiene gate RND complements
* [Consent and suppression model](/concepts/consent-and-suppression-model) —
  the consent record the `consent_date` parameter reads from
* [Outbound send gating](/concepts/send-gating-and-quiet-hours) — the
  full gate chain the RND check slots into
* [Dialer pacing model](/concepts/dialer-pacing-model) — where the
  automatic RND gate fires on paced calls
* [Audit ledger model](/concepts/audit-ledger-model) — the evidence chain
  the scrub writes to
* [Legal holds guide](/guides/compliance-legal-hold) — preserving your
  hold scope
