Signup forms

Forms & lead capture

Signup forms

Forms grow your subscribed audience: a popup or embedded signup that collects an email (and optionally a name, phone or birthday) with proper consent. New sign-ups become contacts and can trigger a welcome automation.

On this page28 sections

Create a form#

  1. Go to Forms and create a new form.
  2. Choose the type and design it: heading, fields, button, image and styling. Pictures follow the same formats and limits as in the email builder: see Uploading images.
  3. Add the fields you need. Email is required; a date field can capture birthdays for a birthday automation.
  4. Publish. Views and submissions are tracked on the Forms list.

Consent matters

A signup is explicit opt-in: the cleanest way to grow a healthy, deliverable list. Make clear what people are subscribing to.

What happens on submit#

  • With double opt-in off (the default), the person becomes a subscribed contact (de-duplicated by email).
  • With double opt-in on, they stay pending until they confirm the email; they are not subscribed yet.
  • Any welcome automation enrolls them once they are subscribed.
  • Every field they filled in lands on their profile: see Where each field is saved.

Where each field is saved#

Every answer a form collects is saved on the contact, under the same rules a CSV import or the contacts API follow:

  • An email or phone field is the contact's email or phone.
  • A text field whose label says name, surname or full name is the contact's name; a single full-name field is split into first and last name.
  • A date field is the contact's birthday (it powers the birthday automation) unless you map it to a custom property.
  • A field recognised as phone or birthday, in Italian or English, goes to that field.
  • A field recognised as part of the address goes to the contact's address fields, whatever you called it: Indirizzo or Address becomes address, Città becomes city, Provincia becomes state, Cap or ZIP becomes postal_code, Paese becomes country. These are the same fields a CSV import or the contacts API fill, so you can filter a segment on them and export them as one column each.
  • Every other field (a dropdown, a checkbox, anything you ask) is saved as a custom property named after the field's label: Codice fiscale becomes codice_fiscale, Taglia becomes taglia.

To choose the destination yourself, select the field in the designer: Save to customer profile offers First name, Last name, Full name and Custom property with the name you want. The line under it always says where the answer will be saved.

You find every answer under Audience → the contact → Customer details: the address fields under their own names (Address, City, State, Postal/Zip code, Country), the other properties under the name you gave them. A later submission by the same person updates the values; a submission that leaves a field blank never erases an earlier answer.

Already-subscribed visitors#

When someone submits an email that's already subscribed, the form shows a dedicated “already subscribed” step instead of a generic thank-you, and its message is fully customizable in the form designer.

Double opt-in#

Double opt-in is off by default. Open the form, go to the Behavior tab, and switch on Enable double opt-in. Who signs up then receives a confirmation email and becomes a contact only after they confirm. A cleaner list, and one that matches the rules that require a confirmed opt-in.

  1. Open Forms, open the form, click Behavior.
  2. Switch on Enable double opt-in.
  3. Set Link validity (days) between 1 and 60 (7 by default). After that the confirmation link shows Link expired and they must sign up again.
  4. Click Edit the confirmation email and keep {{ confirmation_url }} on a button or a link: without it nobody can confirm. The editor warns you if the link is missing.
  5. Optionally fill Confirmation page title and Confirmation page text, or leave them empty for Sendcore's defaults.
  • A pending confirmation does not redirect to a thank-you URL: the visitor still has to open their inbox. Count those sign-ups with the conversion events, not with a thank-you page.
  • Conversion events (browser Pixel, dataLayer, Conversions API) fire at submission, before the confirmation click, so a pending confirmation still counts as a conversion.
  • Turning it off later does not confirm people who are still pending.

Where forms appear#

A popup needs no setup per form: once your store is connected, every published popup shows up on its own. Through the theme app embed on Shopify, and through the Sendcore plugin or script on WordPress / WooCommerce.

An embedded form sits inside the page: footer, homepage, contact page, sidebar. Open the form: the Where to place it panel shows two different things, and they are not interchangeable. In the layout panel, Maximum width can cap the form instead of letting it stretch to the full container: choose Full or Narrow.

Embedded forms on Shopify#

