ZyanDocs

Preflight check reference

Every preflight check a voice campaign can fail, what each code actually means, and the exact change that clears it — including the ones you cannot clear yourself.

Preflight is the deterministic compliance and operational check that stands between a campaign and a phone ringing. It runs server-side, it is the same code every time, and the model is never consulted — which is why the codes below are worth learning. A check either blocks (error) or needs acknowledging (warning). Preflight passes when there are no errors, whatever the warnings say.

Before you start

Running a preflight needs the voice edit permission. Viewers see results only after someone with the permission has run one.

When it runs

Three times, and this catches people out:

  1. At approval — and again inside the Approve dialog, so a stale pass is not accepted.
  2. At launch, resume included. Launch is refused if any check fails, even if approval succeeded an hour earlier.
  3. Before every single dial, with the lead's own checks added on top.

The panel says it plainly: Compliance checks re-run server-side at approval, launch, and before every dial.

How to read a row

Each row carries a code (the machine name, worth quoting in a support message), a severity, a plain-English message, a remediation line, and — for per-lead checks — the number of leads affected. The remediation text comes from the check itself, not from a help article, so it is always accurate for your exact situation.

Campaign checks that block

These are checked before approval, before launch, and again before every dial.

CodeWhat it meansHow to clear it
emergency_stop_activeThe workspace emergency stop is on. Every campaign is paused and no launch can succeedClear it in Settings → Voice & Telephony → Emergency stop
agent_version_unpublishedThe campaign points at an agent draftPublish the agent version, or select a published one on the campaign
product_version_unpublishedThe campaign points at a product draftPublish the product version, or select a published one
disclosure_missingNo AI disclosure text is configuredFill Honest disclosure wording on the agent version, then publish it
recording_policy_missingThe workspace has never chosen a recording policySet Recording policy in Settings → Voice & Telephony
calling_window_missingThe campaign has no calling windows at allConfigure at least one allowed day and time window
transfer_unconfiguredAllow human transfer is on with an empty destinationSet a Destination number in Tools and guardrails, or switch transfer off

transfer_unconfigured is the most common first failure

Turning on Allow human transfer reveals the destination fields but does not require them, so it is easy to leave the number blank and move on. The check fires at approval, long after you have forgotten. If you are not actually transferring anyone yet, switch Allow human transfer off — that clears it too.

Caller ID and live-call checks

These only fire when the workspace is on a live voice runtime. On the default mock runtime they are skipped entirely — which is why a campaign can look perfectly healthy and still never dial a real number.

CodeWhat it meansHow to clear it
caller_id_missingNo approved caller number is selected on the campaignSelect an active, approved caller number in the campaign settings
caller_id_inactiveThe selected number exists but is not activatedActivate it in the telephony settings, or choose another
caller_id_not_allowedThe number is not allowed for this campaignAllow the number for the campaign in the phone-number settings
live_calls_disabledLive calling is off at the platform levelNot clearable from the admin. Live dialing is armed by Zyan — contact support
allowlist_emptyThe campaign is in test mode and the live-call allowlist is empty, so nothing is dialableVerified test destinations must be added to the allowlist at the platform level

You cannot arm live calling from Settings

live_calls_disabled and allowlist_empty name platform environment settings, not fields in the admin portal. No toggle in SettingsVoice & Telephony clears them. Until Zyan arms live dialing for your workspace, use Voice Lab, scenario simulation, or a live usability test to a saved test number.

External verified caller ID

Using a verified number that Zyan does not own is behind an experimental flag and restricted to test-mode campaigns. Three codes come out of it:

CodeSeverityWhat it meansHow to clear it
external_caller_id_forbiddenErrorThe campaign's caller number is an external verified caller ID and the experimental flag is offUse a platform-owned number instead. The flag is not exposed in the admin — contact Zyan support if you need it
external_caller_id_requires_test_modeErrorThe flag is on, but the campaign is not in test modeKeep Test campaign ticked while using an external caller ID
external_caller_id_experimentalWarningThe campaign will display an external verified caller ID; attestation, reputation and callback behaviour may differ from a platform-owned numberAcknowledge it at approval, then watch attestation after each call and be ready to disable

