Widgets
Create Popup
Create an on-site signup popup and get its embed script
POST
Create Popup
Create a saved popup and get the one-line script tag that deploys it. The popup
is published by default, so the script is live as soon as it is added to the
site. Trigger, targeting, audience, and duplicate handling stay server-side, so
the deployed script carries no API key.
Omit
listIds to capture into every list, matching the dashboard default.
Request
string
required
Internal popup name.
string
Starting design:
newsletter-modal, discount-offer, scratch-to-reveal,
countdown-launch, minimal-slide-in, exit-lead-magnet, live-demo,
launch-modal, paper-digest, stark-takeover, top-bar,
announcement-bar, or fullscreen-welcome. Defaults to newsletter-modal.
scratch-to-reveal starts with the reward enabled and the placeholder value
“10% off your first order”. Change it to your real offer and add your store’s
code through reward before you install the popup.string
draft or published. Defaults to published.string[]
Lists every signup joins. Omit or pass an empty array to capture into every
list.
string[]
Existing tag IDs to apply.
string
skip, merge, or overwrite. Defaults to skip.string
default:"reactivate"
What happens when a contact who unsubscribed from all email submits this popup
again.
reactivate resubscribes them and restores the popup’s lists.
double_opt_in sends your double opt-in confirmation email first and
resubscribes them once they confirm. Turning on double_opt_in needs a double
opt-in confirmation email and a sender profile; otherwise the request returns
400. If the email or sender is removed later, returning unsubscribed
contacts stay unsubscribed until you fix it. When workspace double opt-in is
on, contacts always confirm first. duplicateStrategy never changes
subscription status.boolean
default:"false"
Run a Cloudflare Turnstile check before each signup, invisibly for most
visitors. Signups that fail it must confirm by email before they are
subscribed. Turning it on needs a double opt-in confirmation email and a
sender profile, otherwise the request returns
400. See Bot protection
frame.string
Text for the popup’s first heading block.
string
Text for the popup’s first paragraph block.
string
Submit button label.
string
Confirmation shown when
redirectUrl is omitted.string
Optional HTTP or HTTPS success redirect.
string
modal, slide-in, floating-bar, or fullscreen.string
center, left, right, top, or bottom.object
When the popup opens:
{ "type": "delay" | "scroll" | "exit-intent" | "click" | "manual", "delaySeconds": 0-3600, "scrollPercent": 1-100, "clickSelector": "#join" }. A click trigger requires a clickSelector.object
Where it may show:
{ "domains": [], "paths": [], "excludedPaths": [], "device": "all" | "desktop" | "mobile" }. Empty arrays mean no restriction.
A path matches that page and everything under it (/blog covers
/blog/post), and / matches every page. End a path with $ to match only
that exact page (/$ is the home page). * matches any characters, and a
trailing slash is ignored. Full URLs, with or without https://, are
reduced to their path (query strings and fragments are ignored), and a bare
site URL such as https://example.com/ matches only the home page.object
Optional run window:
{ "startsAt": "2026-09-01T00:00:00Z", "endsAt": "2026-09-08T00:00:00Z" }. endsAt must be later than startsAt.object
How often one visitor sees it:
{ "maxDisplays": 1-100, "windowDays": 1-365 }.object
Media panel and urgency treatment:
{ "style": "none" | "accent" | "header" | "rail" | "image" | "countdown", "placement": "top" | "left" | "center" | "right", "imageUrl": "https://...", "imageAlt": "...", "countdownMinutes": 1-10080 }. The image style requires an https imageUrl - the image panel is
painted as a background, so a missing or blocked image would leave an empty
column beside your content.object
Scratch-to-reveal reward, merged key by key. When
enabled is true the
popup opens on a scratch card. The visitor scratches it, or taps Tap to
reveal, to see the public teaser, clicks Claim, enters their email, and
then sees the private value and optional code. See Scratch to reveal
rewards.{ "enabled": true, "value": "10% off your first order", "code": "WELCOME10", "heading": "Try your luck", "subheading": "...", "teaserEyebrow": "You've got a", "teaser": "Mystery discount", "claimText": "Claim", "coverText": "Scratch here", "coverStyle": "gold" | "silver" | "rose-gold" | "holographic" | "accent" | "custom", "coverColor": "#rrggbb", "coverTextColor": "#rrggbb" | null, "coverPattern": "sheen" | "sparkle" | "plain", "coverImageUrl": "https://..." | null, "prizeBackgroundColor": "#rrggbb" | null, "prizeTextColor": "#rrggbb" | null, "cardRadius": 0-32 }value (up to 120 characters) is required while enabled. code allows
letters, numbers, hyphens and underscores, up to 64 characters. While
enabled, the popup cannot redirect after submission (send redirectUrl: ""),
cannot use the floating-bar presentation, and no form field may write a
discount custom attribute. coverImageUrl must be https.object
Visual theme overrides:
accentColor, backgroundColor, textColor,
mutedTextColor, cardColor, borderColor (all #rrggbb), borderRadius
(0-32), headingFontFamily, bodyFontFamily, density.object[]
Complete replacement for the popup’s content blocks. The popup must keep
exactly one required email field and one submit button. See Content
blocks for each kind’s
properties.