Collect signups from your own website.
Your in-store QR codes already capture members. This is the same thing for the web: a copy-paste HTML form you drop on any page. It posts to the same capture pipeline — so a website signup gets the identical consent record, welcome coupon, bot defenses and CCPA handling as a QR scan. No key, no SDK, no backend.
One form, posting to one endpoint
The form POSTs a small JSON body to your store's capture endpoint. The endpoint is CORS-enabled, so the form works from your own domain — no proxy or server code on your side:
Get your short code
Every store QR code has a short code (Stores → open a store → QR codes). Use it in the endpoint URL — it identifies the store and brand, no key needed.
Paste the form
Drop the self-contained snippet into any page. It renders the form, carries the bot defenses, and posts on submit.
Flash does the rest
One unified contact is created or updated, consent is recorded, and — if the QR code has a welcome coupon — it is issued, exactly like an in-store capture.
Set YOUR_SHORT_CODE and paste it in.
Self-contained — no external script or dependency. Style it to match your site; keep the hidden website honeypot and the _t timestamp — they are the bot defenses. You can also generate this snippet for a specific store in Stores → QR codes → “Embed on your website”.
<!-- SocialHub signup form — paste anywhere in your site's HTML -->
<form class="flash-signup" style="max-width:340px;font-family:sans-serif">
<input type="email" name="email" required placeholder="Email address"
style="width:100%;padding:10px;margin-bottom:8px;border:1px solid #ccc;border-radius:6px" />
<label style="display:block;font-size:13px;margin-bottom:8px">
<input type="checkbox" name="opt_in" checked /> Send me offers and updates
</label>
<!-- honeypot: real people never fill this; bots do -->
<input type="text" name="website" tabindex="-1" autocomplete="off"
style="position:absolute;left:-9999px" aria-hidden="true" />
<button type="submit" style="width:100%;padding:10px;border:0;border-radius:6px;background:#111;color:#fff;cursor:pointer">Sign up</button>
</form>
<script>
(function () {
var f = document.currentScript.previousElementSibling;
var t = Date.now(); // render time — the min-fill-time bot check
f.addEventListener("submit", function (e) {
e.preventDefault();
fetch("https://flash.socialhub.ai/api/flash/capture/YOUR_SHORT_CODE", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: f.email.value,
opt_in: f.opt_in.checked,
_t: String(t),
website: f.website.value // honeypot value
})
})
.then(function (r) { return r.json(); })
.then(function (d) { f.innerHTML = d && d.success ? "<p>Thanks — you're signed up!</p>" : "<p>Sorry, something went wrong.</p>"; })
.catch(function () { f.innerHTML = "<p>Sorry, something went wrong.</p>"; });
});
})();
</script>The JSON body
Send application/json. The response is { success: true, couponCode?, couponExpiresAt?, isRepeat } on acceptance, or a success:false with an error code otherwise.
| Field | Type | Notes |
|---|---|---|
| string | The subscriber's email. Required. | |
| opt_in | boolean | Marketing consent from your checkbox. Recorded with the capture. |
| _t | string | Milliseconds epoch when the form rendered — powers the min-fill-time bot check. Required. |
| website | string? | Honeypot field. Leave it hidden and empty; a filled value is treated as a bot. |
| fp | string? | Optional device fingerprint you generate. |
Bot defenses built in
The short code is public (it's in your page source), so the endpoint defends itself server-side — the same protections as the in-store capture flow:
Rate limiting · always on
The endpoint caps how many signups one source can send, so a copied short code cannot flood your list.
Honeypot + timing
The hidden website field and the _t render timestamp catch scripted submissions that fill hidden fields or submit instantly.
Disposable-email + duplicate guards
Throwaway domains are rejected and a repeat email on the same store is de-duplicated, not double-counted.
Honest about the limits
These raise the bar for a public form; for high-sensitivity ingestion, send server-to-server through the authenticated API instead.
Capture consent, not just an address
The opt-in is recorded
The opt_in checkbox is stored with the capture, so downstream sends respect whether the visitor agreed to marketing.
CCPA-aware
Same disclosure handling as the QR flow — California visitors get the required notice server-side.
No secrets in the page
Only the public short code is exposed. There is no API key to leak on your site.
Your consent banner first
If you use a consent manager, gate the form behind it so you only collect where you have the right to.
Capture everywhere your customers are
In store via QR, and now on your website — every signup lands in the same unified member profile.