Article sections

    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

    GlobalWhat it is
    apiReturned by _mktz._api.get('v0', '{MKTZ[EXP_ID]}')). Scoped to one experiment.
    _mktzThe 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.js only. Calling api.runnable in a variation file does nothing. In variation files, apply your DOM changes directly — do not register another runnable.

    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:

    OptionTypePurpose
    onstringDOM event to listen for ('click', 'change', …)
    namestringGoal name
    valuevalue 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.track resolves 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 call api.track again after the element exists, or wire the goal manually by listening on a stable ancestor and calling api.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 null

    Visitor & session data — _mktz.visitor.*

    Read-only properties about the current visitor:

    PropertyPropertyProperty
    device_typebrowser_namebrowser_version
    oscountrycity
    ipsession_iduid
    new_visitoris_returningvisits_count
    views_sessiontime_onsitereferer_type
    historyresolutionlanding_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 Promise

    Template tokens

    TokenReplaced 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

    CallContextPurpose
    _mktz._api.get('v0', id)wrapperReturns the experiment api object
    api.runnable(fn)global.js onlyRegister the variation entry point
    api.isControlanywheretrue for the control bucket
    api.goal(name, value?)anywhereFire a conversion goal
    api.track(selector, opts)anywhereBind a goal to a DOM event
    api.storageanywhereShare state between experiment files
    _mktz.push(['_Goal', name, value?])anywhereFire a goal without the api object
    _mktz.events.on/trigger/once*anywherePub/sub + page lifecycle events
    _mktz._set_cookie / _get_cookieanywhereRead/write cookies
    _mktz.visitor.*anywhereVisitor & session data
    _mktz._is_preview()anywhereDetect the Explore editor/preview
    _mktz.running_test / _mktz.experimentsanywhereOther experiments active for the visitor

    Was this post helpful?