The Omniconvert Explore JavaScript API is available inside every experiment’s variation code through two globals: api (the per-experiment object) and _mktz (the global Explore object). Together they let you register variation logic, fire conversion goals, track interactions, read visitor data, and coordinate between experiments.
Globals at a glance
| Global | What it is |
|---|---|
api | Returned by . Scoped to one experiment. |
_mktz | The site-wide Explore object. Available everywhere. |
The experiment wrapper
Every variation script follows this IIFE pattern:
(function (_mktz, api) {
'use strict';
api.runnable(run);
function run() {
// variation logic + tracking go here
}
})(_mktz, _mktz._api.get('v0', '{MKTZ[EXP_ID]}'));{MKTZ[EXP_ID]} is a template token that Explore replaces with the live experiment ID when the script is served. Hard-coding an ID also works, but the token keeps code portable across variations.
The api object
api.runnable(fn) — register your variation
Works in
global.jsonly. Callingapi.runnablein a variation file does nothing. In variation files, apply your DOM changes directly — do not register anotherrunnable.
Pass the function that applies your changes. Explore calls it once the experiment is cleared to run (correct page, audience, and bucket).
api.isControl — detect the control group
A boolean that is true when the visitor is in the control (original) variation. Use it to fire control-side tracking without touching the page.
function run() {
if (api.isControl) {
_mktz.push(['_Goal', 'ab-test-control-view', '1']);
return;
}
// variation changes…
}api.goal(name, value?) — fire a conversion goal
Records a goal for the experiment. The optional second argument attaches a numeric or string value.
api.goal('clicked-product');
api.goal('click-filter', selectedFilter);api.track(selector, options) — bind a goal to a DOM event
Declaratively attaches a goal to a DOM event without writing addEventListener manually.
api.track('.compare-tab input[type="radio"]', {
on: 'change',
name: 'click-card-selector',
value: ($element) => $element[0].defaultValue,
before: function (options, event, $element) {
if (event.isTriggered) return false;
},
});Options:
| Option | Type | Purpose |
|---|---|---|
on | string | DOM event to listen for ('click', 'change', …) |
name | string | Goal name |
value | value or ($element) => … | Optional value; a function is evaluated at fire time |
before | (options, event, $element) | Guard run before firing; return false to cancel |
⚠️ Only binds to elements already in the DOM.
api.trackresolves the selector and attaches its listener once, at call time. It does not use event delegation, so it will not fire for elements added later (lazy-loaded content, modals, AJAX, SPA route changes). For dynamic elements, either callapi.trackagain after the element exists, or wire the goal manually by listening on a stable ancestor and callingapi.goal()or_mktz.push(['_Goal', ...])when the event matches.
api.storage — share state between experiment files
A free-form object scoped to the experiment. Use it to pass state or functions between global.js and variation files.
// global.js
api.storage.benefitsData = [...];
api.storage.fillBenefits = function () { /* … */ };
// variation-1.js (same experiment)
api.storage.fillBenefits();Firing goals without the api object
When you only have _mktz available — shared snippets, code outside the experiment wrapper — push a goal onto the Explore queue directly:
_mktz.push(['_Goal', 'click-add-to-cart']); _mktz.push(['_Goal', 'add-to-cart-pdp', value]);
This is equivalent to calling api.goal(name, value?).
The _mktz global
Events
_mktz.events.on('omni:changed:{MKTZ[EXP_ID]}', handler); // subscribe
_mktz.events.trigger('job_event', payload); // publish
_mktz.events.onceIdle(fn); // fires once the page goes idle
_mktz.events.onScroll(fn); // fires on scroll
_mktz.events.onExit(fn); // exit-intent (repeating)
_mktz.events.onceExit(fn); // exit-intent (fires once)Cookies
_mktz._set_cookie('MY_KEY', '1', 10, '/'); // name, value, lifetime in hours, pathname
var val = _mktz._get_cookie('MY_KEY'); // returns the value, or nullVisitor & session data — _mktz.visitor.*
Read-only properties about the current visitor:
| Property | Property | Property |
|---|---|---|
device_type | browser_name | browser_version |
os | country | city |
ip | session_id | uid |
new_visitor | is_returning | visits_count |
views_session | time_onsite | referer_type |
history | resolution | landing_page |
if (_mktz.visitor.device_type === 'mobile') { /* … */ }
if (_mktz.visitor.new_visitor) { /* … */ }Timing & promises
_mktz.promised.idle(); // resolves when the page is idle
_mktz.promised.delay(2); // resolves after N seconds
// Self-cleaning timers grouped by a tag
_mktz.taggedTimeouts.setTaggedInterval(fn, intervalMs, 'my-timer');
_mktz.taggedTimeouts.setTaggedTimeout(fn, delayMs, 'my-timer');
_mktz.taggedTimeouts.clearTaggedTimers('my-timer');Checking other active experiments
// Find a specific running experiment
_mktz.running_test.find((exp) => Number(exp.id_experiment) === 54628);
// Check if another experiment is active
_mktz.running_test.some((exp) => exp.id_experiment === 1290320);
// Read config for the current experiment
var cfg = _mktz.experiments['{MKTZ[EXP_ID]}'] || {};
// Variations the visitor has already been exposed to
_mktz.getSeenVariations(); // e.g. ['1321240=1', ...]Other utilities
_mktz.validator.validateEmail(value); // boolean
_mktz._get_parameter('utm_campaign', window.location.href); // query param, or false
_mktz.applyExperiment('50015-116135'); // force-apply experiment-variation
_mktz.id_website; // the Explore site ID
_mktz.Promise.all([p1, p2]).then(/* … */); // bundled PromiseTemplate tokens
| Token | Replaced with |
|---|---|
{MKTZ[EXP_ID]} | The experiment ID at serve time |
Always use the token instead of hard-coding IDs so the same code stays portable across variations.
Full example
(function (_mktz, api) {
'use strict';
api.runnable(run);
function run() {
// Control group: measure the original without changing it
if (api.isControl) {
api.goal('control-view');
return;
}
// Variation: apply DOM changes
var checkoutBtn = document.querySelector('#CartPage .checkout-btn');
if (checkoutBtn) {
checkoutBtn.textContent = 'Buy now';
}
// Track clicks on the button
api.track('#CartPage .checkout-btn', {
on: 'click',
name: 'click-checkout',
value: function ($el) { return $el.text().trim(); },
});
}
})(_mktz, _mktz._api.get('v0', '{MKTZ[EXP_ID]}'));Quick reference
| Call | Context | Purpose |
|---|---|---|
_mktz._api.get('v0', id) | wrapper | Returns the experiment api object |
api.runnable(fn) | global.js only | Register the variation entry point |
api.isControl | anywhere | true for the control bucket |
api.goal(name, value?) | anywhere | Fire a conversion goal |
api.track(selector, opts) | anywhere | Bind a goal to a DOM event |
api.storage | anywhere | Share state between experiment files |
_mktz.push(['_Goal', name, value?]) | anywhere | Fire a goal without the api object |
_mktz.events.on/trigger/once* | anywhere | Pub/sub + page lifecycle events |
_mktz._set_cookie / _get_cookie | anywhere | Read/write cookies |
_mktz.visitor.* | anywhere | Visitor & session data |
_mktz._is_preview() | anywhere | Detect the Explore editor/preview |
_mktz.running_test / _mktz.experiments | anywhere | Other experiments active for the visitor |