Website Script
CampaignOS.js is a lightweight script you embed on your website to enable tracking, identification, push notifications, and personalization.
Installation
Add this script tag to your website:
<script
src="https://your-campaignos-domain.com/campaignos.js"
data-workspace="your-workspace-slug"
data-uid="optional-user-id"
async
></script>Or load via URL parameters:
<script src="https://your-campaignos-domain.com/campaignos.js?workspace=your-slug&uid=user123" async></script>Script Configuration Endpoint
GET /api/script/config
Returns personalization configuration for the embedded script.
Auth: None required
Query Parameters:
| Param | Type | Required | Description |
|---|---|---|---|
workspace | string | Yes | Workspace slug |
uid | string | No | User identifier (externalId or identity) |
Response:
{
"workspaceId": "ws_abc123",
"segments": ["seg_1", "seg_2"],
"personalization": [],
"pushEnabled": true
}The script uses this response to:
- Determine which segments the visitor belongs to
- Apply personalization rules (modals, banners, toasts)
- Enable/disable push notification prompts
Event Tracking Endpoint
POST /api/script/event
Tracks events from the website script.
Auth: None required
Request Body:
{
"workspace": "your-workspace-slug",
"type": "page_view",
"uid": "user123",
"metadata": {
"title": "Pricing Page"
},
"sessionId": "sess_abc123",
"pageUrl": "https://example.com/pricing",
"referrer": "https://google.com",
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "summer-sale"
}| Field | Type | Required | Description |
|---|---|---|---|
workspace | string | Yes | Workspace slug |
type | string | Yes | Event type |
uid | string | No | User identifier |
metadata | object | No | Arbitrary event data |
sessionId | string | No | Browser session ID |
pageUrl | string | No | Current page URL |
referrer | string | No | Referring URL |
utmSource | string | No | UTM source |
utmMedium | string | No | UTM medium |
utmCampaign | string | No | UTM campaign |
Response (201):
{ "id": "evt_abc123" }What the Script Does
Tracking
- Page views — Automatic on each navigation
- Custom events — Via
CampaignOS.track('event_type', { metadata }) - UTM capture — Automatically extracts UTM parameters from URL
Identification
- Resolves visitors by
uidparameter (externalId or identity email) - Supports anonymous-to-known identity stitching when
uidis provided later - Optional signed identity payloads for secure identification
Personalization
- Fetches personalization rules from
/api/script/config - Renders modals, banners, toasts, and embedded widgets
- Targeting based on:
- Segment membership
- Event history
- Page path / referrer / UTM
- Frequency caps
- Reports impressions, dismissals, and clicks as events
Push Notifications
- Checks push permission status
- Shows permission prompt (if enabled for workspace)
- Registers push subscription with CampaignOS
- Associates subscription with contact
JavaScript API
// Track a custom event
CampaignOS.track('purchase', {
productId: 'prod_123',
amount: 99.99
});
// Identify a user
CampaignOS.identify('user@example.com');
// Update user attributes
CampaignOS.setAttributes({
plan: 'pro',
company: 'Acme Inc.'
});Consent Mode
The script never sends tracking events until it has consent. How consent is obtained is controlled by the consent parameter:
<script src="https://your-campaignos-domain.com/campaignos.js?workspace=your-slug&consent=required" async></script>| Mode | Behaviour |
|---|---|
auto (default) | Tracks immediately unless a TCF v2 CMP (__tcfapi) or Cookiebot is present, in which case it follows that CMP’s decision. |
required | Nothing is sent until you call CampaignOS.consent.grant(). Events fired before that are buffered (last 50) and flushed on grant. |
cmp | Detects OneTrust, Cookiebot, a TCF v2 CMP or Google Consent Mode and grants/revokes automatically. Events are buffered until the CMP reports a decision. |
disabled | Consent handling is off; tracking always runs. Use only where no consent is legally required. |
The decision is remembered in localStorage under cos_consent (granted / denied), so a returning visitor is tracked (or not) on the very first page view.
By default the script keys off the analytics / statistics category. Pass consent-category=marketing to follow the marketing / targeting category instead:
<script src=".../campaignos.js?workspace=your-slug&consent=cmp&consent-category=marketing" async></script>Consent API
CampaignOS.consent.status(); // "granted" | "denied" | "pending"
CampaignOS.consent.grant(); // start tracking, flush buffered events, open personalization
CampaignOS.consent.revoke(); // stop tracking, drop buffered events, close the live stream
CampaignOS.consent.pending(); // number of buffered events waiting for consentCampaignOS.grantConsent(), CampaignOS.denyConsent() and CampaignOS.hasConsent() remain available as aliases.
Buffered events keep their original timestamp and pageUrl, so a page view that happened before the visitor clicked “Accept” is still attributed to the right page and time.
Wiring your own banner (consent=required)
<script src=".../campaignos.js?workspace=your-slug&consent=required" async></script>
<script>
document.getElementById("accept-cookies").addEventListener("click", function () {
window.CampaignOS && CampaignOS.consent.grant();
});
document.getElementById("reject-cookies").addEventListener("click", function () {
window.CampaignOS && CampaignOS.consent.revoke();
});
</script>Consent management platforms (consent=cmp)
No extra code is needed; load the CMP before or after CampaignOS.js, the script re-checks for a CMP for up to 10 seconds.
- OneTrust — wraps
OptanonWrapperand listens toOneTrustGroupsUpdated; consent is granted whenOptanonActiveGroupscontainsC0002(analytics) orC0004(marketing). - Cookiebot — listens to
CookiebotOnAccept,CookiebotOnDeclineandCookiebotOnConsentReady; readsCookiebot.consent.statistics(or.marketing). - Google Consent Mode v2 — reads
consent default/consent updateentries already indataLayerand hooksdataLayer.pushfor later updates; followsanalytics_storage(orad_storage). - IAB TCF v2 — subscribes via
__tcfapi("addEventListener", 2, …)and follows purpose 1.
If your CMP is not detected, nothing is sent; call CampaignOS.consent.grant() from the CMP’s own callback. See Compliance & Privacy for full snippets.
Service Worker
CampaignOS includes a service worker (cos-sw.js) for push notification handling. Service workers are same-origin, so the script registers it as /cos-sw.js relative to your website, not the CampaignOS host. Copy public/cos-sw.js from CampaignOS to the web root of your own site (it must be served at https://your-site.com/cos-sw.js). The script registers it automatically when push is enabled and passes the CampaignOS API base, workspace slug and user id as query parameters, so the worker needs no configuration.