# 06 — Go Live & Monitor

[← Back to README](README.md) · Previous: [05-facebook-ad.md](05-facebook-ad.md) · Related: [appendix-C-troubleshooting.md](appendix-C-troubleshooting.md)

---

Everything is built. Before you spend a dollar, you prove the whole chain works with a
**test lead** — no ad, no money, no waiting. Then you go live, and you keep a light hand on
the monitoring so a silent failure can never cost you days of leads again.

This file covers four things:

1. The smoke test (prove it works before spending)
2. The repeatable diagnosis playbook (when leads "stop")
3. Judging whether it's working (attribution + counting real bookings)
4. The consolidated go-live checklist

---

## 1. The smoke test — prove it works before spending

Meta gives you a tool that fakes a real lead submission, end to end, for free. Use it
before activating any ad.

**Tool:** Meta Lead Ads Testing Tool —
[developers.facebook.com/tools/lead-ads-testing](https://developers.facebook.com/tools/lead-ads-testing)

**Steps:**

1. In a terminal, start tailing the worker logs so you can watch the lead flow through in
   real time:

   ```
   npx wrangler tail <worker-name> --format pretty
   ```

   > NeatNow example (use your own): the worker is named `neatnow-api`, so the command is
   > `npx wrangler tail neatnow-api --format pretty`.

2. Open the Lead Ads Testing Tool and:
   - Select your **Page** (double-check it is *your* Page, not another business's).
   - Set the product to **Lead Retrieval**.
   - Pick your **live Form** (the one attached to your ad).
   - Click **Create Lead**.

3. Watch the log tail. A healthy run logs the lead being received, fetched, priced, and
   the texts being sent.

**Success = all three of these happen:**

- **(a)** The test "lead" receives the **auto-quote SMS** (it goes to the phone on the
  test lead — for a test submission this is typically your own profile's number).
- **(b)** **You** receive the **owner-notification SMS** (the "🧹 NEW FB LEAD" alert with
  the lead's details and the `Ad:` line).
- **(c)** A **backup row hits Formspree** (you get the backup email), if you wired
  Formspree.

If all three fire, your engine works. Now — and only now — activate your ad
([05-facebook-ad.md](05-facebook-ad.md)).

If something is missing, jump to the diagnosis playbook below.

---

## 2. The repeatable diagnosis playbook

The situation this catches: **you stop getting leads**, but Meta's Ads Manager still
shows leads arriving (and still charges you for them). That means leads ARE being created;
something between Facebook and your phone is broken. Here is how to find it in minutes.

### Step 1 — Tail the worker logs

```
npx wrangler tail <worker-name> --format pretty
```

### Step 2 — Fire a test lead

Use the Lead Ads Testing Tool exactly as in the smoke test above (Page → Lead Retrieval →
your Form → Create Lead). This gives you a controlled event to read in the logs.

### Step 3 — Read the log line and match it to the cause

The worker tags its log lines with prefixes like `FB webhook:`, `FB lead …`, and
`Graph API error …`. The fragments in the "What the log shows" column below are the
distinctive part to search for in your `wrangler tail` output.

| What the log shows | What it means | What to do |
|---|---|---|
| `failed to fetch lead` + `code 190 / subcode 460` | **The page token died** (almost always a Facebook password change or a Meta security reset) | Regenerate the never-expiring System User token — see [appendix-C-troubleshooting.md](appendix-C-troubleshooting.md) (the headline incident) |
| `owner notify failed: OpenPhone …` | **SMS provider key / number issue** | Check `OPENPHONE_API_KEY` and `OPENPHONE_FROM_NUMBER`; see Appendix C |
| `owner notify sent` **and** the text arrives | **The pipeline is healthy** | The problem is elsewhere (e.g. you are looking at the wrong number, or the ad simply is not delivering) |
| **Nothing logs at all** | **The webhook is not reaching the worker** — the app's `leadgen` subscription on the Page lapsed | Re-subscribe the app to the Page's `leadgen` field; see Appendix C |

### Step 4 — Confirm the token directly (when you suspect the token)

You can test the token without any test lead by asking the Graph API for the form's leads
directly:

```
GET https://graph.facebook.com/<version>/<FORM_ID>/leads?access_token=<TOKEN>
```

- A **list of leads** comes back → the token is healthy.
- An **auth error** (`code 190` — for a dead token, subcode 460) comes back → the token is
  dead or lacks permissions. Regenerate it (Appendix C).

> The reason the "I stopped getting leads" failure is so dangerous is that the original
> design failed **silently** — a dead token dropped every lead with only a buried log line
> as evidence. The hardened worker now **alerts you loudly** the instant a fetch fails, so
> you find out in minutes, not days. That fail-loud alert is described in
> [appendix-C-troubleshooting.md](appendix-C-troubleshooting.md) and the worker code in
> [04-the-worker.md](04-the-worker.md).

---

## 3. Judging whether it's working

### Every lead knows which ad produced it

Each lead carries its **`ad_id`**, and the owner-notification SMS includes an **`Ad:`** line
with that ID. So when a lead comes in, you immediately know which ad earned it. Keep a simple
note of which ad ID maps to which creative/offer and you can see, per ad, what is pulling.

### Your booking platform will undercount, so count bookings yourself

Here is the trap that can make the engine look worse than it is:

> For NeatNow, most leads that booked did so by **replying to the text**, not by completing an
> online form or checkout. So an online booking platform or CRM only records the few who
> self-serve online and misses anyone who booked over text. Our online count showed only a
> fraction of the bookings the engine actually produced.

So do not judge it by the online booking count. **Count real bookings by scanning each lead's
SMS thread** for signals that the lead became a paying job:

- "booked you in" / "you're booked for…"
- "charged the card" / payment confirmation
- a reply to your **review link** (you only send that after a completed job)

### What it looked like for NeatNow (our experience, not a promise)

We are deliberately **not** putting a single ROAS number on this. A one-time return figure
undersells what a lead engine actually does, so here is the honest picture instead:

- In about **two and a half months**, the engine captured **around 150 leads**.
- They are a mix: some are tire-kickers, some are real buyers. Expect both, that is normal.
- It produced real bookings, **including recurring clients** from Facebook ads, the
  repeat-revenue customers that matter most.

Why we will not reduce it to a multiple: a recurring client is not one job, they pay again and
again, so any single-period "X times return" understates them. And a lead that goes cold is not
dead, you can re-engage it later. Judge the engine over time on **bookings and recurring
signups**, not on a snapshot number.

> This guide stops at the automated quote. How you track replies, re-engage cold leads, and
> close them (your booking/CRM, a spreadsheet, your phone) is your own manual follow-up, out
> of scope here.

---

## 4. The consolidated go-live checklist

Walk this top to bottom before you turn on spend. (This is the new-owner setup distilled —
the deeper "why" behind each line is in [04-the-worker.md](04-the-worker.md) and
[appendix-C-troubleshooting.md](appendix-C-troubleshooting.md).)

- [ ] **System User created** in **Meta Business Suite → Settings → Users → System users**
      (older accounts: "Business Settings → Users → System Users"; both open the same place).
- [ ] **Page assigned to the System User with the Ads *and* Leads tasks** (the Ads task
      alone is NOT enough to read lead data — you must enable Leads too).
- [ ] **Never-expiring token generated** for the lead-webhook app, with all five
      permissions: `leads_retrieval`, `pages_read_engagement`, `pages_manage_ads`,
      `pages_show_list`, `ads_management`.
- [ ] **"Verify account" prompt completed** — Meta requires this account-verification step
      (password / 2FA) before it will show you the token.
- [ ] **All secrets set on the worker via `wrangler`** — the FB token, app secret, verify
      token, SMS API key, SMS "from" number, and your owner-notify phone.
- [ ] **App subscribed to the Page's `leadgen` webhook** (the GET handshake echoes
      `hub.challenge` when the verify token matches).
- [ ] **Smoke test passed** (Section 1 above) — auto-quote SMS, owner alert, and Formspree
      backup all fired — **before activating any ad.**

When every box is checked and the smoke test is green, activate your ad and watch the first
real leads come through your log tail.

---

If leads ever stop — or never start — go straight to the lookup table:
**[appendix-C-troubleshooting.md](appendix-C-troubleshooting.md)**. For the worker and
token internals, see **[04-the-worker.md](04-the-worker.md)**.
