{"id":10428,"date":"2026-08-15T14:39:25","date_gmt":"2026-08-15T12:39:25","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/meta-capi-match-key-planner\/"},"modified":"2026-08-15T14:48:40","modified_gmt":"2026-08-15T12:48:40","slug":"meta-capi-match-key-planner","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/","title":{"rendered":"Meta CAPI Match Key Planner &#038; Hasher"},"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;\">An event with a weak set of match keys is delivered, accepted and counted &#8211; and matched to nobody. The first half below estimates how far a given selection gets; the second normalises and hashes a single value the way Meta expects it, so a mismatch can be seen instead of guessed.<\/p>\n<div style=\"font-family: 'Nunito Sans', sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; margin-bottom: 10px;\">Which parameters does the event carry?<\/div>\n<div id=\"mk-felder\" style=\"display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px 16px; margin-bottom: 18px;\"><\/div>\n<p>    <button id=\"mk-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Assess coverage<\/button><\/p>\n<div id=\"mk-ausgabe\" style=\"margin-top: 22px;\"><\/div>\n<hr style=\"border: none; border-top: 1px solid var(--border, #2a2a35); margin: 28px 0 22px;\">\n<div style=\"font-family: 'Nunito Sans', sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; margin-bottom: 6px;\">Normalise and hash a value<\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 14px; font-size: 0.88rem;\">Meta prescribes an exact form per parameter. A value hashed in the wrong form produces a hash that is valid, accepted and matches nothing.<\/p>\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end;\">\n<div style=\"min-width: 200px;\">\n            <label for=\"mk-art\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Parameter<\/label><br \/>\n            <select id=\"mk-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; box-sizing: border-box;\"><\/select>\n        <\/div>\n<div style=\"flex: 1; min-width: 260px;\">\n            <label for=\"mk-wert\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Raw value<\/label><br \/>\n            <input id=\"mk-wert\" type=\"text\" class=\"form-control\" value=\"  Max.Mustermann@Example.COM \" 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;\">\n        <\/div>\n<p>        <button id=\"mk-hash\" class=\"button\" style=\"background: var(--accent, #7ee787); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Normalise and hash<\/button>\n    <\/div>\n<div id=\"mk-hash-ausgabe\" style=\"margin-top: 18px;\"><\/div>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"An event with a weak set of match keys is delivered, accepted and counted - and matched to nobody. The first half below estimates how far a given selection gets; the second normalises and hashes a single value the way Meta expects it, so a mismatch can be seen instead of guessed.\",\"h_auswahl\":\"Which parameters does the event carry?\",\"knopf_bewerten\":\"Assess coverage\",\"stufe_3\":\"strong\",\"stufe_2\":\"medium\",\"stufe_1\":\"in combination\",\"stufe_name_schwach\":\"weak\",\"stufe_name_ausbaufaehig\":\"worth extending\",\"stufe_name_gut\":\"good\",\"stufe_name_sehr_gut\":\"very good\",\"stufe_name_gewicht_3\":\"strong key - the largest single gain\",\"stufe_name_gewicht_2\":\"medium - worthwhile once the strong ones are in place\",\"stufe_name_gewicht_1\":\"helps only alongside the others\",\"deckung_erklaerung\":\"Coverage of the possible match keys, weighted by how much each one carries on its own.\",\"kein_emq\":\"This is not the Event Match Quality figure. Meta computes that from actual matches; what is shown here is how much material the event gives it to work with.\",\"h_hinweise\":\"Worth knowing about this selection\",\"hinweis_kein_starker\":\"Without email, phone or external ID the match rests on signals that many visitors share.\",\"hinweis_ip_ua_paar\":\"IP address and user agent only work as a pair - one without the other adds almost nothing.\",\"hinweis_fbc_ohne_fbp\":\"fbc only exists when the visit arrived with an fbclid in the link. For every other visit it is empty, and without fbp there is nothing to carry the returning visitor.\",\"hinweis_ort_ohne_land\":\"City, state and postal code are ambiguous without the country.\",\"hinweis_starke_da_rest_fehlt\":\"The strong keys are all there. The remaining gain is small, and adding more parameters is worth less than making sure these three are always populated.\",\"h_fehlend\":\"Missing, largest gain first\",\"h_streuen\":\"Hashed or plain\",\"muss_gestreut\":\"send as SHA-256\",\"darf_nicht_gestreut\":\"send in plain text - hashing it breaks the match\",\"h_normalisieren\":\"Normalise and hash a value\",\"normalisieren_hinweis\":\"Meta prescribes an exact form per parameter. A value hashed in the wrong form produces a hash that is valid, accepted and matches nothing.\",\"label_art\":\"Parameter\",\"label_wert\":\"Raw value\",\"knopf_normalisieren\":\"Normalise and hash\",\"art_email\":\"email address\",\"art_telefon\":\"phone number\",\"art_name\":\"first or last name\",\"art_ort\":\"city\",\"art_kuerzel\":\"state or country code\",\"art_plz\":\"postal code\",\"art_geschlecht\":\"gender\",\"art_datum\":\"date of birth\",\"zeile_roh\":\"entered\",\"zeile_normal\":\"normalised\",\"zeile_hash\":\"SHA-256\",\"bleibt_im_browser\":\"The value is normalised and hashed in this browser. Nothing is sent anywhere.\",\"warn_email\":\"No at sign - that is not an email address.\",\"warn_telefon_null\":\"After the country code comes a zero. That is the national trunk prefix and does not belong in the international form.\",\"warn_telefon_kurz\":\"Fewer than eight digits - the country code is probably missing.\",\"warn_kuerzel\":\"Expected two letters, for example de or pl.\",\"warn_geschlecht\":\"Meta accepts only f or m here.\",\"warn_datum\":\"Expected YYYY-MM-DD, DD.MM.YYYY or YYYYMMDD. Anything else is ambiguous and is not guessed.\",\"warn_krypto\":\"This browser does not provide SHA-256 to the page. That happens without HTTPS.\",\"dezimal\":\".\"};<\/p>\n<p>    \/\/ --- Stammdaten der Parameter -------------------------------------------\n    \/\/ stufe: 3 = starker Schluessel, 2 = mittlerer, 1 = nur in Kombination\n    \/\/ streuen: true = muss als SHA-256 gesendet werden, false = im Klartext\n    const PARAMETER = [\n        { id: 'em',                stufe: 3, streuen: true,  art: 'email' },\n        { id: 'ph',                stufe: 3, streuen: true,  art: 'telefon' },\n        { id: 'external_id',       stufe: 3, streuen: true,  art: 'roh' },\n        { id: 'fbc',               stufe: 3, streuen: false, art: null },\n        { id: 'fbp',               stufe: 2, streuen: false, art: null },\n        { id: 'client_ip_address', stufe: 2, streuen: false, art: null },\n        { id: 'client_user_agent', stufe: 2, streuen: false, art: null },\n        { id: 'fn',                stufe: 2, streuen: true,  art: 'name' },\n        { id: 'ln',                stufe: 2, streuen: true,  art: 'name' },\n        { id: 'ct',                stufe: 1, streuen: true,  art: 'ort' },\n        { id: 'st',                stufe: 1, streuen: true,  art: 'kuerzel' },\n        { id: 'zp',                stufe: 1, streuen: true,  art: 'plz' },\n        { id: 'country',           stufe: 1, streuen: true,  art: 'kuerzel' },\n        { id: 'ge',                stufe: 1, streuen: true,  art: 'geschlecht' },\n        { id: 'db',                stufe: 1, streuen: true,  art: 'datum' }\n    ];<\/p>\n<p>    const HOECHSTWERT = PARAMETER.reduce(function (s, p) { return s + p.stufe; }, 0);<\/p>\n<p>    \/\/ Laendervorwahlen, bei denen eine folgende Null die nationale\n    \/\/ Verkehrsausscheidungsziffer ist und nicht zur Rufnummer gehoert.\n    const VORWAHLEN = ['49', '43', '41', '48', '44', '33', '39', '34', '31', '32', '46', '45', '47', '420'];<\/p>\n<p>    function param(id) {\n        for (let i = 0; i < PARAMETER.length; i++) { if (PARAMETER[i].id === id) { return PARAMETER[i]; } }\n        return null;\n    }\n\n    \/\/ --- Normalisierung ------------------------------------------------------\n\n    function normalisieren(art, wert) {\n        const erg = { wert: '', hinweis: '', ok: true };\n        let s = String(wert === undefined || wert === null ? '' : wert);\n\n        if (art === 'email') {\n            s = s.trim().toLowerCase();\n            erg.wert = s;\n            if (s !== '' &#038;&#038; s.indexOf('@') === -1) { erg.ok = false; erg.hinweis = T.warn_email; }\n            return erg;\n        }\n\n        if (art === 'telefon') {\n            const ziffern = s.replace(\/\\D+\/g, '').replace(\/^0+\/, '');\n            erg.wert = ziffern;\n            for (let i = 0; i < VORWAHLEN.length; i++) {\n                const v = VORWAHLEN[i];\n                if (ziffern.indexOf(v) === 0 &#038;&#038; ziffern.charAt(v.length) === '0') {\n                    erg.hinweis = T.warn_telefon_null;\n                    break;\n                }\n            }\n            if (ziffern !== '' &#038;&#038; ziffern.length < 8) { erg.hinweis = T.warn_telefon_kurz; }\n            return erg;\n        }\n\n        if (art === 'name' || art === 'ort') {\n            \/\/ Kleinbuchstaben, ohne Satzzeichen, Ziffern und Leerraum.\n            \/\/ Umlaute und diakritische Zeichen bleiben erhalten.\n            s = s.toLowerCase().replace(\/[^\\p{L}]+\/gu, '');\n            erg.wert = s;\n            return erg;\n        }\n\n        if (art === 'kuerzel') {\n            s = s.toLowerCase().replace(\/[^a-z]+\/g, '');\n            erg.wert = s;\n            if (s !== '' &#038;&#038; s.length !== 2) { erg.ok = false; erg.hinweis = T.warn_kuerzel; }\n            return erg;\n        }\n\n        if (art === 'plz') {\n            s = s.toLowerCase().replace(\/[^a-z0-9]+\/g, '');\n            erg.wert = s;\n            return erg;\n        }\n\n        if (art === 'geschlecht') {\n            const k = s.trim().toLowerCase();\n            if (\/^(f|w|female|weiblich|frau|kobieta|k)$\/.test(k)) { erg.wert = 'f'; return erg; }\n            if (\/^(m|male|maennlich|m\u00e4nnlich|mann|mezczyzna|m\u0119\u017cczyzna)$\/.test(k)) { erg.wert = 'm'; return erg; }\n            erg.wert = '';\n            erg.ok = false;\n            erg.hinweis = T.warn_geschlecht;\n            return erg;\n        }\n\n        if (art === 'datum') {\n            const k = s.trim();\n            let m;\n            if ((m = \/^(\\d{4})-(\\d{2})-(\\d{2})$\/.exec(k))) { erg.wert = m[1] + m[2] + m[3]; return erg; }\n            if ((m = \/^(\\d{2})\\.(\\d{2})\\.(\\d{4})$\/.exec(k))) { erg.wert = m[3] + m[2] + m[1]; return erg; }\n            if ((m = \/^(\\d{8})$\/.exec(k))) { erg.wert = m[1]; return erg; }\n            erg.wert = '';\n            erg.ok = false;\n            erg.hinweis = T.warn_datum;\n            return erg;\n        }\n\n        erg.wert = s.trim();\n        return erg;\n    }\n\n    \/\/ --- SHA-256 -------------------------------------------------------------\n\n    function streuen(text) {\n        const puffer = new TextEncoder().encode(String(text === undefined || text === null ? '' : text));\n        return crypto.subtle.digest('SHA-256', puffer).then(function (roh) {\n            const bytes = new Uint8Array(roh);\n            let hex = '';\n            for (let i = 0; i < bytes.length; i++) {\n                hex += bytes[i].toString(16).padStart(2, '0');\n            }\n            return hex;\n        });\n    }\n\n    \/\/ --- Bewertung der Abdeckung ---------------------------------------------\n\n    function bewerten(auswahl) {\n        const gewaehlt = {};\n        (auswahl || []).forEach(function (id) { if (param(id)) { gewaehlt[id] = true; } });\n\n        let summe = 0;\n        const fehlend = [];\n        PARAMETER.forEach(function (p) {\n            if (gewaehlt[p.id]) { summe += p.stufe; }\n            else { fehlend.push({ id: p.id, stufe: p.stufe }); }\n        });\n        fehlend.sort(function (a, b) { return b.stufe - a.stufe; });\n\n        const wert = Math.round((summe \/ HOECHSTWERT) * 100) \/ 10;   \/\/ 0 bis 10, eine Nachkommastelle\n\n        let stufe = 'schwach';\n        if (wert >= 8)      { stufe = 'sehr_gut'; }\n        else if (wert >= 6) { stufe = 'gut'; }\n        else if (wert >= 3) { stufe = 'ausbaufaehig'; }<\/p>\n<p>        const hinweise = [];\n        if (!gewaehlt.em && !gewaehlt.ph && !gewaehlt.external_id) { hinweise.push('kein_starker'); }\n        if (gewaehlt.client_ip_address !== gewaehlt.client_user_agent) { hinweise.push('ip_ua_paar'); }\n        if (gewaehlt.fbc && !gewaehlt.fbp) { hinweise.push('fbc_ohne_fbp'); }\n        if ((gewaehlt.ct || gewaehlt.st || gewaehlt.zp) && !gewaehlt.country) { hinweise.push('ort_ohne_land'); }\n        if (gewaehlt.em && gewaehlt.ph && gewaehlt.external_id && wert < 8) { hinweise.push('starke_da_rest_fehlt'); }\n\n        return { wert: wert, summe: summe, hoechstwert: HOECHSTWERT, stufe: stufe, fehlend: fehlend, hinweise: hinweise };\n    }\n\n    \/\/ --- Pruefpunkt ----------------------------------------------------------\n    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.MK = {\n        normalisieren: normalisieren,\n        streuen: streuen,\n        bewerten: bewerten,\n        parameter: PARAMETER,\n        hoechstwert: HOECHSTWERT\n    };\n\n    \/\/ --- Oberflaeche ---------------------------------------------------------\n\n    const felder  = document.getElementById('mk-felder');\n    const btn     = document.getElementById('mk-btn');\n    const out     = document.getElementById('mk-ausgabe');\n    const artWahl = document.getElementById('mk-art');\n    const wertFeld = document.getElementById('mk-wert');\n    const hashBtn = document.getElementById('mk-hash');\n    const hashOut = document.getElementById('mk-hash-ausgabe');\n    if (!felder || !btn || !out) { return; }\n\n    function el(tag, stil, text) {\n        const e = document.createElement(tag);\n        if (stil) { e.setAttribute('style', stil); }\n        if (text !== undefined) { e.textContent = text; }\n        return e;\n    }\n\n    const FARBE_STUFE = { schwach: '#ff6b6b', ausbaufaehig: '#ffa94d', gut: 'var(--accent, #7ee787)', sehr_gut: 'var(--accent, #7ee787)' };\n\n    PARAMETER.forEach(function (p) {\n        const zeile = el('label', 'display: flex; align-items: baseline; gap: 8px; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem; cursor: pointer;');\n        const kasten = document.createElement('input');\n        kasten.type = 'checkbox';\n        kasten.id = 'mk-p-' + p.id;\n        kasten.checked = (p.id === 'em' || p.id === 'client_ip_address' || p.id === 'client_user_agent' || p.id === 'fbp');\n        kasten.style.cssText = 'accent-color: var(--accent, #7ee787); flex-shrink: 0;';\n        zeile.appendChild(kasten);\n        const name = el('span', 'font-family: monospace; color: var(--text-primary, #e8e8ee);', p.id);\n        zeile.appendChild(name);\n        zeile.appendChild(el('span', 'font-size: 0.78rem; color: var(--text-secondary, #a0a0b0);', T['stufe_' + p.stufe]));\n        felder.appendChild(zeile);\n    });\n\n    PARAMETER.forEach(function (p) {\n        if (!p.art || p.art === 'roh') { return; }\n        const o = document.createElement('option');\n        o.value = p.art;\n        o.textContent = p.id + ' \u2013 ' + T['art_' + p.art];\n        if (artWahl &#038;&#038; !Array.prototype.some.call(artWahl.options, function (x) { return x.value === p.art; })) {\n            artWahl.appendChild(o);\n        }\n    });\n\n    const UEBERSCHRIFT = 'font-family: \\'Nunito Sans\\', sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.92rem; margin: 18px 0 8px;';\n\n    btn.addEventListener('click', function () {\n        const auswahl = [];\n        PARAMETER.forEach(function (p) {\n            const k = document.getElementById('mk-p-' + p.id);\n            if (k &#038;&#038; k.checked) { auswahl.push(p.id); }\n        });\n        const erg = bewerten(auswahl);\n        out.innerHTML = '';\n\n        const kopf = el('div', 'display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 4px;');\n        kopf.appendChild(el('span', 'font-family: \\'Nunito Sans\\', sans-serif; font-weight: 800; font-size: 1.6rem; color: ' + FARBE_STUFE[erg.stufe] + ';', erg.wert.toFixed(1).replace('.', T.dezimal) + ' \/ 10'));\n        kopf.appendChild(el('span', 'font-family: \\'Nunito Sans\\', sans-serif; font-weight: 700; color: ' + FARBE_STUFE[erg.stufe] + ';', T['stufe_name_' + erg.stufe]));\n        out.appendChild(kopf);\n        out.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.85rem; margin-bottom: 4px;', T.deckung_erklaerung));\n        out.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.82rem;', T.kein_emq));\n\n        if (erg.hinweise.length) {\n            out.appendChild(el('div', UEBERSCHRIFT, T.h_hinweise));\n            const liste = el('ul', 'margin: 0 0 0 18px; padding: 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem; line-height: 1.6;');\n            erg.hinweise.forEach(function (h) { liste.appendChild(el('li', '', T['hinweis_' + h])); });\n            out.appendChild(liste);\n        }\n\n        if (erg.fehlend.length) {\n            out.appendChild(el('div', UEBERSCHRIFT, T.h_fehlend));\n            const tab = el('div', 'display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; font-size: 0.87rem;');\n            erg.fehlend.slice(0, 6).forEach(function (f) {\n                tab.appendChild(el('span', 'font-family: monospace; color: var(--text-primary, #e8e8ee);', f.id));\n                tab.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0);', T['stufe_name_gewicht_' + f.stufe]));\n            });\n            out.appendChild(tab);\n        }\n\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_streuen));\n        const streutab = el('div', 'display: grid; grid-template-columns: auto 1fr; gap: 3px 14px; font-size: 0.85rem;');\n        PARAMETER.forEach(function (p) {\n            if (auswahl.indexOf(p.id) === -1) { return; }\n            streutab.appendChild(el('span', 'font-family: monospace; color: var(--text-primary, #e8e8ee);', p.id));\n            streutab.appendChild(el('span', 'color: ' + (p.streuen ? 'var(--accent, #7ee787)' : '#ffa94d') + ';', p.streuen ? T.muss_gestreut : T.darf_nicht_gestreut));\n        });\n        out.appendChild(streutab);\n    });\n\n    if (hashBtn) {\n        hashBtn.addEventListener('click', function () {\n            const art = artWahl ? artWahl.value : 'email';\n            const roh = wertFeld ? wertFeld.value : '';\n            const n = normalisieren(art, roh);\n            hashOut.innerHTML = '';\n\n            const tab = el('div', 'display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: 0.87rem; align-items: baseline;');\n            tab.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0);', T.zeile_roh));\n            tab.appendChild(el('span', 'font-family: monospace; color: var(--text-primary, #e8e8ee); word-break: break-all;', JSON.stringify(roh)));\n            tab.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0);', T.zeile_normal));\n            tab.appendChild(el('span', 'font-family: monospace; color: var(--accent, #7ee787); word-break: break-all;', n.wert === '' ? '\u2014' : n.wert));\n            hashOut.appendChild(tab);\n\n            if (n.hinweis) {\n                hashOut.appendChild(el('div', 'color: #ffa94d; font-size: 0.85rem; margin-top: 8px;', n.hinweis));\n            }\n            if (n.wert === '') { return; }\n\n            streuen(n.wert).then(function (hex) {\n                const t2 = el('div', 'display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: 0.87rem; align-items: baseline; margin-top: 6px;');\n                t2.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0);', T.zeile_hash));\n                t2.appendChild(el('span', 'font-family: monospace; color: var(--text-primary, #e8e8ee); word-break: break-all;', hex));\n                hashOut.appendChild(t2);\n                hashOut.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.82rem; margin-top: 8px;', T.bleibt_im_browser));\n            }).catch(function () {\n                hashOut.appendChild(el('div', 'color: #ff6b6b; font-size: 0.85rem; margin-top: 8px;', T.warn_krypto));\n            });\n        });\n    }\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Shows which customer parameters a Conversions API event carries, how far that gets the match, and what each value has to look like before it is hashed. Everything runs in the browser.<\/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":[91057,91061],"class_list":["post-10428","page","type-page","status-publish","hentry","tag-meta-conversions-api","tag-server-side-gtm"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Meta CAPI Match Key Planner &amp; Hasher - 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\/meta-capi-match-key-planner\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Meta CAPI Match Key Planner &amp; Hasher - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Shows which customer parameters a Conversions API event carries, how far that gets the match, and what each value has to look like before it is hashed. Everything runs in the browser.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-15T12:48:40+00:00\" \/>\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\\\/meta-capi-match-key-planner\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/meta-capi-match-key-planner\\\/\",\"name\":\"Meta CAPI Match Key Planner & Hasher - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-15T12:39:25+00:00\",\"dateModified\":\"2026-08-15T12:48:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/meta-capi-match-key-planner\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/meta-capi-match-key-planner\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/meta-capi-match-key-planner\\\/#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\":\"Meta CAPI Match Key Planner &#038; Hasher\"}]},{\"@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":"Meta CAPI Match Key Planner & Hasher - 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\/meta-capi-match-key-planner\/","og_locale":"en_US","og_type":"article","og_title":"Meta CAPI Match Key Planner & Hasher - Lukas Wojcik - Blog","og_description":"Shows which customer parameters a Conversions API event carries, how far that gets the match, and what each value has to look like before it is hashed. Everything runs in the browser.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-08-15T12:48:40+00:00","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\/meta-capi-match-key-planner\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/","name":"Meta CAPI Match Key Planner & Hasher - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-15T12:39:25+00:00","dateModified":"2026-08-15T12:48:40+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/meta-capi-match-key-planner\/#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":"Meta CAPI Match Key Planner &#038; Hasher"}]},{"@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\/10428","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=10428"}],"version-history":[{"count":1,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10428\/revisions"}],"predecessor-version":[{"id":10446,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10428\/revisions\/10446"}],"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=10428"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=10428"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}