Push Goals from Your Backend

Overview

Use this when you want to record a goal, typically a sale, from your own backend rather than relying on JavaScript in the visitor's browser. Pushing a goal server-side is more reliable around checkout: it fires only once you have validated the order, and it cannot be blocked by an ad blocker or a browser tab closing before the JavaScript goal runs.

Note

No API key is required for this call.

1. Save the visitor's tracking identifiers at checkout

Our tracking script keeps a cookie called mktz_client in the visitor's browser. When the user clicks Purchase, read it, URL-decode it, and save these fields with the order: they are all top-level keys in that JSON:

uid

The visitor ID.

session

The session ID.

last_variation

The test variation(s) the visitor has seen. Send it exactly as it is: it links the sale to the A/B test the visitor saw.

device_type

desktop, mobile or tablet.

Decoded, the cookie looks like this (other fields omitted):

{
  "uid": "12387015921894349754",
  "session": "sess.2.3707456223.1790088296288",
  "last_variation": "53519=1790088457422",
  "device_type": "desktop"
}

2. Push the goal once the order is validated

Send one request from your backend to our tracking endpoint, with the saved cookie values plus:

  • your Omniconvert website ID

  • the goal name (sale for a purchase)

  • the order value and its currency

  • your order/transaction ID (the same one you send to GA4)

Note

Always include the transaction ID. If the same order arrives twice (a retry, or the same order sent by both your frontend and your backend with the same ID), it is only counted once. If your frontend already sends this sale without a transaction ID, remove that call, or the order will be counted twice.

3. The request

POST to:

https://app.omniconvert.com/mktzsave

All data goes in the query string; the request body is ignored. Set a normal User-Agent header: your application's name is fine. Requests that look like they come from a bot are ignored.

Example

A short, working example in plain JavaScript (Node 18+, no libraries). Fill in INPUT with the cookie values saved at checkout and the validated order, then run node push-goal.mjs. The push is a single HTTP request, so it is easy to reproduce in any backend language.

const TRACKING_URL = 'https://app.omniconvert.com/mktzsave';
const USER_AGENT = 'my-backend/1.0'; // any normal User-Agent; requests that look like bots are ignored

const INPUT = {
    websiteId: 1380654, // your numeric Omniconvert website ID

    // Saved from the visitor's `mktz_client` cookie when they clicked Purchase
    uid: '12387015921894349754',
    session: 'sess.2.3707456223.1790088296288',
    lastVariation: '53519=1790088457422', // links the sale to the A/B test variation(s) the visitor saw
    deviceType: 'desktop',

    // From the validated order
    goal: 'sale',
    value: 149.90,
    currency: 'EUR',
    transaction: 'ORD-1001', // the same order ID you send to GA4; the same order sent twice is counted once
};

async function pushGoal(input) {
    // Current time in UTC, as YYYY-MM-DDTHH:MM:SS+00:00
    const time = new Date().toISOString().replace(/\.\d{3}Z$/, '+00:00');

    const params = new URLSearchParams({
        event: 'multipleGoals',
        id_website: String(input.websiteId),
        uid: input.uid,
        session: input.session,
        last_variation: input.lastVariation,
        device_type: input.deviceType,
        time,
        transaction: input.transaction,
        goals: JSON.stringify({
            pairs: [{
                goalName: input.goal,
                goalValue: input.value,
                transId: input.transaction,
                goalDetails: { currency: input.currency },
            }],
        }),
    });

    const response = await fetch(`${TRACKING_URL}?${params}`, {
        method: 'POST', // all data goes in the URL; a request body is ignored
        headers: { 'User-Agent': USER_AGENT },
        signal: AbortSignal.timeout(10000),
    });

    return response.status; // 204 = received, not a confirmation that it was recorded
}

pushGoal(INPUT)
    .then((status) => console.log(`Omniconvert responded ${status}`))
    .catch((error) => console.error(`Goal push failed: ${error.message}`));

Good to know

  • When a sale counts toward a test: only if the request includes last_variation, the test is still running, and the order arrives within the test's goal window (between 3 and 90 days after the visitor saw the variation, depending on the test's settings). A sale that misses this is still recorded in your overall goal totals.

  • Currency: if the order currency differs from your account's base currency, include it and we convert the value.

  • The response: a 204 means the request was received, not that the goal was recorded. There is no separate confirmation call.

Updated