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:
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.
Why the gate fires
The 403 appears only while no platform Do-Not-Call snapshot is synced — readfederal_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:
- No federal, state, or TCR snapshot is synced for the platform, and
- Your organization has not set
dnc_sync_enabled: true.
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
Thednc_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 number1does not count). - The settings row is missing.
- The settings lookup itself fails (a transient database error resolves to OFF the same way).
true, not a string.
Resolution
Enable the acknowledgment per organization in the dashboard compliance settings (thednc_sync_enabled toggle — see the
posture map, 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 carriesfederal_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/scrubaccepts up to 500 E.164 numbers per request and is rate-limited to 10 requests per minute per organization. A429there is throttling, not the gate — back off and chunk your list. - Validation first — malformed phone numbers return
422with field errors before the gate is even evaluated; fix the E.164 shape first.