> ## 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.

# Troubleshooting: DNC pre-flight returns 403 DNC_SYNC_NOT_ENABLED

> Resolve 403 DNC_SYNC_NOT_ENABLED on GET /dnc/check and POST /dnc/scrub — read the gate state, acknowledge the stub-feed gap, and recognize when a synced snapshot retires the gate.

# Troubleshooting: DNC pre-flight returns 403 DNC\_SYNC\_NOT\_ENABLED

`GET /api/v1/compliance/dnc/check` and `POST /api/v1/compliance/dnc/scrub`
both run the pre-flight Do-Not-Call chain before you dial or text a number.
While the org has not acknowledged the pre-flight gate, both endpoints
answer **403** with a structured envelope and `on_dnc` is not served:

```json theme={null}
{
  "error": {
    "code": "DNC_SYNC_NOT_ENABLED",
    "status": 403,
    "details": {
      "flag": "organizations.settings.dnc_sync_enabled",
      "federal_feeds_synced": false
    }
  }
}
```

This page maps the 403 to the gate that fired and the resolution you can
run yourself. For the concept behind the gate — what the pre-flight chain
checks and what the acknowledgment means — see
[Send Gates → DNC](/compliance/send-gates); for the campaign workflow, see
[Batch DNC Pre-Flight Scrubbing](/guides/dnc-preflight-scrub).

<Note>
  The gate is an acknowledgment mechanism, not a compliance verdict. It
  exists so no one treats a negative result as a federal-register scrub
  before a snapshot is synced. Turning it on does not change what Orbit
  enforces on your send paths — tenant-curated DNC flags, suppression
  lists, and consent opt-outs keep applying either way.
</Note>

***

## Why the gate fires

The 403 appears only while **no platform Do-Not-Call snapshot is synced**
— read `federal_feeds_synced: false` on any response to confirm. In that
state the route is held behind your org setting
`dnc_sync_enabled` (default **off**). Both conditions together produce the
403:

1. No federal, state, or TCR snapshot is synced for the platform, **and**
2. Your organization has not set `dnc_sync_enabled: true`.

The gate is deliberate: without it, a number listed only on the FTC
register would read back as `on_dnc: false`, and a pre-flight you trusted
would be a false negative. Acknowledging the flag means you understand the
pre-flight currently checks tenant-curated sources only.

### The flag lookup fails closed

The `dnc_sync_enabled` lookup resolves to OFF on every one of these — by
design:

* The organization has never visited compliance settings and the flag was
  never set.
* The stored settings value isn't a literal boolean `true` (a string
  `"true"` or number `1` does not count).
* The settings row is missing.
* The settings lookup itself fails (a transient database error resolves
  to OFF the same way).

So an org that has never touched the toggle always gets the 403, and a
transient lookup failure can never silently open the gate. If you see the
403 right after you believed you enabled it, re-read your settings and
confirm the stored value is a boolean `true`, not a string.

***

## Resolution

Enable the acknowledgment **per organization** in the dashboard compliance
settings (the `dnc_sync_enabled` toggle — see the
[posture map](/compliance/posture-overview), which lists the toggle and
its default). One flip enables both the single-number check and the bulk
scrub; the endpoints serve immediately — no propagation delay.

Confirm the gate state without running a check by calling
`GET /api/v1/compliance/dnc/availability`: it reports `available`
(the exact gate both endpoints enforce), `org_opt_in`, and
`federal_feeds_synced` for the calling organization.

**What you're acknowledging:** the pre-flight has no federal-register
scrub backing it yet. A number present only on the FTC register returns
`on_dnc: false` until a platform snapshot syncs. Your contact DNC flags,
DNC list, suppression list, and consent opt-outs are checked regardless of
the flag — the acknowledgment governs only this read endpoint.

***

## When the gate clears by itself

The gate auto-retires the moment a platform snapshot syncs: the DNC feed
sync job upserts the federal, state, and TCR snapshot on a daily cadence,
and once a snapshot exists the route serves directly — no acknowledgment
required and no org change needed.

How to recognize it: every served response carries
`federal_feeds_synced`. When it flips to `true`, a federal scrub is
actually backing the result and the acknowledgment is no longer consulted.
If your 403 cleared without anyone enabling the toggle, this is why — and
it is the stronger of the two states.

***

## Still blocked? Checklist

* **Right org / API key** — the flag is per organization. A key scoped to
  a different org reads that org's setting.
* **Stored as boolean `true`** — a string or numeric value resolves to
  OFF; re-set the flag.
* **RBAC** — both endpoints require an authenticated role; a valid bearer
  token for the wrong environment or an expired session returns 401, not
  this 403, so distinguish the two.
* **Bulk scrub rate limit** — `POST /dnc/scrub` accepts up to 500 E.164
  numbers per request and is rate-limited to 10 requests per minute per
  organization. A `429` there is throttling, not the gate — back off and
  chunk your list.
* **Validation first** — malformed phone numbers return `422` with field
  errors before the gate is even evaluated; fix the E.164 shape first.
