Skip to main content

Connect your website

Connect your own website to ConnectWiz and three things start to happen:

  • ConnectWiz learns which ad, campaign or site brought each visitor — the campaign tags of the link and the ad click id (Google's gclid, Meta's fbclid…), when the visitor allows it.
  • A tap on a WhatsApp link on your site carries a short ref code into the chat, so the conversation can be tied back to the ad that brought the person.
  • The forms on your site arrive in your ConnectWiz forms, with the visitor's source attached — the same submissions, contacts, tags, notifications and flows as a form hosted by ConnectWiz.

If your site already runs the ConnectWiz chat widget, its code does all of this too — no second code, no second key. A site without the chat widget uses a small standalone script instead. Nothing here replaces your own analytics or Google Tag Manager: either code runs next to them.

Who can set it up

The website connection is part of every plan. Setting it up needs the Manage integrations permission (integrations.manage). Sending the results on to Meta and Google Ads, and the conversion report, are Pro and above — see Send conversions to Meta and Google Ads.

Open the website screen​

Go to Settings → Integrations and open Website (under Advertising). The first time, give the site a Site name and its Domains, one per line, leave Capture with the chat widget code on if the site runs the chat widget, then press Connect site.

  • example.com also covers www.example.com.
  • *.example.com covers every subdomain.
  • The browser key — and the chat widget's key, for this — works only from these domains: a page on any other domain that copies your snippet is refused.

You can connect more than one site (Add another site), each with its own keys and settings. Connection on switches a site off without deleting it; Disconnect site removes it — its keys stop working at once, and the visits already received stay.

What the site script does​

Under What the site script does:

SwitchWhat it means
Record visits that come from an ad, a campaign link or another siteA page view is recorded only when it carries a campaign signal (utm tags, an ad click id) or came from another site. Plain visits from your own pages or typed addresses are not.
Add a ref code to WhatsApp linksSee WhatsApp ref codes below.
Forms the script fillsOnly forms marked data-cw-form (default) or Every form on the page.

Keys​

A site has two kinds of key. They are not interchangeable. A site linked to the chat widget also accepts the chat widget key (the one already in your chat widget snippet) in place of the browser key — from the site's domains only.

KeyLooks likeWhere it goesWhat it can do
Browser keypk_…In your pages' HTML. Public by design.Report visits and WhatsApp clicks — only from the site's domains. It cannot read anything and cannot submit forms.
Server keysk_…In your web server's settings (an environment variable), never in a page.Send form submissions to ConnectWiz (scope forms:submit). Nothing else.
  • New browser key replaces the browser key. The old one stops working immediately, so update the snippet on your site straight away.
  • Create server key gives the key a name (for example Production server) and shows it once: Copy this key now. It is not shown again. If you lose it, use Replace — a new key is issued and the old one stops.
  • Revoke switches a server key off for good. The list shows each key's Last used date, so you can see which one your server really uses.

Install​

Your chat widget code already does it​

With Capture with the chat widget code on, Install says Source capture runs with the chat widget code and shows the chat widget's own snippet:

<script async
src="https://api.connectwiz.net/widget/widget.js"
data-widget-key="…"
></script>

If the chat widget is already on the site, there is nothing to add. The widget code captures sources, adds WhatsApp ref codes and fills the form fields exactly like the standalone script, under the same consent rules.

  • It starts at once, before the chat and independent of it: also in manual mode (data-manual) before Smaibot.init(), and while the chat itself is switched off.
  • The switches under What the site script does apply without touching the code: the widget asks ConnectWiz for them once per browser tab.
  • The chat widget key works for this only from the site's domains. On any other domain the widget code still shows the chat but captures nothing — links and forms are left alone.
  • To keep one page out, add data-attribution="off" to the tag (or attribution=off in the address under Google Tag Manager). data-cookie-domain works as below.
  • When a visitor who came from an ad starts a chat, the chat and the visit are the same person: the visit is added to the contact the chat creates, and the landing is counted once.

Turning the switch on is a deliberate step: the chat widget key is pasted on every site that shows the chat, so it captures sources only where you named the domains here.

Standalone script (sites without the chat widget)​

For a site that does not run the chat widget, switch Capture with the chat widget code off. Install then shows the standalone snippet with the site's browser key filled in. Paste it into every page, before </head>:

<script async src="https://api.connectwiz.net/widget/cw-attribution.v1.js" data-key="pk_…"></script>

Copy it from the panel rather than from here: the panel's version carries your key and your switches. If both codes end up on one page, the first one to start does the work and the other stays out.

Options​

Each option of the standalone script is a data-* attribute on the tag:

