Documentation

Docs

Everything from "drop the snippet" to reading your first leads — plus signed webhooks for pushing leads into your own tools.

Installation

1. Install the snippet

Add this single line of JavaScript to your site's <head> tag.

<script src="https://clickmemaybe.com/cmm/YOUR_SITE_KEY.js" defer></script>

Replace YOUR_SITE_KEY with the site key from your Websites page — or just copy the ready-made snippet from the site's Manage page.

2. CMS-specific guides

We support direct installation in WordPress (via plugin), Shopify (via theme.liquid), Webflow, Squarespace, and any custom HTML or React/Vue/Svelte SPA.

3. Verify the script

Open your site, then come back to the dashboard. Your site card should show "Live" within 30 seconds.

Widgets

Create your first widget

Pick a category, drop in your headline and CTA, and pick which site to show it on. You can refine targeting and design later.

Widget types

  • Popuppopup live
  • Sticky Barsticky_bar live
  • Floating CTAfloating_cta live
  • Inline Formform soon
  • Exit Intentexit_intent live
  • Countdowncountdown live
  • Social Proofsocial_proof live
  • Announcementannouncement soon
  • Callbackcallback live
  • Slide-inslide_in live
  • Welcome Matfullscreen soon
  • Multi-step / Quizmulti_step soon
  • Cookie Consentcookie_consent soon
  • Sticky Add-to-cartsticky_atc soon
  • Spin-to-winspin_to_win soon
  • Survey / NPSsurvey soon
  • Back-in-stockback_in_stock soon
  • Age Gateage_gate soon
  • Video Popupvideo_popup soon
  • Live Visitorslive_visitors soon

Design and brand

Each widget supports your brand colors, fonts, and a custom CSS escape hatch.

Targeting

Page rules

Show a widget only on selected paths (exact path such as /pricing, or a prefix such as /blog/*) and exclude paths where it must never appear. Exclusions win. Rules match the page path, not the query string.

Device

Target all devices, desktop only, or mobile only (viewports narrower than 768px). Geo, language, returning visitors, referrer and UTM targeting are on the roadmap.

Triggers

Each widget type has a built-in trigger: on-load popups appear shortly after the page is ready, exit-intent popups fire when the cursor leaves the viewport (timer + scroll-up on touch devices), bars and floating buttons render immediately. Scroll-depth, time-on-page and custom-event triggers are on the roadmap.

Analytics & Leads

Tracked events

We track impressions (widget rendered), clicks (interaction), and submissions (form completion). Custom events coming soon.

Working with leads

Leads land in your inbox in real time. Mark them new, reviewed, or contacted, and export as CSV anytime.

API & Integrations

REST API coming soon

List and create widgets, query analytics, and pull leads — all over a clean REST API.

Webhooks live

Get every new lead pushed to your own endpoint the moment it arrives. Open your website → InstallSecurity, paste an https:// URL and save. A signing secret is generated and shown once — store it.

Request

We send a POST with a JSON body and these headers:

Content-Type: application/json
X-CMM-Event: lead.created
X-CMM-Signature: sha256=<hex HMAC-SHA256 of the raw body, keyed with your secret>
User-Agent: ClickMeMaybe-Webhook/1.0

Payload — lead.created

{
  "event": "lead.created",
  "created_at": "2026-09-03T10:15:42+00:00",
  "lead": {
    "id": 1234,
    "email": "anna@example.com",
    "phone": null,
    "name": "Anna",
    "page": "https://yoursite.com/pricing",
    "device": "mobile",
    "type": "optin"
  },
  "widget": { "id": 42, "name": "Exit popup — yoursite.com", "category": "exit_intent" },
  "website": { "id": 7, "domain": "yoursite.com" }
}

lead.type is one of callback, message, optin, contact (falls back to the widget category). Fields that don't apply are null.

Delivery & retries

  • Respond with any 2xx within 5 seconds to acknowledge. Do the heavy work asynchronously.
  • Non-2xx responses, timeouts and connection errors are retried 3 times in total (after ~10 s, 60 s and 5 min). After that the delivery is marked failed.
  • Deliveries are sent from a queue — the visitor's widget never waits on your server.
  • Treat lead.id as the idempotency key: a retry may re-send the same lead.

Verifying the signature

Always compute the HMAC over the raw request body (before JSON parsing) and compare in constant time.

PHP
$secret   = getenv('CMM_WEBHOOK_SECRET');
$body     = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $body, $secret);
$given    = $_SERVER['HTTP_X_CMM_SIGNATURE'] ?? '';

if (! hash_equals($expected, $given)) {
    http_response_code(401);
    exit('bad signature');
}

$event = json_decode($body, true);
// $event['lead']['email'] ...
http_response_code(204);
Node.js (Express)
import crypto from 'node:crypto';
import express from 'express';

const app = express();
const SECRET = process.env.CMM_WEBHOOK_SECRET;

// Keep the raw body — the signature is computed over the exact bytes we sent.
app.post('/cmm-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
  const given = req.get('X-CMM-Signature') || '';

  if (expected.length !== given.length || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(given))) {
    return res.status(401).send('bad signature');
  }

  const event = JSON.parse(req.body.toString('utf8'));
  // event.lead.email ...
  res.sendStatus(204);
});

Rotating the secret (Regenerate secret in Security) invalidates the old one immediately — update your endpoint first, then rotate.

Zapier, Make, n8n via webhook

No native app needed. In Zapier create a Zap with the trigger Webhooks by Zapier → Catch Hook, copy the generated URL and paste it as your webhook URL in Security. Send a test lead from your widget, then map lead.email, lead.name etc. into any of 5,000+ apps. The same works with Make (Custom webhook) and n8n (Webhook node).

Stop guessing. Start converting.

Install in 5 minutes. Publish your first widget today.

Start Free Now