{"id":10244,"date":"2026-08-15T00:30:14","date_gmt":"2026-08-14T22:30:14","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/matomo-tracking-api-builder\/"},"modified":"2026-08-15T00:30:14","modified_gmt":"2026-08-14T22:30:14","slug":"matomo-tracking-api-builder","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/","title":{"rendered":"Matomo Tracking API &#038; Custom Dimension Builder"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">The Matomo tracking API answers with an empty image, no matter what was wrong with the request. This builder assembles the call, checks the parameters that are usually to blame, and hands over a ready command line.<\/p>\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap;\">\n<div style=\"flex: 2; min-width: 240px;\">\n            <label for=\"mt-host\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Address of matomo.php<\/label><br \/>\n            <input type=\"text\" id=\"mt-host\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"https:\/\/analytics.example.com\/matomo.php\">\n        <\/div>\n<div style=\"flex: 1; min-width: 110px;\">\n            <label for=\"mt-idsite\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Site ID<\/label><br \/>\n            <input type=\"text\" id=\"mt-idsite\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"1\">\n        <\/div>\n<div style=\"flex: 1; min-width: 160px;\">\n            <label for=\"mt-art\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Hit type<\/label><br \/>\n            <select id=\"mt-art\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\"><option value=\"seite\">Page view<\/option><option value=\"ereignis\">Event<\/option><option value=\"ziel\">Goal<\/option><\/select>\n        <\/div>\n<\/p><\/div>\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap; margin-top: 12px;\">\n<div style=\"flex: 2; min-width: 240px;\">\n            <label for=\"mt-url\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Page URL<\/label><br \/>\n            <input type=\"text\" id=\"mt-url\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"https:\/\/www.example.com\/preise\">\n        <\/div>\n<div style=\"flex: 1; min-width: 200px;\">\n            <label for=\"mt-name\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Page title (action_name)<\/label><br \/>\n            <input type=\"text\" id=\"mt-name\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"Preise\">\n        <\/div>\n<div style=\"flex: 1; min-width: 200px;\">\n            <label for=\"mt-besucher\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Visitor ID (_id, 16 hex characters)<\/label><br \/>\n            <input type=\"text\" id=\"mt-besucher\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" placeholder=\"0123456789abcdef\">\n        <\/div>\n<\/p><\/div>\n<div id=\"mt-ereignis\" style=\"display: none; gap: 12px; flex-wrap: wrap; margin-top: 12px;\">\n<div style=\"flex: 1; min-width: 150px;\">\n            <label for=\"mt-e-c\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Event category<\/label><br \/>\n            <input type=\"text\" id=\"mt-e-c\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"Download\">\n        <\/div>\n<div style=\"flex: 1; min-width: 150px;\">\n            <label for=\"mt-e-a\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Event action<\/label><br \/>\n            <input type=\"text\" id=\"mt-e-a\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"Klick\">\n        <\/div>\n<div style=\"flex: 1; min-width: 150px;\">\n            <label for=\"mt-e-n\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Event name<\/label><br \/>\n            <input type=\"text\" id=\"mt-e-n\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"Preisliste.pdf\">\n        <\/div>\n<div style=\"flex: 1; min-width: 110px;\">\n            <label for=\"mt-e-v\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Event value<\/label><br \/>\n            <input type=\"text\" id=\"mt-e-v\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" placeholder=\"12.50\">\n        <\/div>\n<\/p><\/div>\n<div id=\"mt-ziel\" style=\"display: none; gap: 12px; flex-wrap: wrap; margin-top: 12px;\">\n<div style=\"flex: 1; min-width: 150px;\">\n            <label for=\"mt-idgoal\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Goal ID<\/label><br \/>\n            <input type=\"text\" id=\"mt-idgoal\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" value=\"3\">\n        <\/div>\n<div style=\"flex: 1; min-width: 150px;\">\n            <label for=\"mt-revenue\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Revenue<\/label><br \/>\n            <input type=\"text\" id=\"mt-revenue\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; box-sizing: border-box;\" placeholder=\"49.90\">\n        <\/div>\n<\/p><\/div>\n<div style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.85rem; margin: 18px 0 8px;\">Custom dimensions (index and value)<\/div>\n<div id=\"mt-liste\" style=\"margin-bottom: 12px;\"><\/div>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap;\">\n        <button id=\"mt-add\" class=\"button\" type=\"button\" style=\"background: transparent; color: var(--text-primary, #e8e8ee); border: 1px solid var(--border, #2a2a35); padding: 10px 18px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Add dimension<\/button><br \/>\n        <button id=\"mt-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Build request<\/button>\n    <\/div>\n<div id=\"mt-ergebnis\" style=\"margin-top: 22px;\"><\/div>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"The Matomo tracking API answers with an empty image, no matter what was wrong with the request. This builder assembles the call, checks the parameters that are usually to blame, and hands over a ready command line.\",\"label_host\":\"Address of matomo.php\",\"label_idsite\":\"Site ID\",\"label_art\":\"Hit type\",\"art_seite\":\"Page view\",\"art_ereignis\":\"Event\",\"art_ziel\":\"Goal\",\"label_url\":\"Page URL\",\"label_name\":\"Page title (action_name)\",\"label_besucher\":\"Visitor ID (_id, 16 hex characters)\",\"label_e_c\":\"Event category\",\"label_e_a\":\"Event action\",\"label_e_n\":\"Event name\",\"label_e_v\":\"Event value\",\"label_idgoal\":\"Goal ID\",\"label_revenue\":\"Revenue\",\"label_dimensionen\":\"Custom dimensions (index and value)\",\"ph_dimension\":\"value\",\"knopf\":\"Build request\",\"knopf_zeile\":\"Add dimension\",\"knopf_weg\":\"Remove\",\"fehler_host\":\"The address of matomo.php is missing.\",\"fehler_host_schema\":\"The address has to start with http:\\\/\\\/ or https:\\\/\\\/.\",\"fehler_idsite\":\"The site ID has to be a whole number of 1 or more.\",\"fehler_besucher\":\"The visitor ID has to be exactly 16 hexadecimal characters, otherwise Matomo silently ignores it.\",\"fehler_ereignis\":\"An event needs at least a category and an action.\",\"fehler_e_v\":\"The event value has to be a number.\",\"fehler_idgoal\":\"The goal ID has to be a whole number.\",\"fehler_revenue\":\"The revenue has to be a number.\",\"fehler_dimension\":\"Row %s carries no valid dimension index.\",\"fehler_dimension_doppelt\":\"Dimension %s appears twice; the second value would overwrite the first.\",\"h_befunde\":\"Findings\",\"h_url\":\"Request as a URL\",\"h_curl\":\"Same call for the command line\",\"h_parameter\":\"Parameters in order\",\"b_ohne_id\":\"Without _id Matomo derives the visitor from IP and user agent. That is fine in the browser, but on the server it merges every visitor into one.\",\"b_ohne_url\":\"Neither url nor action_name is set, so the hit lands in the report without a name.\",\"b_url_relativ\":\"The page URL is relative. Matomo expects an absolute address including the scheme.\",\"b_dimension_leer\":\"Dimension %s has no value and is left out.\",\"b_dimension_lang\":\"The value of dimension %s is longer than 250 characters and gets truncated.\",\"hinweis_server\":\"Parameters such as cip for the real IP address, cdt for a custom timestamp or the geographic fields only work together with token_auth. That token belongs on a server: in the browser it hands every visitor write access to the statistics.\"};<\/p>\n<p>    \/\/ --- reine Rechenlogik ---<\/p>\n<p>    function textWert(wert) {\n        return String(wert === undefined || wert === null ? '' : wert).trim();\n    }<\/p>\n<p>    function bauen(eingabe) {\n        const ergebnis = { ok: false, fehler: '', parameter: [], url: '', curl: '', befunde: [] };\n        const e = eingabe || {};<\/p>\n<p>        const host = textWert(e.host);\n        if (host === '') { ergebnis.fehler = T.fehler_host; return ergebnis; }\n        if (!\/^https?:\\\/\\\/\/i.test(host)) { ergebnis.fehler = T.fehler_host_schema; return ergebnis; }<\/p>\n<p>        const idsite = textWert(e.idsite);\n        if (!\/^[0-9]+$\/.test(idsite) || parseInt(idsite, 10) < 1) { ergebnis.fehler = T.fehler_idsite; return ergebnis; }\n\n        const art = e.art === 'ereignis' || e.art === 'ziel' ? e.art : 'seite';\n        const url = textWert(e.url);\n        const name = textWert(e.name);\n\n        \/\/ Die Reihenfolge ist die aus der Matomo-Dokumentation gewohnte.\n        const parameter = [];\n        parameter.push(['idsite', idsite]);\n        parameter.push(['rec', '1']);\n        parameter.push(['apiv', '1']);\n        if (url !== '') { parameter.push(['url', url]); }\n        if (name !== '') { parameter.push(['action_name', name]); }\n\n        const besucher = textWert(e.besucher);\n        if (besucher !== '') {\n            if (!\/^[0-9a-fA-F]{16}$\/.test(besucher)) {\n                ergebnis.fehler = T.fehler_besucher;\n                return ergebnis;\n            }\n            parameter.push(['_id', besucher.toLowerCase()]);\n        } else {\n            ergebnis.befunde.push({ schwer: false, text: T.b_ohne_id });\n        }\n\n        if (art === 'ereignis') {\n            const kategorie = textWert(e.e_c);\n            const aktion = textWert(e.e_a);\n            if (kategorie === '' || aktion === '') { ergebnis.fehler = T.fehler_ereignis; return ergebnis; }\n            parameter.push(['e_c', kategorie]);\n            parameter.push(['e_a', aktion]);\n            if (textWert(e.e_n) !== '') { parameter.push(['e_n', textWert(e.e_n)]); }\n            const wert = textWert(e.e_v).replace(',', '.');\n            if (wert !== '') {\n                if (!\/^-?[0-9]+(\\.[0-9]+)?$\/.test(wert)) { ergebnis.fehler = T.fehler_e_v; return ergebnis; }\n                parameter.push(['e_v', wert]);\n            }\n        }\n\n        if (art === 'ziel') {\n            const ziel = textWert(e.idgoal);\n            if (!\/^[0-9]+$\/.test(ziel)) { ergebnis.fehler = T.fehler_idgoal; return ergebnis; }\n            parameter.push(['idgoal', ziel]);\n            const umsatz = textWert(e.revenue).replace(',', '.');\n            if (umsatz !== '') {\n                if (!\/^[0-9]+(\\.[0-9]+)?$\/.test(umsatz)) { ergebnis.fehler = T.fehler_revenue; return ergebnis; }\n                parameter.push(['revenue', umsatz]);\n            }\n        }\n\n        const gesehen = {};\n        const dimensionen = Array.isArray(e.dimensionen) ? e.dimensionen : [];\n        for (let i = 0; i < dimensionen.length; i++) {\n            const nummer = textWert(dimensionen[i].nummer);\n            const wert = textWert(dimensionen[i].wert);\n            if (nummer === '' &#038;&#038; wert === '') { continue; }\n            if (!\/^[0-9]+$\/.test(nummer) || parseInt(nummer, 10) < 1) {\n                ergebnis.fehler = T.fehler_dimension.replace('%s', String(i + 1));\n                return ergebnis;\n            }\n            if (gesehen[nummer]) {\n                ergebnis.fehler = T.fehler_dimension_doppelt.replace('%s', nummer);\n                return ergebnis;\n            }\n            gesehen[nummer] = true;\n            if (wert === '') {\n                ergebnis.befunde.push({ schwer: false, text: T.b_dimension_leer.replace('%s', nummer) });\n                continue;\n            }\n            if (wert.length > 250) {\n                ergebnis.befunde.push({ schwer: true, text: T.b_dimension_lang.replace('%s', nummer) });\n            }\n            parameter.push(['dimension' + nummer, wert]);\n        }<\/p>\n<p>        parameter.push(['send_image', '0']);<\/p>\n<p>        \/\/ Befunde, die nicht am Aufbau haengen\n        if (url === '' && name === '') { ergebnis.befunde.push({ schwer: true, text: T.b_ohne_url }); }\n        if (url !== '' && !\/^https?:\\\/\\\/\/i.test(url)) { ergebnis.befunde.push({ schwer: true, text: T.b_url_relativ }); }<\/p>\n<p>        const abfrage = parameter.map(function (p) {\n            return encodeURIComponent(p[0]) + '=' + encodeURIComponent(p[1]);\n        }).join('&');<\/p>\n<p>        ergebnis.parameter = parameter;\n        ergebnis.url = host + (host.indexOf('?') === -1 ? '?' : '&') + abfrage;\n        ergebnis.curl = 'curl -s -o \/dev\/null -w \"%{http_code}\\\\n\" \\\\\\n  --get \\\\\\n'\n            + parameter.map(function (p) {\n                return '  --data-urlencode ' + hochkomma(p[0] + '=' + p[1]);\n            }).join(' \\\\\\n')\n            + ' \\\\\\n  ' + hochkomma(host);\n        ergebnis.ok = true;\n        return ergebnis;\n    }<\/p>\n<p>    function hochkomma(text) {\n        \/\/ Einfache Anfuehrungszeichen fuer die Kommandozeile absichern.\n        return \"'\" + String(text).replace(\/'\/g, \"'\\\\''\") + \"'\";\n    }<\/p>\n<p>    function besucherkennung(zufall) {\n        \/\/ Matomo erwartet genau sechzehn Hexziffern.\n        const ziffern = '0123456789abcdef';\n        let raus = '';\n        for (let i = 0; i < 16; i++) {\n            const wert = typeof zufall === 'function' ? zufall(i) : Math.floor(Math.random() * 16);\n            raus += ziffern.charAt(Math.abs(Math.floor(wert)) % 16);\n        }\n        return raus;\n    }\n\n    if (typeof window !== 'undefined') {\n        window.LW_TEST = window.LW_TEST || {};\n        window.LW_TEST.MT = { bauen: bauen, besucherkennung: besucherkennung, hochkomma: hochkomma };\n    }\n\n    \/\/ --- Anbindung an das Dokument ---\n\n    const btn = document.getElementById('mt-btn');\n    const out = document.getElementById('mt-ergebnis');\n    const liste = document.getElementById('mt-liste');\n    const addBtn = document.getElementById('mt-add');\n    const artFeld = document.getElementById('mt-art');\n    const ereignisBlock = document.getElementById('mt-ereignis');\n    const zielBlock = document.getElementById('mt-ziel');\n    if (!btn || !out || !liste || !addBtn || !artFeld || !ereignisBlock || !zielBlock) { return; }\n\n    const KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 6px; padding: 14px; margin-bottom: 18px;';\n    const UEBERSCHRIFT = 'color: var(--text-primary, #e8e8ee); font-weight: 700; margin-bottom: 8px;';\n    const FELD = 'padding: 10px; background: var(--bg-panel, #1e1e24); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace;';\n\n    function el(tag, css, text) {\n        const knoten = document.createElement(tag);\n        if (css) { knoten.setAttribute('style', css); }\n        if (text !== undefined &#038;&#038; text !== null) { knoten.textContent = text; }\n        return knoten;\n    }\n\n    function wert(id) {\n        const knoten = document.getElementById(id);\n        return knoten ? knoten.value : '';\n    }\n\n    let zaehler = 0;\n    function zeileErzeugen(vorgabe) {\n        const v = vorgabe || {};\n        zaehler++;\n        const zeile = el('div', 'display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 8px;');\n        zeile.setAttribute('data-mt', 'zeile');\n\n        const nummer = document.createElement('input');\n        nummer.type = 'text';\n        nummer.id = 'mt-dim-nr-' + zaehler;\n        nummer.setAttribute('style', FELD + ' width: 90px;');\n        nummer.setAttribute('data-mt', 'nummer');\n        nummer.placeholder = 'Nr.';\n        nummer.value = v.nummer ? v.nummer : '';\n        zeile.appendChild(nummer);\n\n        const feldwert = document.createElement('input');\n        feldwert.type = 'text';\n        feldwert.id = 'mt-dim-wert-' + zaehler;\n        feldwert.setAttribute('style', FELD + ' flex: 1; min-width: 200px;');\n        feldwert.setAttribute('data-mt', 'wert');\n        feldwert.placeholder = T.ph_dimension;\n        feldwert.value = v.wert ? v.wert : '';\n        zeile.appendChild(feldwert);\n\n        const weg = el('button', 'background: transparent; color: var(--text-secondary, #a0a0b0); border: 1px solid var(--border, #2a2a35); padding: 10px 14px; border-radius: 6px; cursor: pointer;', T.knopf_weg);\n        weg.type = 'button';\n        weg.addEventListener('click', function () {\n            if (zeile.parentNode) { zeile.parentNode.removeChild(zeile); }\n            if (!liste.querySelector('[data-mt=\"zeile\"]')) { zeileErzeugen({}); }\n        });\n        zeile.appendChild(weg);\n\n        liste.appendChild(zeile);\n    }\n\n    function dimensionenLesen() {\n        const knoten = liste.querySelectorAll('[data-mt=\"zeile\"]');\n        const daten = [];\n        for (let i = 0; i < knoten.length; i++) {\n            const nummer = knoten[i].querySelector('[data-mt=\"nummer\"]');\n            const feldwert = knoten[i].querySelector('[data-mt=\"wert\"]');\n            if (!nummer || !feldwert) { continue; }\n            daten.push({ nummer: nummer.value, wert: feldwert.value });\n        }\n        return daten;\n    }\n\n    function bloeckeZeigen() {\n        ereignisBlock.style.display = artFeld.value === 'ereignis' ? 'flex' : 'none';\n        zielBlock.style.display = artFeld.value === 'ziel' ? 'flex' : 'none';\n    }\n\n    function codeKasten(titel, inhalt) {\n        const rahmen = document.createDocumentFragment();\n        rahmen.appendChild(el('div', UEBERSCHRIFT, titel));\n        const code = el('pre', 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); padding: 16px; border-radius: 6px; overflow-x: auto; font-family: monospace; font-size: 0.85rem; line-height: 1.5; white-space: pre-wrap; word-break: break-all; margin-bottom: 18px;', inhalt);\n        rahmen.appendChild(code);\n        return rahmen;\n    }\n\n    function zeigen(erg) {\n        out.textContent = '';\n\n        if (erg.befunde.length) {\n            out.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n            const kasten = el('div', KASTEN);\n            erg.befunde.forEach(function (b) {\n                const z = el('div', 'display: flex; gap: 10px; padding: 4px 0;');\n                z.appendChild(el('span', 'color: ' + (b.schwer ? '#ffb86c' : 'var(--text-secondary, #a0a0b0)') + '; font-family: monospace;', b.schwer ? '!' : '-'));\n                z.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0); font-size: 0.9rem; line-height: 1.5;', b.text));\n                kasten.appendChild(z);\n            });\n            out.appendChild(kasten);\n        }\n\n        out.appendChild(codeKasten(T.h_url, erg.url));\n        out.appendChild(codeKasten(T.h_curl, erg.curl));\n\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_parameter));\n        const tabelle = el('div', KASTEN);\n        erg.parameter.forEach(function (p) {\n            const z = el('div', 'display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 4px 0; border-bottom: 1px solid var(--border, #2a2a35);');\n            z.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0); font-family: monospace;', p[0]));\n            z.appendChild(el('span', 'color: var(--text-primary, #e8e8ee); font-family: monospace; text-align: right; word-break: break-all; max-width: 70%;', p[1]));\n            tabelle.appendChild(z);\n        });\n        out.appendChild(tabelle);\n\n        out.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.85rem; line-height: 1.6;', T.hinweis_server));\n    }\n\n    artFeld.addEventListener('change', bloeckeZeigen);\n    addBtn.addEventListener('click', function () { zeileErzeugen({}); });\n\n    btn.addEventListener('click', function () {\n        const erg = bauen({\n            host: wert('mt-host'),\n            idsite: wert('mt-idsite'),\n            art: artFeld.value,\n            url: wert('mt-url'),\n            name: wert('mt-name'),\n            besucher: wert('mt-besucher'),\n            e_c: wert('mt-e-c'),\n            e_a: wert('mt-e-a'),\n            e_n: wert('mt-e-n'),\n            e_v: wert('mt-e-v'),\n            idgoal: wert('mt-idgoal'),\n            revenue: wert('mt-revenue'),\n            dimensionen: dimensionenLesen()\n        });\n        out.textContent = '';\n        if (!erg.ok) {\n            out.appendChild(el('div', 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid #ffb86c; color: var(--text-secondary, #a0a0b0); padding: 14px; border-radius: 6px;', erg.fehler));\n            return;\n        }\n        zeigen(erg);\n    });\n\n    bloeckeZeigen();\n    zeileErzeugen({ nummer: '1', wert: 'Mitglied' });\n    zeileErzeugen({ nummer: '2', wert: 'Tarif Pro' });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Assembles a request to the Matomo HTTP Tracking API with page views, events, goals and custom dimensions, and points out the mistakes that make a hit disappear without an error.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[91279,91237],"class_list":["post-10244","page","type-page","status-publish","hentry","tag-prywatnosc-danych-pl","tag-self-hosting"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Matomo Tracking API &amp; Custom Dimension Builder - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Matomo Tracking API &amp; Custom Dimension Builder - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Assembles a request to the Matomo HTTP Tracking API with page views, events, goals and custom dimensions, and points out the mistakes that make a hit disappear without an error.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/matomo-tracking-api-builder\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/matomo-tracking-api-builder\\\/\",\"name\":\"Matomo Tracking API & Custom Dimension Builder - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-14T22:30:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/matomo-tracking-api-builder\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/matomo-tracking-api-builder\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/matomo-tracking-api-builder\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Matomo Tracking API &#038; Custom Dimension Builder\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Matomo Tracking API & Custom Dimension Builder - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/","og_locale":"en_US","og_type":"article","og_title":"Matomo Tracking API & Custom Dimension Builder - Lukas Wojcik - Blog","og_description":"Assembles a request to the Matomo HTTP Tracking API with page views, events, goals and custom dimensions, and points out the mistakes that make a hit disappear without an error.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/","og_site_name":"Lukas Wojcik - Blog","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/","name":"Matomo Tracking API & Custom Dimension Builder - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-14T22:30:14+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/matomo-tracking-api-builder\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/"},{"@type":"ListItem","position":3,"name":"Matomo Tracking API &#038; Custom Dimension Builder"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10244","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=10244"}],"version-history":[{"count":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10244\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=10244"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=10244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}