OptionValuesDefault
data-keyYour browser key (pk_…). Required.—
data-formsall fills every form on the pageOnly forms with data-cw-form
data-whatsappoff leaves WhatsApp links aloneOn
data-visitsoff stops recording visitsOn
data-cookie-domain.example.com shares the visitor across your subdomainsThe current host

The panel adds data-forms, data-whatsapp and data-visits for you when you change the switches.

Google Tag Manager​

Add the snippet as a Custom HTML tag that fires on all pages. If your container drops data-* attributes, put the options in the address instead — the script reads both:

<script async src="https://api.connectwiz.net/widget/cw-attribution.v1.js?key=pk_…&forms=all"></script>

What it puts into your forms​

In every form it fills, the script adds two hidden fields:

  • cw_attribution — where the visitor came from (JSON);
  • cw_event_id — a fresh id for this submission.

On submit it also pushes { event: "cw_lead_attribution", cw_event_id } to the dataLayer. Use the same id as the event ID of your Meta pixel's Lead event: Meta then counts the browser event and ConnectWiz's server event once, not twice.

For forms your page draws later (a pop-up, a single-page app), call window.cwAttribution.fill() after the form appears. window.cwAttribution.get() returns the current attribution block.

ConnectWiz can hold the consent too

Switch on ConnectWiz cookie consent and the same code keeps the visitor's choice, tells your tags and records it — see Cookie consent. A choice made there wins over the signals below.

The script follows your cookie banner. It understands these signals, the explicit ones first (an IAB TCF consent tool, __tcfapi, is read too — see Your own consent tool instead):

  1. window.cwConsent — set it before the script loads (window.cwConsent = { ads: true, analytics: true }), or call window.cwConsent.update({ ads: true }) from your banner when the visitor decides.
  2. Google Consent Mode — the gtag('consent', 'default' | 'update', …) calls already in your dataLayer. Ads consent means ad_storage granted (and ad_user_data not denied).

No signal at all counts as no consent. What changes:

Without marketing consentWith marketing consent
Campaign tags, landing page, referrerKept for this browser tab only (session storage)Kept in the first-party _cw_at cookie for 90 days
Ad click ids (gclid, gbraid, wbraid, fbclid), Meta's _fbp / _fbcNever read, kept or sentSent with the visit, the WhatsApp click and the form
Page address sentStripped of click idsAs it is
The visitor's IP address and browser (user agent) on the visit, the WhatsApp click and the form's source recordNot stored (a form submission keeps its own copy as the evidence of your form's consent box)Stored, encrypted

When the visitor accepts later, the session copy moves into the cookie with the click ids still in the address. When they withdraw, the _cw_at cookie is deleted and every id the script held is dropped. _cw_at is a marketing cookie: list it in your cookie policy as one.

Ad measurement is a separate yes​

Sharing a person's hashed phone number and e-mail with Meta and Google for ad measurement needs its own, explicit consent — ad_measurement. Accepting marketing cookies does not imply it, and Consent Mode has no such signal. Give your form an optional checkbox (for example "Share my details for ad measurement") and pass the answer on:

  • in the browser: window.cwConsent.update({ ad_measurement: true }), or
  • from your server, in the submission: "consent": {"ad_measurement": true}.

What each answer allows is explained in Send conversions to Meta and Google Ads. Your privacy notice must cover sharing this data with Meta and Google.

WhatsApp ref codes​

With Add a ref code to WhatsApp links on, a tap on a wa.me, api.whatsapp.com or whatsapp:// link on your site is held for a moment (under a second): the script reports the click, receives a short code and puts a ready message into the link. WhatsApp then opens with, for example:

Hello, I would like some information (ref: K7Q2M)

  • The code is 5 characters from letters and digits that are hard to confuse (no 0/O, no 1/I), unique in your workspace and valid for 30 days.
  • If ConnectWiz does not answer in time, the visitor goes on to WhatsApp with the link as it was. A lost attribution is better than a button that does nothing.
  • If the link already has its own text, the code is added to the end of it.
  • When the visitor sends the message, ConnectWiz finds the code in the first message of the conversation, ties the conversation and the person to the click, and shows a Source chip on the conversation — see Follow up on a lead. The message itself is kept as the customer wrote it, but the AI assistant never sees the code, so it does not ask what it means.
  • A code counts once. A second message, a retry or another conversation with the same code changes nothing.

Edit the message​

In the WhatsApp section:

  • WhatsApp channel the messages arrive on and WhatsApp number — note which of your numbers the site's links open. The code is recognised on any of your connected WhatsApp numbers (and on Instagram, Messenger, Telegram and the chat widget), because it is unique in your workspace.
  • Message (language) — one text per language. {ref} is replaced with the visitor's code; the field must contain it. The visitor's browser language picks the text; without a text for that language the first one you wrote is used, and without any, ConnectWiz's own sentence. Preview shows the result with a sample code.

Send your forms from your server​

When your server receives a form, it forwards it to ConnectWiz with a server key. ConnectWiz checks it exactly like a form filled in on ConnectWiz and runs the same steps — the contact, tags, consent, notifications, flows and the form.submitted webhook. The submission shows Website (server) as its source.

Choose the form​

Submissions go to the form picks the ConnectWiz form the snippets point at. The form must be published; a draft form refuses submissions. The panel warns you if the form does not create contacts — without a contact, nothing can be sent on to the ad platforms.

Create the ready-made lead form makes one in a click: Full name, Phone, E-mail and Message, published, creating a contact for every submission, and set as this site's form. Its field keys are name, phone, email and message.

The request​

POST https://api.connectwiz.net/api/intake/forms/{form}/submissions
Authorization: Bearer sk_…
Content-Type: application/json

{form} is the form's id; the panel's snippet already has it. The body:

FieldRequiredWhat it is
valuesYesThe answers, keyed by the form's field keys: {"name": "Ada", "phone": "+905320000000"}.
attributionNoThe cw_attribution field of the form, as it arrived (text or object). If you forward the whole form inside values, it is read from there too.
event_idNoThe cw_event_id field — the Meta pixel deduplication key.
client_ipNoThe visitor's IP address, not your server's.
user_agentNoThe visitor's browser User-Agent.
page_urlNoThe page the form was on.
idempotency_keyNoYour own id for this submission.
consentNo{"ad_measurement": true} when the visitor ticked your ad-measurement box. It is added to what the script already recorded.

Send the visitor's real IP and User-Agent: Meta needs both to treat the lead as a website event.

Idempotency. Send the same idempotency_key again — a retry after a timeout, a queue that runs twice — and you get the first submission back ("duplicate": true, HTTP 200), with no second contact, consent record, conversion or webhook.

Examples​

curl:

curl -X POST 'https://api.connectwiz.net/api/intake/forms/FORM_ID/submissions' \
-H "Authorization: Bearer $CONNECTWIZ_SERVER_KEY" \
-H 'Content-Type: application/json' \
-d '{
"values": {"name": "Ada", "phone": "+905320000000"},
"attribution": "<the cw_attribution field of the form>",
"event_id": "<the cw_event_id field of the form>",
"client_ip": "<the visitor IP>",
"user_agent": "<the visitor User-Agent>",
"idempotency_key": "<your own submission id>",
"consent": {"ad_measurement": false}
}'