The Sendcore form theme block has a Form ID field. That field wants the ID string from Where to place it: a UUID, not the HTML snippet.

  1. In Sendcore go to Forms, open an Embedded form, and copy the Form ID from Where to place it.
  2. In Shopify go to Online Store → Themes → Customize.
  3. Add the Sendcore form block where the form should sit.
  4. Paste the Form ID into the block's Form ID field. Leave it empty to show your published embedded form.
  5. Save.

The HTML snippet in the same panel is the other path: paste it into a Custom Liquid block (or any HTML) if you are editing code instead of using the Sendcore form block. It looks like this:

html
<div data-sendcore-form="YOUR-FORM-ID"></div>

Form ID vs HTML snippet

The Form ID field in Shopify wants only the ID. The HTML snippet is for a Custom Liquid or HTML block. Do not paste the snippet into the Form ID field: that is why the form would not appear.

Your theme cannot hide or restyle the form#

Once the block is on the page, nothing else is needed for the form to show up: no theme setting, no custom CSS. Sendcore draws the form inside its own <sendcore-form> element within the block, sealed off from the theme's stylesheet. Theme rules that hide empty containers (Dawn and the many themes built on it do this) or restyle inputs and buttons never reach it, so the form always looks exactly as you designed it in Sendcore. To add space around the form, use the section's padding settings in the theme editor rather than CSS on the block.

Embedded forms on WordPress / WooCommerce#

Same split: the Sendcore form block wants the Form ID string; a Custom HTML block wants the HTML snippet (or the [sendcore_form] shortcode). Step by step: Forms on WooCommerce.

Never touched WordPress before? Follow the click-by-click Forms on WooCommerce guide.

Who sees a popup#

For a Popup or Flyout, the right-hand drawer controls when it appears. Open the form: the drawer has Display, Show the form, Frequency, Targeting and Pages.

  • Show the form: Immediately, After a delay, After scrolling the page or On exit intent.
  • Frequency: whether a popup the visitor closed comes back, and when. See How often a popup comes back.
  • Visitor targeting options: All visitors, Don't show to existing contacts, Show to existing contacts or Target by specific segment. See Show a form only to some visitors.
  • Location targeting: Off, Show to visitors in or Do not show to visitors in the countries you search.
  • Source targeting: show or hide by how the visit arrived, including Email, SMS, or Push (visits from a message link: Sendcore does not send SMS or push), plus Direct, Organic search, Google Ads, Facebook and Instagram.
  • Also appear on out-of-stock product pages: off by default.

On the Behavior tab, Scheduling sets a Start date and End date so a sale popup can turn itself off.

Which pages#

Still in the drawer, Pages decides on which URLs the form may appear:

  • All pages.
  • Specific pages only.
  • All except specific pages.

One path per line (e.g. /collections/sale). Use * as a wildcard. Paths are matched against the page path, not the full domain.

How often a popup comes back#

A popup or flyout that a visitor closes without subscribing comes back when you decide. You find Frequency under Display, both in the editor's Behavior tab and in the drawer on the Forms list: they edit the same setting.

  • Limit form appearance on: once a visitor closes the form, however they close it (the ×, a close button, the Esc key, a click on the backdrop), it does not show again for the time you set, from 1 to 999 Seconds, Minutes, Hours or Days. The count starts at the close: with 5 Days, a visitor who closes it on Monday morning can see it again from Saturday morning.
  • Limit form appearance off: the form appears on every page load, even right after it was closed.
  • Only closing starts the count. A flyout left open while the visitor keeps browsing shows again on the next page.
  • Whatever you choose, a visitor who subscribes through the form does not see it again on that browser.
  • A new form starts at 1 Hour. Embedded forms have no frequency: they are part of the page and always show where you placed them.

Testing your popup?

Once you close it, it stays away for the time you set, on your own browser too. To see it again right away, open the site in a private window, or switch Limit form appearance off while you test.

Forms saved before this setting existed kept the closest equivalent of their choice: Once per session became 1 hour, Once per day 1 day, Every visit and Until they sign up the limit switched off.

Show a form only to some visitors#

