Skip to content

Web SDK reference

The Origamy Web SDK ships in two parts, following the Segment/RudderStack pattern: a tiny snippet you paste into <head> that stubs the API and queues calls, and the full engine (analytics.min.js, ~25 KB gzipped) the snippet loads asynchronously from https://cdn.origamy.io. Your page never blocks on analytics.

The API is Segment-compatible: if you have existing analytics.track(...) instrumentation, the call signatures carry over unchanged.

Paste the snippet from the Quickstart into your <head>. Calls made before the engine arrives are queued and replayed in order.

Initializes the SDK. Must be called before events are delivered; calls made earlier are queued.

await origamy.load("YOUR_WRITE_KEY", {
apiHost: "https://events.origamy.io", // where events are delivered
cdnHost: "https://cdn.origamy.io", // where plugin bundles load from
flushInterval: 10000, // ms between automatic flushes
maxQueueSize: 20, // events per batch before an early flush
retryLimit: 3, // delivery attempts per batch
debug: false, // verbose console logging
autoTrack: {
clicks: { enabled: true }, // see Auto-tracking below
pages: { enabled: true },
},
});
Option Default Description
apiHost https://events.origamy.io Ingestion endpoint. Point this at your own gateway on a self-hosted (BYOD) data plane.
cdnHost https://cdn.origamy.io Host device-mode plugin bundles are loaded from.
flushInterval 10000 How often (ms) the queue flushes to /v1/batch.
maxQueueSize 20 Queue flushes early once it holds this many events.
retryLimit 3 Failed batches retry with exponential backoff up to this many attempts.
debug false Logs every event, flush, and retry to the console.
autoTrack off Opt-in automatic page and click tracking.

All five methods share the same optional last argument, options:

{
context?: object, // merged into the event's context
timestamp?: string, // ISO-8601 override (for late/imported events)
anonymousId?: string, // override the stored anonymous ID
integrations?: { [destination: string]: boolean }, // per-event routing
}

See the Event spec for what each event looks like on the wire.

Records an action the user performed. Name events in Object Action title case ("Order Completed", not "order-completed") — downstream destinations expect it.

origamy.track("Order Completed", {
orderId: "12345",
amount: 99.99,
currency: "USD",
}, {
integrations: { GoogleAnalytics: false }, // skip GA for this event
});

Ties the current visitor to a known user and records traits. Traits persist locally and merge across calls. Calling identify with no userId updates traits on the current identity.

origamy.identify("user_123", {
email: "ada@example.com",
name: "Ada Lovelace",
plan: "premium",
});

Records a page view. The SDK fills in url, path, title, referrer, and search automatically; anything you pass is merged on top.

origamy.page("Pricing", { experiment: "pricing-v2" });

Associates the current user with an account, company, or team.

origamy.group("company_456", {
name: "Acme Corp",
plan: "enterprise",
employees: 100,
});

Links two identities — typically the pre-signup anonymous ID to the new user ID — so identity resolution can merge their history. previousId defaults to the stored anonymous ID.

origamy.alias("user_123");

Both surfaces are off by default and opt-in via load() config.

Emits an Element Clicked track event when the user clicks an element carrying a data-origamy-event attribute (or a custom selector). Deliberately not track-everything — opt-in per element keeps your event stream high-signal.

origamy.load("KEY", { autoTrack: { clicks: { enabled: true } } });
<button data-origamy-event="Upgrade Clicked">Upgrade</button>
Option Default Description
enabled false Turn click auto-tracking on.
selector [data-origamy-event] CSS selector matched against the click target and its ancestors.

Auto-fires page() on initial load, back/forward navigation, and SPA route changes (history.pushState/replaceState are patched and restored on destroy()).

Option Default Description
enabled false Turn page auto-tracking on.
skipInitial false Skip the auto event on first load if you call page() explicitly at boot.