PHP:

<?php
$ch = curl_init('https://api.connectwiz.net/api/intake/forms/FORM_ID/submissions');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CONNECTWIZ_SERVER_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'values' => ['name' => $_POST['name'] ?? '', 'phone' => $_POST['phone'] ?? ''],
'attribution' => $_POST['cw_attribution'] ?? null,
'event_id' => $_POST['cw_event_id'] ?? null,
'client_ip' => $_SERVER['REMOTE_ADDR'] ?? null,
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
'page_url' => $_SERVER['HTTP_REFERER'] ?? null,
'idempotency_key' => $submissionId,
// Your form's optional "share for ad measurement" checkbox, if it has one.
'consent' => ['ad_measurement' => !empty($_POST['ad_measurement'])],
]),
]);
$response = curl_exec($ch);

Send it from a background job if you can, so a slow answer never holds up your visitor's page.

Answers​

HTTPMeans
201Received. The body carries submission_id, status, contact_id, attribution_touch_id and duplicate: false.
200The same idempotency_key was sent before; the first submission is returned with duplicate: true.
401missing_token or unknown_token — no key, a wrong key, or a browser key used where a server key belongs.
403revoked_token, missing_scope:forms:submit, or site_disabled (the site's connection is off).
404form_unavailable — the form does not exist or is not published.
422The answers did not pass the form's own checks; errors names the fields.
429Too many requests for this key (120 a minute). Retry later with the same idempotency_key.

The full schema is in the API reference.

Hidden fields in your forms​

The form builder has a Hidden value field type. The visitor never sees it.

  • On a form hosted by ConnectWiz, it is filled from the page address: Read from the URL parameter (empty = the field key), or Value when the URL has none.
  • From a connected website, your server sends it in values like any other field.

Use it for things you want to keep with the submission — a product code, the branch the page belongs to. Where the visitor came from does not need a hidden field: it travels with the submission on its own.

Is anything arriving?​

Is anything arriving? → Show the last touches lists the most recent visits, form touches and WhatsApp clicks from the site: when, the type, the source and campaign, which click ids came (by name, never their value), the ref code and whether ads consent was given.

To test, open a page of your site with a campaign link (for example ?utm_source=test), or tap a WhatsApp link, then press Refresh. A plain visit without a campaign tag or a referring site is not recorded — that is by design.

Next​