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

# Ads hub reference

> Field-level reference for the Ads hub: the connection cards, the four tabs and their data vocabulary, the role matrix, connect and the typed-DISCONNECT guard, and the per-tab empty states.

# Ads hub reference

The **Ads** hub is the dashboard surface for the Meta click-to-chat ads loop: connect one Meta Ad Account per organization, run campaigns whose destination is a WhatsApp, Messenger, or Instagram Direct conversation, activate CDP segments as hashed Custom Audiences, ingest Meta lead-form submissions as contacts, and forward conversions back to Meta. This page is the field-level reference for what is on the hub; the narrative version lives in [Ads hub: first Meta connect, first attributed lead](/guides/ads-hub-overview).

Every control on the hub is tenant-owned: you connect your own Meta account, your segments define the audiences, and nothing renders until you put data in.

## The connection cards

Until a Meta Ad Account is connected, all four tabs render only the **Connect Meta Ad Account** card: a how-it-works list, a **Connect via Settings** button that deep-links to the Meta Ads connector card under **Settings > Channels**, and an **Early access** badge while the channel is still rolling out. Every Ads endpoint except `GET /ads/status` returns `CHANNEL_UNAVAILABLE` while no connection exists.

Once connected, the top of the hub shows:

| Card | What it carries |
| - | - |
| **Meta Ad Account Connected** | The connected `ad_account_id`, as a green banner at the top of Ad Campaigns. |
| **Currency** | The account's billing `currency`, recorded at connect. It drives how budgets, spend, and ROAS render everywhere downstream. |
| **Early access** | A badge while the channel rolls out. Connect works today; the badge only flags that the rollout is not finished. |

If `GET /ads/status` itself fails (a 401/403/500), the tab shows a real error with **Try again**, not the connect card. A failed status read never looks like "not connected yet."

## The four tabs

### Ad Campaigns

Create and manage click-to-chat campaigns.

| Surface | Vocabulary |
| - | - |
| Table columns | name, status, destination, daily budget in the account's billing currency, impressions, clicks, conversations |
| Statuses | `PAUSED` (every campaign is created paused), `ACTIVE` after **Resume** |
| Destinations | `WHATSAPP`, `MESSENGER`, `INSTAGRAM_DIRECT`; no other network exists in the hub |
| Header | search, status filter, **Create campaign** |
| Row menu | **Pause** / **Resume**, **Delete**, **View Insights** (impressions, reach, clicks, CTR, spend, CPC, conversations) |

### Conversions

The Meta Conversions API (CAPI) card, with three surfaces.

| Surface | Vocabulary |
| - | - |
| **Configuration** | Set the Meta **Dataset ID** once (`PUT /ads/conversions/dataset`). |
| **Test Conversion Event** | Sends a test event. The recent-test-events panel is session-scoped and logs only sends Meta confirmed with `events_received > 0`; a rejected send never becomes a false green. |
| **Post Conversion** | Posts a real attributed event with at least one match key: `ctwa_clid` (deterministic), or `phone` / `email` / `external_id` (SHA-256 hashed server-side). Without a match key the API rejects with 422. |

### Audiences

Custom Audiences linked to CDP segments.

| Surface | Vocabulary |
| - | - |
| Per-audience row | linked `segment_id`, member count, last-synced timestamp |
| Actions | create, **Sync members**, delete |
| Sync modes | `add` pushes membership for targeting; `remove` suppresses the same contacts |
| Hashing | email and phone are SHA-256 hashed before they leave Orbit |
| Cap | 100,000 members; past it, a sync reports `truncated: true` |

### Lead Ads

| Surface | Vocabulary |
| - | - |
| Paste box | Accepts the `leadgen` webhook batch Meta delivered to your endpoint; unparseable JSON is rejected client-side. |
| Last import tally | received / created / updated / duplicates / skipped / fetch failures |

Each `leadgen_id` is fetched from Meta's Graph and upserted through the same dedupe-consent-audit path as a CSV import.

