Skip to main content

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:
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; for the campaign workflow, see Batch DNC Pre-Flight Scrubbing.
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 — 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, 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 limitPOST /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.