Middleware runs on every event before delivery. Return the (possibly modified) event, or null to drop it. Async middleware is supported.

// Enrich every event
origamy.use((event) => {
event.context.appVersion = "1.2.3";
return event;
});
// Drop internal traffic
origamy.use((event) => {
if (event.type === "track" && event.event.startsWith("Internal ")) return null;
return event;
});

Plugins load a destination’s native script in the browser and forward events to it directly. Which plugins load is controlled by your source’s destination configuration in the Origamy dashboard, fetched from /v1/config at load time.

Built-in plugins: Google Analytics and Mixpanel.

Register a custom plugin before or after load():

origamy.registerPlugin("CustomDestination", () => ({
name: "CustomDestination",
initialize(config) {
// load vendor script, init client
},
track(event) {
// forward the event
},
identify(event) {},
}));

Use the per-event integrations option to skip a destination for a single event.

Plugin scripts load from cdnHost at /integrations/<name>/<version>/index.js. The SDK accepts only path-safe names and versions from the configuration, and when a destination’s config carries an integrity value (a sha384-… Subresource Integrity hash for that build) it is set on the script tag with crossorigin="anonymous", so a tampered CDN file is refused by the browser.

  • Events queue in memory and flush to POST /v1/batch every flushInterval ms, or earlier once maxQueueSize events accumulate.
  • Failed batches retry with exponential backoff, up to retryLimit attempts.
  • On page unload, the SDK drains the queue with navigator.sendBeacon (falling back to a synchronous XHR) so trailing events aren’t lost.
  • Requests authenticate with your write key — see Ingestion API.

origamy.webPush subscribes the browser to push notifications from your journeys and broadcasts. Connect the Web Push provider under Channels first, copy its VAPID public key, and host the service worker. Then, from a user gesture:

const subscription = await origamy.webPush.subscribe({
vapidPublicKey: "YOUR_VAPID_PUBLIC_KEY",
serviceWorkerPath: "/origamy-sw.js", // default
// registration: existingRegistration, // reuse a service worker you already have
});

It resolves to the PushSubscription, or null when the browser has no push support or the person declined. It never throws.

Method Description
webPush.subscribe(options) Asks permission, registers the service worker, subscribes, and registers the device with Origamy.
webPush.unsubscribe() Unsubscribes the browser and removes the device from Origamy.
webPush.getSubscription() The current subscription, or null.
webPush.permission() "granted", "denied", "default", or "unsupported".
webPush.isSupported() Whether the browser has service workers, the Push API and notifications.

The device is registered with a Device Created or Updated event that goes to Origamy only — never to device-mode plugins. Afterwards the SDK keeps it current by itself:

  • on page load it re-sends a subscription the browser rotated, or one older than a week;
  • after identify() with a different person, it moves the device to them;
  • reset() unregisters the device for the person signing out, and it stays unregistered until someone identifies again;
  • if notifications are blocked in browser settings, or the browser drops the subscription, the device is removed.
Method Description
ready(callback) Runs the callback once the SDK is loaded (immediately if it already is).
reset() Clears the stored user ID, traits, and anonymous ID — call on logout. Also unregisters this browser’s push subscription for the person signing out.
getAnonymousId() Returns the current anonymous ID.
getUserId() Returns the identified user ID, or null.
isLoaded() true once load() has completed.
arePluginsLoaded() true once device-mode plugins have initialized.
destroy() Tears down timers, listeners, and history patches. Mostly useful in tests and SPAs that hot-swap the SDK.

The anonymous ID, user ID and traits are kept in localStorage, falling back to a cookie and then to memory. Cookies are written with SameSite=Lax, and with Secure on HTTPS pages. Message and anonymous IDs come from the Web Crypto API (crypto.randomUUID, or getRandomValues on older browsers).

Modern evergreen browsers (Chrome, Firefox, Safari 11+, Edge). The SDK has zero runtime dependencies, uses no eval, and is CSP-compatible.