Attribution has no tab by design: `GET /ads/ctwa/attribution` is the report. Read it over the API and render it wherever you need it; the model behind it is [Ads attribution and lead ingestion](/concepts/ads-attribution-lead-ingestion).

## Roles and permissions

| Action | Member seat | Owner / admin |
| - | - | - |
| Read campaigns, audiences, and the attribution API | yes | yes |
| Connect or disconnect the Meta Ad Account | no | yes |
| Create, update, or delete campaigns and audiences | no | yes |
| Configure, test, and post conversions | no | yes |
| Ingest Lead Ads batches | no | yes |

## Connect and the typed-DISCONNECT guard

Connect runs once per organization:

1. Click **Connect via Settings** on the hub's connect card, or go straight to **Settings > Channels > Meta Ads**.
2. Click **Connect Ad Account**. In Meta's OAuth dialog, sign in with the Facebook account that administers the business and pick the ad account.
3. Meta redirects back with an authorization code; the callback exchanges it over `POST /ads/oauth/exchange`, stores the long-lived token encrypted at rest, and records the `ad_account_id` and the billing `currency`.
4. Validate with `GET /ads/status`: a working connection returns `connected: true`, the `ad_account_id`, and `currency`. Every other Ads endpoint returns `CHANNEL_UNAVAILABLE` until it succeeds.

Disconnect stops live data flow from Meta and disables click-to-chat campaigns, and reconnecting means a fresh Meta re-authorization. The banner's **Disconnect** button therefore opens a dialog that requires typing `DISCONNECT` (all caps, case-sensitive) before the confirm button enables, and `DELETE /ads/disconnect` only fires after the phrase matches. The step-by-step walkthrough is in [Ads hub: first Meta connect, first attributed lead](/guides/ads-hub-overview); the object-verb map is in the [Ads console walkthrough](/guides/ads-console).

## Empty states

What renders per tab before Connect, and what an empty tile means after Connect.

| Tab | Pre-Connect | Post-Connect but empty | First check |
| - | - | - | - |
| Ad Campaigns | Connect card only | No campaign was created, or all were deleted; a search or status filter can also hide rows ("{N} filters active") | Clear filters, then create a campaign; it appears immediately, status `PAUSED` |
| Conversions | Connect card only | The tab always renders once connected; an empty Recent Test Events panel means no test was sent this session (the log is session-scoped), or the send was rejected counterside | Check the **Dataset ID** under **Configuration**; only sends with `events_received > 0` log |
| Audiences | Connect card only | No audience was created, or the linked segment matches zero contacts | Preview the segment first: `match_count: 0` ships an empty sync, and rows need an email or phone to count |
| Lead Ads | Connect card only | No import ran yet; the "Last import" tally appears only after the first paste | Read the tally: `received: 0` means the envelope carried no `leadgen` changes, `skipped_no_contact` means the lead had neither email nor phone, `fetch_failures` counts per-lead Graph fetch failures |

If a tab shows the connect card where you expected data, `GET /ads/status` still returns `connected: false`; re-run the OAuth exchange. The long-form version of each case is the FAQ in [the hub walkthrough](/guides/ads-hub-overview).

## Related docs

* [Ads API reference](/api-reference/ads): every endpoint behind the tiles.
* [Ads attribution and lead ingestion](/concepts/ads-attribution-lead-ingestion): the first-touch attribution model the hub implements.
* [Ads hub: first Meta connect, first attributed lead](/guides/ads-hub-overview): the narrative walkthrough this page references.
* [Ads console walkthrough](/guides/ads-console): the object-verb map and troubleshooting.
* [Meta Ads: segment to campaign to attribution](/guides/ads-activation): the loop over the API with copy-pasteable curl.
* [Your first attributed lead, end to end](/guides/ads-first-attributed-lead-walkthrough): the same loop in tab order.
* [Ads: scope and feature boundaries](/guides/ads-scope): the network, destination, and objective boundary.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.