> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useboom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Lead Capture

> A pop-up for your own site that collects emails and WhatsApp numbers, hands out a promo code through a small game, and starts a journey.

Lead Capture puts a pop-up on your website that asks visitors for their email
and WhatsApp number and gives them a promo code in return. You can show the code
straight away, or make it a game: **pick 1 of 3** cards, **spin the wheel**,
drop a ball down a **Plinko** board, **scratch** a card, pull a **slot machine**,
or open **1 of 3 gift boxes**.

Every submission becomes a lead in your [CDP](/cdp/overview) people, marked
`source: lead_capture`, and a `lead_captured` [event](/events), so a [journey](/journeys) can welcome the lead on WhatsApp or
email within seconds, while they still remember you.

<Note>
  Lead Capture is an add-on. If you don't see **Lead capture → Pop-ups** in
  the Boom app's left sidebar, ask your account manager to turn it on for your
  organization.
</Note>

## Create a pop-up

In the left sidebar, open **Lead capture → Pop-ups** and choose **New pop-up**, pick a
template, and give it a name and the site it will run on. Templates are finished
pop-ups (a big coupon, a newsletter sign-up, a full-screen offer, the wheel and
the other games) with their design and text already in English, Spanish and
Portuguese; choose **Blank** to start plain. Either way you only add your prizes
and codes. New pop-ups start **Paused**, so you can design one without it
showing to anyone.

The pop-up's page is a live preview with the settings beside it. The left
sidebar lists its sections, grouped under Setup, Look, Engage and Results; pick one and its settings open next to the preview.
A blue dot on a section means it has unsaved changes, and an orange dot means
something there needs fixing. Switching sections keeps your unsaved changes, and
**Save** saves them all at once.

On a phone the settings come first. Tap **Preview** at the top of the settings
to see the pop-up, and **Back to settings** to return.