Open the form, go to the Behavior tab and open Targeting. Under Visitor targeting options choose who the form is for. It works the same for popups, flyouts and embedded forms: an embedded form that is not meant for the visitor leaves its spot on the page empty.

  • All visitors: everyone. This is the default.
  • Don't show to existing contacts: for people you don't know yet, such as a welcome discount.
  • Show to existing contacts: for people you already know, such as a survey or an offer for customers.
  • Target by specific segment: only for the members of the segments you pick, as explained below.

Who counts as an existing contact#

Sendcore decides in the visitor's browser, as the page loads. A visitor is an existing contact when, in that browser:

  • they left their email in one of your Sendcore forms, or in the "Notify me when it's back in stock" box;
  • they arrived from a link in one of your Sendcore emails, on that visit and every later one;
  • they are logged into their customer account on your store.

Everyone else is a new visitor, even when their email is already among your contacts: on a new phone, or after clearing the browser, Sendcore cannot tell who they are until they log in, sign up or click a link in one of your emails.

Target by specific segment#

Pick the segments from the two lists that appear, up to 10 in each:

  • Show to members of: the form shows only to members of at least one of these segments. Leave it empty to show it to everyone.
  • Don't show to members of: members of any of these segments never see the form, even if they also belong to a segment in the first list. Exclusion always wins.
  • With both lists empty, the form shows to every visitor.
  • A segment you delete later shows as Deleted segment: it has no members any more, so remove it or pick another one.

Segments only recognise logged-in customers

Your store tells Sendcore who a visitor is only when they are logged into their customer account. To Sendcore, everyone else belongs to no segment: they never see a form that uses Show to members of, and always see one that only uses Don't show to members of. To reach visitors who are not logged in, choose Don't show to existing contacts or Show to existing contacts instead.
  • Shopify: nothing to set up. The store vouches for the logged-in customer through the Sendcore app.
  • WooCommerce: needs the Sendcore plugin from version 1.2.0, which signs the logged-in customer's identity. A page a caching plugin cached for logged-in users can carry a stale identity: until the cache refreshes, Sendcore treats that customer as not logged in. Most caching plugins do not cache logged-in pages.
  • The check takes a moment once the page has loaded. If Sendcore cannot answer within a couple of seconds, the form stays hidden on that page: a form meant for some customers never reaches the wrong ones.
  • Nobody can ask Sendcore which segments someone else belongs to: the answer only ever concerns the customer your store vouched for.

Track sign-ups as conversions (Meta Ads, Google Tag Manager)#

Running ads to a signup form? The conversion you want the campaign to learn from is a successful subscription: the moment Sendcore has actually accepted the email. Sendcore gives you three ways to count exactly that in the browser, plus the server-side Conversions API for Meta. They can be combined; pick the ones your setup supports.

Why not track the click on the button?

A click happens before anything is checked. It fires on an empty or misspelled email, on someone who is already subscribed, twice on a double press, and on people who close the form right after. A custom conversion built on the click therefore over-counts, and, worse, it teaches the ad platform to find people who click, not people who subscribe. Every option below fires only when the subscription went through.

1. A thank-you page: works today, nothing to install#

The simplest and most robust option, and it needs no code: after a successful submission the form sends the visitor to a page of your site, and your ad platform counts the visit to that page as the conversion. Because the form only redirects once Sendcore has accepted the subscription, the page is reached by real sign-ups and nobody else.

  1. Create a thank-you page on your site, for example /thanks. Keep it out of menus and search results (a noindex tag is enough) so only people arriving from the form ever reach it.
  2. Open the form → Behavior → After submission, choose Redirect to a URL and paste the page's full address.
  3. In Meta Events Manager create a custom conversion with the rule URL contains /thanks, or add the Pixel's standard Lead event to that page, then pick it as the campaign's conversion goal.
  4. Google Ads and GA4 work the same way: a conversion on the page view of /thanks.

The Shopify-safe option

The Meta Pixel installed through Shopify's Facebook & Instagram channel runs in Shopify's sandbox: it only sees page views, never a popup on the page. The thank-you page is a page view, so this option works there with nothing else to install.

Double opt-in