external_caller_id_forbidden is not a mistake you made

It means the number you chose is a verified caller ID rather than a number owned by the platform, and that path is experimental. The fix is to select a different caller number, not to change a setting. There is no in-app switch for the flag.

Audience checks

CodeSeverityWhat it meansHow to clear it
audience_policy_deniedErrorAudience classification is consumer cold, which is denied by default policyReclassify: consent-backed leads, internal test numbers, or a counsel-approved B2B classification. There is no override
audience_b2b_ackWarningB2B calling rules vary by jurisdiction and industryConfirm counsel has reviewed the applicable federal, state, industry, recording, disclosure, calling-hour and do-not-call rules, then type the acknowledgment at approval

Per-lead checks

These are added to the campaign checks immediately before each attempt. They appear in the preflight panel with an affected-lead count, and in the Block reason column on the campaign's Leads table.

CodeWhat it meansHow to clear it
invalid_destinationThe lead's number is not valid E.164Fix or remove the lead's phone number
lead_suppressedThe lead is suppressed or previously opted outSuppressed leads are never dialed. Remove the lead from the campaign
wrong_numberThe number was previously recorded as a wrong numberUpdate the lead with a corrected number before any further attempt
no_consentThe campaign is consent-backed and this lead has no valid consent recordAttach a consent record with evidence, or reclassify the campaign under an approved policy
consent_expiredThe lead's consent record has expiredRe-obtain consent, or remove the lead
outside_calling_windowThe lead's local time is outside the campaign's windowsNothing to fix — the dialer defers until the next window opens
max_attempts_reachedThe lead has used all its allowed attemptsNo further attempts are permitted for that lead
cooldown_activeThe retry cooldown has not elapsed since the last attemptWait. The remediation names the exact number of minutes left
destination_not_allowlistedThe campaign is in test mode and this destination is not on the live-call allowlistAdd the number to the allowlist at the platform level, or take the campaign out of test mode through the approval flow

Checks that defer rather than stop

Three checks are temporary by nature. The per-lead errors outside_calling_window and cooldown_active both mean not yet: the dialer defers the attempt and comes back. daily_cap_reached is a campaign-level warning that resolves itself the next day.

CodeSeverityBehaviour
outside_calling_windowError, per leadDeferred until the lead's next window opens
cooldown_activeError, per leadDeferred until the cooldown elapses
daily_cap_reachedWarning, campaignDialing resumes on the next allowed day, or raise Daily cap

A roster full of outside_calling_window at four in the afternoon is not a fault. A roster full of it at eleven in the morning means your Timezone fallback is wrong for those leads.

Warnings and the typed acknowledgment

Warnings do not block preflight, but they do block the Approve dialog until you type an exact acknowledgment phrase. The label reads Type “…” to continue and it is matched byte-for-byte — this is an API contract, not free text. Copy the phrase from the label rather than typing it from memory.

Troubleshooting

SymptomCauseFix
Preflight passed at approval and the launch was still refusedPreflight re-runs at launch; something changed in betweenRun it again and read the new rows — the emergency stop and version status are the usual culprits
A check names an environment setting you cannot findlive_calls_disabled, allowlist_empty and the external caller ID flag are platform-levelThey are not exposed in the admin portal — contact Zyan support
Preflight looks clean but no real calls happenThe mock runtime skips the caller-ID and live-call checks entirelyA clean preflight on the mock runtime is not proof of live readiness
The same lead is blocked every time you lookmax_attempts_reached or lead_suppressed are permanent for that leadCorrect the record, or remove the lead
Approve stays disabled with no visible errorA warning is present and the acknowledgment has not been typed exactlyCopy the phrase from the label
A campaign that ran yesterday now fails on the agent versionPublishing a new agent version archives the old oneA pinned version stays usable after approval; drafts must point at the current published version