| Section | What you set |
| - | - |
| **Install** | Status, how to install it (Shopify, script tag or your own button), and the sites allowed to load it. A checklist shows what is still missing before it can go live. |
| **Design** | **Browse templates** (replaces the design and text, keeps your prizes, sites and timing), a one-click **look**, then fine-tuning: layout (centered, split, corner card or full screen), where the image goes (inside, top banner or background), your brand colors, one of twelve fonts, button shape and corner roundness. **On phones** it opens from the bottom: as tall as each step needs, half the screen, or the whole screen. |
| **Content** | Every piece of text, in English, Spanish and Portuguese — including the big **offer** line ("\$250", "15% OFF"). Wrap words in `*asterisks*` to highlight them. Anything left blank uses the English text. Lines that start with `- ` in a body become a bulleted list. Optional small lines: one above the headline (shown on the quiz and the first form step too), one above the prize, and a label on the side photo ("SAVE UP TO 15%"). Under **Design → Highlighted words**, choose coloured text or a marker behind the words. At the end, **Under the code** adds a small table below the code, for example a volume offer ("−10%, 2 products", "−15%, 3 or more"). |
| **Form** | Which fields to ask for, the phone field's default country, an optional **ask first** screen (one "yes" before the form), and what happens after: show the code (optionally with a button that applies it in your store) or send it by message. |
| **Trigger** | When it opens: after a delay, after scrolling part of the page, whichever of those two comes first (e.g. 8 seconds or 40% of the page), when the visitor is about to leave, or only when they click a button you add. Whether it shows on phones, and how many days to wait before showing it again: counted from when someone closes it, or from any time it was shown ("once every 14 days"). |
| **Quiz** | Optional: up to three questions before the form, one tap or several picks each. See [Quiz](#quiz). |
| **Prizes** | The game, the **order of screens** (form first, or play first — see [Play first](#play-first)), and the prizes it can land on, each with its promo code and odds. |
| **Leads** | How many people it has collected, how many in the last 7 days compared with the 7 days before, and how many opted in. **See leads in People** opens your People list filtered to this pop-up. |

## Install

The **Install** section has a tab for each way to install the pop-up. If your
Shopify store is connected to Boom, the **Shopify** tab comes first; otherwise
you start on **Script tag**. **Rotate key** sits below the tabs and changes the
key in all of them; the confirmation explains what stops working.

### Shopify

Stores connected to Boom through their own Boom Shopify app do not need to edit
any code. The **Shopify** tab has two steps:

1. **Copy your key** (the `blc_live_…` value).
2. **Open theme editor.** The button opens your live theme on **App embeds** with
   **Boom Chat Widget** already switched on. Paste the key in **Lead Capture
   install key**, then click **Save**.

If you don't see a Lead Capture setting, open **Don't see Lead Capture?** in the
tab:

* **Turn the embed on yourself:** App embeds → **Boom Chat Widget**. In a Shopify
  admin in Spanish, that's **Tienda online → Temas → Personalizar →
  Incrustaciones de aplicaciones**.
* **No Lead Capture setting at all?** Your app needs updating; ask Boom.
* **The same embed has Enable AI Chat** (on by default) **and Enable WhatsApp.**
  Leave both off unless you use Boom's chat on your store, or turning the embed
  on also shows a chat bubble.

Your store's domain still has to be in **Allowed sites** (see below).

### Script tag

Copy the tag from the **Script tag** tab and paste it at the end of the page body on
every page that should show the pop-up:

```html theme={null}
<script async src="https://www.useboom.ai/widget/v1/lc/blc_live_YOUR_INSTALL_KEY"></script>
```

It is separate from the [web widget](/web-widget)'s tag; you can use either or
both. Like the widget's, the install key is public and identifies the pop-up — it
does not authorize anything.

Then add every site that hosts it under **Allowed sites**. Matching is exact:
`https://example.com` does not cover `https://www.example.com`. On any other site
the pop-up does not open, and your browser's console says why.

### Open it from your own button

The **Your own button** tab has a ready-made sample. Any button or link with the pop-up's install key in `data-boom-lead-capture-open`
opens it when clicked, whatever its trigger:

```html theme={null}
<button type="button" data-boom-lead-capture-open="blc_live_YOUR_INSTALL_KEY">
  Get my gift
</button>
```

The tag above must still be on the page. A button opens the pop-up even for a
visitor who closed it or already signed up, because they asked for it. Every
entry records a `lead_captured` event, a repeat one included (`repeat` is
`true`), so give a welcome journey a frequency cap or branch on `repeat` to
avoid welcoming the same person twice. Set the trigger to **On click** if it
should only ever open this way. That is also the
choice for a page where search ranking matters: a pop-up that covers a page as
soon as it loads on a phone can cost it.

## Apply the code in your store

Under **Form → After the form**, add an apply-code link and the prize screen gets
a button that opens your store with the code already applied. Write `{code}`
where the code goes. For Shopify:

```
https://your-store.com/discount/{code}
```

## Going live

**Set Active** is refused until the pop-up can keep its promise:

* at least one allowed site;
* it asks for an email or a WhatsApp number;
* a game has at least one prize;
* if it asks for a WhatsApp number, it has a consent sentence;
* if it plays first, it has a game.

While it is Active, changes that would break one of these are refused too —
pause it first.

## Prizes and games

Each visitor gets **one** prize, drawn on Boom's side using the odds you set. The
game only shows the result: whichever card or box the visitor picks, the wheel,
the ball and the reels land on the prize already drawn, and the scratch card hides it. Nothing on your page can change what a
visitor wins, and the promo codes are never sent to the page until a prize is
drawn.

Someone who enters again — same WhatsApp number, or the same email inbox, even
with a `+tag` or Gmail dots — gets the prize they got the first time.

<Tip>
  Wheel slices, Plinko slots, reels and gift tags are small. Lead with the value
  in each prize's label — "10% off", "Free shipping" — or give it a short label.
</Tip>

### Play first

By default the visitor leaves their details first and then plays to reveal the
prize. Set **Order of screens** to **Play first** (in **Prizes**, once a game is
picked) to turn it around: the visitor plays straight away, sees what they won
("You won! 10% off"), and then leaves their details to get the code. The
**ask first** screen and the quiz, when you use them, still come before the
game. The line over the form is the **Claim message** in **Content**; `{prize}`
in it becomes the prize's name, e.g. `Leave your details to get your {prize}.`

The prize is still drawn on Boom's side, when the game starts, and the code
still reaches the page only after the visitor has left their details. After the
form they see the code, or the message that it is on its way if you send it by
message. Someone who entered before still gets their first prize, even if the
game showed them another one, and the screen after the form shows the prize
they actually get. If the prize cannot be drawn when the game starts (a network
problem, for example), the pop-up falls back to the form first.

## Quiz

Turn on the quiz to ask up to three quick questions before the form, such as
"What would you like to work on?" with answers like Stress, Sleep or Energy.
Each question has two to twelve answers, one question per screen.

**One tap or several picks.** With **Answers they can pick** at 1, the visitor
taps one answer and moves on. Set it higher, say 3 for "pick up to 3", and the
answers show as tiles two to a row, with a counter ("2 of 3 chosen") and a
**Continue** button that works from the first pick.

Every answer is saved on the person under the question's **Saved as** name
(filled in from the question; you can rename it), and on the `lead_captured`
event, so a segment or a journey can branch on it. Answers are saved as written
in English, the base language, whatever language the visitor saw, so a condition
like `interest = "Sleep"` matches everyone. If the person already answered
before, their first answer is kept.

**Saved values.** Give an answer a **saved value**, a short code such as `sleep`
or `hormones` (lowercase letters, digits, `_` and `-`), and that code is stored
instead of the English text. A code survives rewording the answer, and a journey
can build a link from it, e.g. `/collections/need-{{need_primary}}`.

**Several picks are saved as a list**, in the order the visitor picked them,
e.g. `need = ["sleep", "stress"]`, and the first pick also as
`<name>_primary` (`need_primary = "sleep"`). Segments can match any pick in the
list ("need includes sleep"). Journey branches compare single values, so branch
on the `_primary` one. A question already live as one tap can't become
multi-pick under the same name, since its saved answers are text: give it a new
name.

An answer can also have a **link**, for example the collection that matches it.
The last screen then shows a button to it, with the words you choose for that
answer, and the link reaches your journey as `link_url`. Use `{code}` in the link
to apply the code as well, e.g.
`https://your-store.com/discount/{code}?redirect=/collections/sleep`. When the code
is sent by message, a link that contains `{code}` is left off the screen and only
reaches the journey.

<Tip>
  Keep it short: each extra question costs some visitors. One question that
  changes what you send is worth more than three that don't.
</Tip>

## Consent

When the pop-up asks for a WhatsApp number, it shows your consent sentence beside
an unticked box, and the visitor has to tick it to continue. Boom stores, with
each lead, whether they ticked it, the exact sentence they saw, the language it
was in, and when.

A visitor who leaves the box unticked (on a form that asks only for email) is
still saved as a lead, but is **not** enrolled in journeys.

The same goes for someone on your Do Not Contact list (in People), even if they
tick the box: they are saved, but not opted in and not enrolled, and their
event says `consent: false`.

A form that asks only for email can show the consent sentence as a **notice**
instead of a checkbox — submitting the form is then the agreement. Forms that ask
for a WhatsApp number always use the checkbox. Each lead records which of the
two it was.

**Progress bar.** Turn on **Form → Progress bar** to show a thin bar on top with one segment per screen (each quiz question, each form step, the game, the code), filled up to where the visitor is.

**A form in steps.** Under **Form → Steps** you can split the form into a few
screens, for example your email first and then an optional WhatsApp step with a
link like "I'd rather just use email". Each step has its own headline, button and
consent sentence. The visitor's details are sent once, at the end; someone who
skips the WhatsApp step, or closes the pop-up on it, is still saved with the email
they gave. Consent is kept per channel: the email step's sentence (often a notice)
opts them in to email, and the WhatsApp step always has a box to tick, which opts
them in to WhatsApp. When both were agreed, the lead records both sentences.

To link your terms and conditions, add the page under **Form → Terms and
conditions link** and mark the words that should link with asterisks in the
consent sentence (**Content**), for example `I accept the *terms and conditions*`.
Those words open your page in a new tab, and each lead records the link as
`consent_terms_url`. A pop-up with a terms link cannot go live until the sentence has marked words in every language you wrote it in.

## Use the lead in a journey

Start a journey with the **`lead_captured`** event. It appears in the journey
builder as soon as a pop-up is first set Active. Its properties are available as
message variables:

| Property | |
| - | - |
| `email`, `phone`, `displayName` | What the visitor entered |
| `promo_code`, `prize_label`, `prize_id` | The prize they won |
| `form_id`, `form_name` | Which pop-up |
| `consent` | Whether they ticked the consent box |
| `consent_method` | `checkbox` (they ticked it) or `notice` (submitting was agreeing) |
| `consent_text` | The exact sentence they agreed to — your record of the opt-in |
| `consent_terms_url` | The terms page the sentence linked to, when you set one |
| `locale` | The language the pop-up was shown in |
| `repeat` | `true` when this person had already entered |
| `page_url` | The page they submitted from |
| `link_url` | The link of the quiz answer they tapped, with the code filled in |
| Your quiz names | Each quiz answer, e.g. `interest`; a multi-pick question gives a list plus `<name>_primary` |

A typical welcome sends the promo code again on WhatsApp, then follows up if no
order arrives.

### Before you publish

* **Check for a WhatsApp number first.** `email` and `phone` are only there
  when the visitor gave them, so some leads arrive with an email and no number.
  Start the journey with a condition on `phone` **is set**: send WhatsApp on
  *Yes* and email on *No*. A WhatsApp step for someone with no number ends their
  journey there; an email step for someone with no email is skipped.
* **One journey hears every pop-up.** The trigger is the event name, so a
  `lead_captured` journey receives leads from all your pop-ups. To treat them
  differently, add a condition on `form_name` (or `form_id`) right after the
  start.
* **Publishing is going live.** The journey starts enrolling new leads the
  moment you publish it, so test the messages first.
* Visitors who left the consent box unticked are saved as leads but never
  enter a journey.

Anyone can type any email or number into a public form, so a submission never
changes a customer you already have — not their details, opt-ins or journeys.
Each visitor is a **lead** of their own (its ID starts with `lead_`, and it
carries `source: lead_capture`), even when the email or number matches a
customer. The same visitor coming back, on any of your pop-ups, is the same lead,
and gets the prize they were first given. To target leads in a segment, use
`source` is `lead_capture`.

In the **Leads** section each person counts once, however many times they submit,
and counts as opted in if any of their submissions was. The People list it opens
is filtered by the `leadCaptureForm` attribute, which holds the name of the last
pop-up or form the person used. Someone who later signs up through another one
is listed under that one, and renaming a pop-up leaves its earlier leads under
the old name. Seeing the list needs access to People; the counts do not.

## From the API or an AI tool

Everything above can also be done over [MCP](/use-mcp) or the REST API, with
five tools:

| Tool | Endpoint | Does |
| - | - | - |
| `lead_capture_forms_list` | `GET $BASE/lead-capture/forms` | Every pop-up with its status, game, allowed sites and install key |
| `lead_capture_forms_get` | `GET $BASE/lead-capture/forms/{formId}` | One pop-up in full: its config, the install tag and button tag, and what still stops it from going live |
| `lead_capture_forms_create` | `POST $BASE/lead-capture/forms` | Create a pop-up, paused, optionally from a template |
| `lead_capture_forms_update` | `PATCH $BASE/lead-capture/forms/{formId}` | Restyle with a template, edit any part of the config, replace the allowed sites, set it Active or Paused |
| `lead_capture_leads_list` | `GET $BASE/lead-capture/forms/{formId}/leads` | The leads one pop-up collected, newest first, with consent, prize and quiz answers |

`config` on an update is merged into the current one: objects merge key by key,
while a list (such as `prizes`) or a plain value replaces what was there. So
`{ "copy": { "headline": { "en": "Spin to win" } } }` changes only the English
headline, and sending `prizes` replaces the whole prize list. A field the config does not have, such as a misspelled one, is refused with its path instead of being ignored.

The same rules as the settings page apply. Setting a pop-up **Active** is
refused, with the reasons, until it is ready, and a change that would leave a
live pop-up unable to deliver what it promises is refused the same way. Rotating
the install key and archiving stay in the app.

Creating and changing pop-ups takes the **Owner** or **Admin** role, as they are
organization settings. Listing leads also needs access to customer data. The
tools answer `lead_capture_unavailable` until Lead Capture is switched on for
your organization.

## Your own analytics

After a successful submission the page receives a `boom:lead-captured` event on
`window`, carrying the install key and the prize id (no contact details):

```js theme={null}
window.addEventListener('boom:lead-captured', (event) => {
  analytics.track('Lead captured', event.detail);
});
```


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