Troubleshooting: Ads hub failures
The Ads hub has five failure states that look broken but are each a specific, expected gate: every endpoint answersCHANNEL_UNAVAILABLE until a
Meta Ad Account is connected, the test conversion panel only records sends
Meta confirmed, a conversion post without a match key is refused, an audience
sync caps at 100,000 members, and the Lead Ads paste box rejects text that is
not JSON. Each has a fixed cause and a fixed fix. Work the section that
matches your symptom; the field-level vocabulary for every surface on the hub
is in the Ads hub reference.
Everything returns CHANNEL_UNAVAILABLE
Until a connection is stored, every Ads endpoint exceptGET /ads/status
returns the same envelope:
If
CHANNEL_UNAVAILABLE persists after a connect that GET /ads/status
confirms with connected: true, you are calling a different organization
than the one you connected (API key or session belongs to another workspace).
The conversion test event never turns green
Send Test Event on the Conversions tab posts a test event to the Meta Conversions API. The Recent Test Events panel next to it is session-scoped and only ever logs a send Meta confirmed withevents_received > 0. A
rejected send therefore never turns green and never appears in the panel.
That is the panel working as designed, not a rendering bug:
A confirmed send renders the received count (for example “1 received”) in the
panel. If repeated sends across several minutes all return 200 with nothing
logged, the dataset/ad-account pairing at Meta is the thing to inspect; the
flash of the connection is not.
422 on Post Conversion
POST /ads/conversions requires at least one match key in user_data:
ctwa_clid (the deterministic Click-to-WhatsApp click id), or phone,
email, external_id (Orbit SHA-256 hashes these before they leave the
platform; send them raw). A body with none of the four is refused with a
deterministic VALIDATION_ERROR envelope (HTTP 400 on this endpoint; the
other Ads writes use 422) whose details name the missing match key. Never
retry it verbatim; add a key and send once.
Match-key menu:
Worked body with the deterministic key:
CHANNEL_UNAVAILABLE, the account or dataset is the
problem and the previous two sections apply.
Audience sync reports truncated: true
POST /ads/audiences/:audienceId/sync resolves the linked segment’s members
and uploads them hashed, capped at 100,000 members per sync. Past the cap the
response carries truncated: true:
matched is the members resolved from the segment, sent the members handed
to Meta. Sync metadata (last_synced_at, last_sync_count) on the audience
row updates after each successful sync.
Lead Ads paste rejected / import tallies
The Lead Ads tab accepts the rawleadgen webhook batch Meta delivered to
your endpoint. The paste box checks one thing client-side: the text must
parse as JSON. Anything else is rejected in the browser with “That doesn’t
look like valid JSON. Paste the Meta leadgen webhook payload.” and nothing is
sent. Valid JSON that carries no leadgen changes is sent and answers
received: 0.
After a real import, the Last import panel shows the tally:
received always equals fetched + fetch_failures + skipped_no_contact;
the created/updated/duplicates split applies to the fetched drafts. Every
imported lead goes through the same dedupe, consent, and audit path as a CSV
import, so a lead that appears under updated or duplicates was not lost —
it matched a contact you already have.
See also
- Ads hub reference — the field-level vocabulary for the connection cards, the four tabs, and the role matrix.
- Ads console walkthrough — the object-verb map of the hub, including its troubleshooting notes.
- Ads attribution and lead ingestion —
the first-touch attribution model behind
ctwa_clidand lead ingestion. - Ads hub: first Meta connect, first attributed lead — the narrative connect-to-first-lead walkthrough.
- Troubleshooting hub — the index of every runbook.