While a confirmation is pending the form does not redirect (the visitor still has to open their inbox) so a double opt-in form should rely on the events below instead. They fire at submission either way.

2. A Meta Pixel event fired by the form#

Open the form → Behavior → Conversion tracking and choose the event: Lead (the usual choice for a signup), CompleteRegistration, Subscribe, Contact or a custom name. When the Pixel is on the page as the fbq global (installed by hand in the theme or through a tag manager) Sendcore fires it on every successful submission, with the form's name as content_name and a unique eventID that the server-side Conversions API below reuses, so Meta counts the two once.

  • It fires once per person: a re-submission by someone already subscribed is not a new lead and does not count.
  • It fires before any redirect, so it also works together with option 1.
  • Sendcore does not install the Pixel: it fires the one already on your site. With no fbq on the page (never installed, installed only through Shopify's Facebook & Instagram channel, blocked by an ad blocker) nothing fires and nothing breaks, and the signup is saved as always. The Conversions API below covers exactly those cases.

3. Google Tag Manager and your own scripts#

Every successful submission, on every form, pushes an event to the dataLayer and dispatches a DOM event on window, whatever tags you run:

JavaScript
// Google Tag Manager. Trigger: Custom Event, event name "sendcore_form_submitted"
dataLayer.push({
  event: "sendcore_form_submitted",
  sendcore_form_id: "…",
  sendcore_form_name: "Newsletter popup",
  sendcore_form_type: "popup",           // popup | flyout | embedded
  sendcore_shop: "your-store.myshopify.com",
  sendcore_already_subscribed: false,    // true when the email was already subscribed
  sendcore_pending_confirmation: false,  // true while a double opt-in is pending
  sendcore_event_id: "…"                 // the same id the Meta Pixel event carries
});

// Any script on the page
window.addEventListener("sendcore:form:submitted", (e) => {
  // e.detail: { formId, formName, formType, shop, alreadySubscribed, pendingConfirmation, eventId }
});

In Tag Manager, add a Custom Event trigger named sendcore_form_submitted and attach your Meta Pixel, Google Ads or GA4 tag to it. To count new leads only, filter the trigger on sendcore_already_subscribed equals false.

Conversions API: report the conversion to Meta from the server#

The Pixel event of option 2 lives in the visitor's browser, and a browser is an unreliable place for a conversion to live: on Shopify the Pixel installed through the Facebook & Instagram channel never sees the popup, ad blockers and tracking prevention stop it on a growing share of visitors, and a redirect can cut it off mid-flight. Meta's Conversions API solves this: Sendcore reports the conversion from our servers the moment the subscription is accepted, with no browser involved.

You set it up once per workspace and it works for every form. For each submission of a form that has a Meta event chosen, Sendcore sends that same event to Meta server-side with the same event_id the browser Pixel uses: when both arrive Meta keeps one, and when only the server one arrives the conversion is still counted. Nothing else changes: the thank-you page and the Tag Manager event keep working as before.

Do you need these steps?

The setting that is always required is the event chosen on each form, under Behavior → Conversion tracking: that is what makes a signup a conversion, for the browser Pixel and for the Conversions API alike. If your Pixel is already on the page as fbq (installed in your theme or through a tag manager), that event alone is enough and Meta counts the conversion. Everything below adds a second channel for the same conversion, reported from our servers, and it is what makes the difference when the browser cannot report it: the Pixel comes from Shopify's Facebook & Instagram channel and the form is a popup, the visitor runs an ad blocker or tracking prevention, a redirect cuts the page off right after the submission, or no Pixel is installed at all.

What you need#

  • A Meta Business account with a Pixel (Meta now calls it a dataset) on the ad account that runs the campaign.
  • Permission to manage that Pixel in Events Manager: that is where the token is generated. No app review or approval from Meta is involved.
  • In Sendcore, the Owner or Admin role: the settings live in Settings → Integrations.

Step 1: generate the access token in Meta#

  1. Open Meta Events Manager (business.facebook.com/events_manager) and select the Pixel your campaign uses.
  2. Open the Settings tab and scroll down to the Conversions API section.
  3. Under Set up manually, click Generate access token. Meta may first ask you to choose the Business account that owns the Pixel. Copy the token: a long string that starts with EAA.
  4. At the top of the same page, note the Pixel ID (or Dataset ID): a number of about 15 digits.

Treat the token like a password

Whoever holds the token can send events to your Pixel. Paste it into Sendcore only, never into emails or chats. If it leaks, delete it from the same Meta screen, generate a new one and paste the new one into Sendcore: the old one stops working immediately.

Step 2: paste it into Sendcore#

  1. Go to Settings → Integrations and find the Meta Conversions API card.
  2. Paste the Pixel ID and the Access token, leave the test event code empty for now, and click Save.
  3. The card now says Active and shows the last four characters of the token. The token stays on our servers and is never displayed again: paste a new one only to replace it.

Step 3: choose the event on each form#

The Conversions API sends exactly the event you choose per form under Behavior → Conversion tracking (Lead, CompleteRegistration, Subscribe, Contact or a custom name). A form with no event chosen sends nothing, so you decide form by form which signups are conversions. If you already set the event for the browser Pixel, there is nothing more to do.

Step 4: check it with a test event#

  1. In Events Manager open the Test events tab: it shows a code like TEST12345.
  2. Paste it into the Test event code field of the Sendcore card, click Save, then Send a test event: within seconds a Lead event named Sendcore test appears in that tab.
  3. Now submit one of your own forms on your site: the submission shows up in the same tab, with the event you chose and the form's name.
  4. The code switches itself off after 24 hours (the card shows until when) and events then go to your normal reports. To stop earlier, clear the field and click Save.

While a test code is active

Meta shows events that carry a test code under Test events and does not count them as real conversions. That is why Sendcore honours a code for 24 hours only: a code forgotten in the field would otherwise quietly keep every real signup out of your campaign reports.

What Sendcore sends to Meta#

One event per new subscriber: the event name chosen on the form, the time, the event_id (the same id the browser Pixel event and the dataLayer's sendcore_event_id carry), action_source set to website, the page URL, the form's name as content_name and sendcore_form as content_category, plus the customer information Meta uses to match the person to a Meta account:

  • Email, phone, first name and last name, only the ones the form actually captured: each normalised and hashed with SHA-256 before it leaves our servers. Meta receives the hash, never the plain value.
  • The visitor's IP address and browser, and Meta's own _fbp and _fbc cookies when the browser has them. The _fbc value is also rebuilt from an fbclid in the page address, so visitors arriving from an ad match even on a page with no Pixel at all.
  • A hashed Sendcore visitor id as external_id.
  • Once per person: like the browser event, a re-submission by someone already subscribed is not a new conversion and is not sent.
  • Double opt-in: the event is sent at submission, before the confirmation click, so a pending confirmation counts as a conversion. Same as the browser event.
  • Best effort: if Meta is unreachable the submission still succeeds and the visitor notices nothing. The card shows the last event sent and the last error, so you can tell when something needs attention.

Privacy

Sending hashed customer data to Meta for ad measurement belongs in your privacy policy, exactly as the Pixel does. The consent you collect on your site applies here as well: the Conversions API is a more reliable channel, not a way around consent.

Troubleshooting#

  • Invalid OAuth access token (#190): the token was deleted or regenerated in Meta. Generate a new one and paste it into the card.
  • Nothing shows under Test events: check that the form has an event chosen under Behavior → Conversion tracking, that the card says Active, and that the test code was saved less than 24 hours ago.
  • Nothing reaches Meta and this card is not set up yet: the only channel is then the browser Pixel, which needs fbq on the page. Check that the Pixel is installed in your theme or through a tag manager, and remember that a Pixel installed through Shopify's Facebook & Instagram channel never sees a popup. Completing the steps above reports the conversion whatever the browser does.
  • Conversions look doubled: if a Tag Manager tag also sends the form's event to Meta, give it the dataLayer's sendcore_event_id as its Event ID: Meta only deduplicates events that carry the same id.

Beyond forms: the lead-intake API#

Collecting leads elsewhere (Meta Lead Ads, a landing page, Zapier)? Forward them into Sendcore with the lead-intake API: same result as a form submission.

Next steps