Integration in 3 Minuten
TrackHub empfängt Browser-Events, verarbeitet sie serverseitig und leitet sie simultan an Meta CAPI, GA4, TikTok Events API und weitere Plattformen weiter — ad-blocker-proof, DSGVO-konform, EU-gehostet.
<script>-Tag mit deinem API-Key in den <head> deines Shops.trackhub.track('purchase', {...}) — der Rest passiert automatisch.Script einbinden
Den folgenden Snippet so früh wie möglich in den <head> deiner Seite. Den API-Key findest du im Dashboard unter Properties → Script.
<!-- TrackHub Script — so früh wie möglich im <head> --> <script src="https://collect.trackhub.dev/v1/th.min.js" data-key="th_YOUR_API_KEY" async ></script>
Mit eigenem CNAME (empfohlen)
Für First-Party Tracking via CNAME-Setup wird das Script von deiner eigenen Subdomain ausgeliefert. Konfiguration im Dashboard unter Properties → CNAME.
<!-- Mit CNAME: Script von eigener Domain --> <script src="https://metrics.yourshop.com/v1/th.min.js" data-key="th_YOUR_API_KEY" async ></script>
Erstes Event senden
Nach dem Einbinden des Scripts ist trackhub global verfügbar. pageview wird automatisch gesendet — manuelle Events so:
// Einfachstes mögliches Event trackhub.track('purchase', { order_id: 'ORD-2024-001', value: 99.80, currency: 'EUR', user: { email: 'kunde@example.com', // wird automatisch SHA-256 gehasht phone: '+4917612345678', }, }) // Pre-Queue: funktioniert vor Script-Load window.trackhub = window.trackhub || []; window.trackhub.push(['track', 'purchase', { value: 99.80 }])
Live-Validierung
Events erscheinen sofort im Live-Stream unter Dashboard → Live. Delivery-Status pro Plattform sichtbar:
Konfiguration
Das Script konfiguriert sich über das data-*-Attribut am Script-Tag oder via window.__TH_CONFIG__.
<script src="https://collect.trackhub.dev/v1/th.min.js" data-key="th_YOUR_API_KEY" async ></script>
| Attribut | Typ | Default | Beschreibung |
|---|---|---|---|
| data-key | string | — | required Property API-Key aus dem Dashboard |
trackhub.track()
Zentraler Einstiegspunkt für alle manuellen Events.
| Parameter | Typ | Beschreibung |
|---|---|---|
| eventName | string | required Event-Name (z.B. purchase, add_to_cart) |
| payload | object | optional Event-Daten. Automatisch ergänzt um client_id, session_id, utm-Daten |
Automatisch angehängte Felder
TrackHub ergänzt jeden Event-Payload serverseitig automatisch:
{
event_id: "th_a3f8...", // deterministisch, für Dedup
client_id: "cl_...", // FPCS Cookie / localStorage
session_id: "se_...", // Session-scoped
page_url: "https://...", // aktueller Pfad
referrer: "https://...", // document.referrer
user_agent: "Mozilla/...", // client-seitig
utm: { source: "google", medium: "cpc", ... },
click_ids: { gclid: "...", fbclid: "..." },
}
Consent API
Integration mit eigenem Consent-Manager oder dem mitgelieferten TrackHub-Banner.
// Consent setzen (nach Nutzer-Bestätigung) trackhub.setConsent({ analytics: true, marketing: true, necessary: true, }) // Aktuellen Consent auslesen const consent = trackhub.getConsent() // → { analytics: true, marketing: false, necessary: true } // Google Consent Mode v2 — automatisch via gtag() Hook // TrackHub liest gtag('consent', 'update', {...}) automatisch aus // Kein weiterer Code erforderlich wenn GCM konfiguriert ist
pageview wird immer gesendet, da technisch notwendig.Identity API
Client-ID manuell setzen für Cross-Device-Tracking — z.B. nach Login.
// Client-ID nach Login setzen (ermöglicht Cross-Device) trackhub.setClientId('user_12345') // Aktuelle Client-ID lesen const cid = trackhub.getClientId() // UTM-Daten aus aktuellem Session auslesen const utm = trackhub.getUtm() // → { source: 'google', medium: 'cpc', campaign: 'de_brand_q4' } // UTMs zurücksetzen (z.B. bei Logout) trackhub.clearUtm()
Standard Events
TrackHub kennt ~45 Standard-Events, gruppiert nach Use-Case. Jedes Standard-Event wird automatisch auf das plattformspezifische Schema (Meta CAPI, GA4, TikTok, Pinterest, LinkedIn, Bing UET, Klaviyo) gemappt. Nicht-unterstützte Events werden pro Plattform geskippt — kein Fehler.
Custom Event-Namen (alles außerhalb dieser Liste) werden 1:1 an alle Plattformen durchgereicht.
E-Commerce Funnel
Der vollständige Conversion-Funnel mit allen Stufen. Sende diese Events in der Reihenfolge wie sie auf der Website auftreten — TrackHub mapped sie automatisch auf das jeweilige Plattform-Schema (Meta CAPI, GA4-Items, TikTok-Contents, Klaviyo-Items).
view_item_list
Kategorieseite oder Suchergebnis-Liste angezeigt.
trackhub.track('view_item_list', { item_list_id: 'cat_42', item_list_name: 'Sneaker', contents: [ { id: 'SKU-12345', name: 'Sneaker X Pro', price: 89.90 }, { id: 'SKU-12346', name: 'Sneaker Y Lite', price: 59.90 }, ], })
view_content
Produkt-Detailseite (PDP) aufgerufen.
trackhub.track('view_content', { content_id: 'SKU-12345', content_name: 'Sneaker X Pro', content_category: 'Sneaker', content_type: 'product', value: 89.90, currency: 'EUR', brand: 'Acme', })
add_to_cart
trackhub.track('add_to_cart', { content_id: 'SKU-12345', content_name: 'Sneaker X Pro', value: 89.90, currency: 'EUR', quantity: 1, })
view_cart
Warenkorb-Seite aufgerufen — bei JTL: /Warenkorb, bei Shopify: /cart.
trackhub.track('view_cart', { value: 179.80, currency: 'EUR', num_items: 2, contents: [ { id: 'SKU-12345', quantity: 1, price: 89.90 }, { id: 'SKU-67890', quantity: 1, price: 89.90 }, ], })
initiate_checkout
Checkout-Einstieg — Login- bzw. Register-Schritt.
trackhub.track('initiate_checkout', { value: 179.80, currency: 'EUR', num_items: 2, contents: [ { id: 'SKU-12345', quantity: 1, price: 89.90 }, { id: 'SKU-67890', quantity: 1, price: 89.90 }, ], })
add_shipping_info
Versandadresse + Versandart eingegeben.
trackhub.track('add_shipping_info', { value: 179.80, currency: 'EUR', shipping_tier: 'standard', contents: [/* ... */], })
add_payment_info
Zahlungsmethode gewählt.
trackhub.track('add_payment_info', { value: 179.80, currency: 'EUR', payment_type: 'credit_card', contents: [/* ... */], })
purchase
Bestellung abgeschlossen. Pflichtfeld: order_id für Deduplication.
trackhub.track('purchase', { order_id: 'ORD-2024-001', value: 179.80, currency: 'EUR', shipping: 4.90, tax: 28.65, coupon: 'BLACKFRIDAY', contents: [ { id: 'SKU-12345', name: 'Sneaker X Pro', quantity: 1, price: 89.90 }, { id: 'SKU-67890', name: 'Socken Pack', quantity: 1, price: 89.90 }, ], user: { email: 'kunde@example.com', phone: '+4917612345678', first_name: 'Max', last_name: 'Mustermann', zip: '80331', country: 'DE', }, })
refund
Rückerstattung. Sendet order_id, optional Items für Teilretouren.
trackhub.track('refund', { order_id: 'ORD-2024-001', value: 89.90, currency: 'EUR', contents: [ { id: 'SKU-67890', quantity: 1, price: 89.90 }, ], })
add_to_wishlist / remove_from_cart
Funktionieren analog zu add_to_cart:
trackhub.track('add_to_wishlist', { content_id: 'SKU-12345', value: 89.90, currency: 'EUR', }) trackhub.track('remove_from_cart', { content_id: 'SKU-12345', quantity: 1, value: 89.90, currency: 'EUR', })
event_id aus order_id + event_name. Bei purchase und refund sind doppelt gesendete Events damit auf Browser- und Server-Side gegen Duplikate geschützt.Properties-Referenz
Eine Übersicht aller verfügbaren Felder pro Event:
| Feld | Typ | Required | Beschreibung |
|---|---|---|---|
| order_id | string | required* | Bei purchase/refund Pflicht (Dedup). |
| value | float | optional | Monetärer Gesamtwert. |
| currency | string | optional | ISO 4217 (z.B. EUR). Wird auto-uppercased. |
| content_id | string | optional | Einzelprodukt-SKU. |
| content_name | string | optional | Produktname. |
| content_category | string | optional | Kategorie-Name. |
| content_type | string | optional | Standard product; auch home_listing, travel. |
| brand | string | optional | Markenname. |
| quantity | int | optional | Einzel-Item-Menge. |
| num_items | int | optional | Gesamt-Items. Wird auto-berechnet aus contents. |
| contents | array | optional | Multi-Product-Cart, siehe unten. |
| shipping | float | optional | Versandkosten. |
| tax | float | optional | Steueranteil. |
| coupon | string | optional | Gutschein-Code. |
| shipping_tier | string | optional | Versandart bei add_shipping_info. |
| payment_type | string | optional | Zahlungsmethode bei add_payment_info. |
| item_list_id | string | optional | Kategorie/Listen-ID bei view_item_list. |
| item_list_name | string | optional | Kategorie/Listen-Name. |
| promotion_id | string | optional | Bei view_promotion/select_promotion. |
| promotion_name | string | optional | Promo-Name. |
contents[] — Item-Schema
| Feld | Typ | Required | Beschreibung |
|---|---|---|---|
| id | string | required | Produkt-SKU / Identifier. |
| name | string | optional | Produktname. |
| price | float | optional | Einzelpreis (nicht Gesamtpreis). |
| quantity | int | optional | Menge (Default: 1). |
| category | string | optional | Kategorie-Name. |
| brand | string | optional | Markenname. |
| variant | string | optional | Variante (z.B. Farbe, Größe). |
| coupon | string | optional | Item-Level-Gutschein. |
| discount | float | optional | Item-Level-Rabatt. |
Lead & Account
Events für Lead-Generierung, Formulare und Account-Aktionen. Alle user.* Felder werden serverseitig SHA-256-gehasht — gib sie als Plaintext an.
lead
Generische Lead-Erfassung (Newsletter, Whitepaper-Download, Kontaktformular).
trackhub.track('lead', { lead_type: 'newsletter', value: 5.00, currency: 'EUR', user: { email: 'user@example.com', phone: '+4917612345678', }, })
qualified_lead
Lead mit Qualifizierung (B2B / Sales Funnel). Wird auf LinkedIn als nativer QUALIFIED_LEAD gesendet, auf allen anderen Plattformen als normaler Lead.
trackhub.track('qualified_lead', { lead_type: 'mql', // 'mql' | 'sql' value: 250.00, user: { email: 'user@example.com' }, })
contact / form_submit / schedule / submit_application
Speziellere Lead-Varianten — werden auf Meta als Contact, Schedule, SubmitApplication gesendet.
// Kontaktanfrage trackhub.track('contact', { user: { email: 'user@example.com' } }) // Termin / Demo gebucht trackhub.track('schedule', { value: 0, user: { email: 'user@example.com' }, }) // Bewerbung / Antrag trackhub.track('submit_application', { lead_type: 'job_application', user: { email: 'user@example.com', first_name: 'Max' }, })
complete_registration / login
trackhub.track('complete_registration', { method: 'email', // 'email' | 'google' | 'apple' | ... user: { email: 'user@example.com' }, }) trackhub.track('login', { method: 'google', user: { email: 'user@example.com' }, })
start_trial / subscribe
trackhub.track('start_trial', { value: 0, currency: 'EUR', predicted_ltv: 588.00, // jährlicher Plan-Wert user: { email: 'user@example.com' }, }) trackhub.track('subscribe', { value: 49.00, currency: 'EUR', order_id: 'sub_2024_001', user: { email: 'user@example.com' }, })
Content & Engagement
Events für Content-Interaktion. Diese werden primär an GA4 weitergeleitet (das volle native Engagement-Tracking unterstützt). Meta/TikTok ignorieren sie meist.
video_play / video_complete
trackhub.track('video_play', { video_title: 'Product Tour 2024', video_duration: 120, // Gesamtlänge in Sekunden video_percent: 0, // aktueller Fortschritt video_provider: 'youtube', }) trackhub.track('video_complete', { video_title: 'Product Tour 2024', video_duration: 120, video_percent: 100, })
file_download
trackhub.track('file_download', { file_name: 'Whitepaper-2024.pdf', file_extension: 'pdf', link_url: 'https://shop.de/dl/whitepaper.pdf', })
scroll_depth / button_click / outbound_click
trackhub.track('scroll_depth', { percent_scrolled: 75 }) trackhub.track('button_click', { button_text: 'Jetzt kaufen', button_id: 'cta-pdp-buy', }) trackhub.track('outbound_click', { link_url: 'https://partner.de/page', // link_domain wird automatisch aus link_url abgeleitet })
share / rate
trackhub.track('share', { method: 'twitter', // 'twitter' | 'facebook' | 'email' | ... content_type: 'product', content_id: 'SKU-12345', }) trackhub.track('rate', { content_id: 'SKU-12345', rating: 4.5, // 1-5 Stars })
Branchen-spezifisch
Events für spezielle Verticals (Automotive, Real Estate, Travel, NGO, Service). Werden auf Meta meist als native Standard-Events gemappt, auf anderen Plattformen als Lead oder Purchase mit erweiterten Properties.
find_location
Store-/Filialfinder genutzt.
trackhub.track('find_location', { location_id: 'store_muc_01', })
customize_product
Produkt-Konfigurator durchlaufen.
trackhub.track('customize_product', { content_id: 'SKU-CUSTOM-001', content_name: 'Konfigurierter Stuhl', value: 449.00, currency: 'EUR', })
donate
Spende abgeschlossen (NGO).
trackhub.track('donate', { value: 50.00, currency: 'EUR', content_name: 'Hilfsprojekt XY', user: { email: 'spender@example.com' }, })
submit_test_drive
Probefahrt angefragt (Automotive).
trackhub.track('submit_test_drive', { content_id: 'model_x_2024', content_name: 'Model X 2024', user: { email: 'interessent@example.com' }, })
view_listing
Immobilien-/Mietobjekt-Listing besucht (etwas spezifischer als view_content, kann auch Kategorie-Listings abdecken).
trackhub.track('view_listing', { content_id: 'listing_4711', content_name: '3-Zimmer Altbau München', content_category: 'Mietwohnung', content_type: 'home_listing', value: 1450.00, currency: 'EUR', })
book_travel
Reise gebucht. Strukturell wie purchase, mit content_type: 'travel'.
trackhub.track('book_travel', { order_id: 'BK-2024-001', content_type: 'travel', value: 899.00, currency: 'EUR', user: { email: 'reisende@example.com' }, })
Inbound Field-Aliasing
TrackHub akzeptiert eingehende Events mit unterschiedlichen Feldnamen je nach Sender (GA4-, Meta-Pixel-, WooCommerce-, Shopify-, Klaviyo-Style). Vor der Speicherung werden alle Daten auf das kanonische Schema normalisiert.
Das heißt konkret: Du musst auf Sender-Seite kein Schema-Mapping machen — sende was dein System dir gibt, TrackHub übersetzt automatisch. Kanonische Keys haben dabei immer Vorrang, wenn beide gesetzt sind.
Top-Level Feld-Aliase
| Kanonisch | Akzeptierte Aliase |
|---|---|
| content_id | product_iditem_idskuProductID |
| content_ids | product_idsitem_ids |
| content_name | product_nameitem_nametitleProductNamename |
| content_type | item_typeproduct_type |
| content_category | item_categoryproduct_categorycategory |
| brand | item_brandproduct_brandmanufacturerBrand |
| value | amountrevenuetotalsubtotalprice |
| currency | currency_codeiso_currencyCurrency |
| order_id | transaction_idorder_numberinvoice_numberOrderId |
| contents | itemsline_itemsproductscart_itemsItems |
| search_string | search_termqueryqSearchTerm |
| shipping | shipping_costshipping_amountShipping |
| tax | tax_amountTax |
| coupon | coupon_codediscount_codevoucherDiscountCode |
| payment_type | payment_methodpay_method |
| shipping_tier | shipping_methoddelivery_method |
| link_url | hrefurloutbound_url |
Item-Level Aliase (innerhalb von contents[])
| Kanonisch | Akzeptierte Aliase |
|---|---|
| id | product_iditem_idskucontent_idProductID |
| name | product_nameitem_nametitleProductName |
| price | item_priceunit_priceamountItemPrice |
| quantity | qtyQuantitycountnum |
| category | item_categoryproduct_categoryCategories |
| brand | item_brandproduct_brandBrandmanufacturer |
| variant | item_variantvariant_titlesku_variant |
Beispiel — WooCommerce-Style automatisch normalisiert
Eingehendes Event (z.B. von einem WooCommerce-Plugin):
{
"event_name": "purchase",
"event_data": {
"product_id": "12345",
"product_name": "Sneaker X Pro",
"total": 179.80,
"currency_code": "eur",
"transaction_id": "ORD-001",
"line_items": [
{ "product_id": "A", "qty": 2, "item_price": 89.90 }
]
}
}
Nach Normalisierung in der TrackHub-DB:
{
"content_id": "12345",
"content_name": "Sneaker X Pro",
"value": 179.80,
"currency": "EUR",
"order_id": "ORD-001",
"num_items": 2,
"contents": [
{ "id": "A", "quantity": 2, "price": 89.90 }
]
}
Custom Events
Beliebige Event-Namen außerhalb der Standard-Events sind erlaubt. TrackHub leitet sie 1:1 an alle Plattformen durch, die Custom Events unterstützen:
- Meta CAPI: als Custom Event gesendet — taucht in Events Manager unter "Custom Events" auf
- GA4: 1:1 weitergeleitet, in GA4 als Custom Event sichtbar (max. 50 Custom Events pro Property)
- TikTok: als Custom Event gesendet
- Pinterest: als Custom Event gesendet
- Klaviyo: als generisches Event mit dem gewählten Namen
- LinkedIn / Bing UET / Google Ads: nur Standard-Events, Custom werden geskippt
Properties werden ebenfalls durchgereicht — bekannte Felder (value, currency, order_id, contents) werden trotzdem normalisiert.
// Chat geöffnet trackhub.track('chat_opened', { widget: 'intercom' }) // Konfigurator-Schritt trackhub.track('configurator_step', { step: 2, label: 'Farbe wählen', value: 'Schwarz', }) // Newsletter-Bounce trackhub.track('newsletter_bounce', { reason: 'hard_bounce', user: { email: 'invalid@example.com' }, })
snake_case für Event-Namen — konsistent mit den Standard-Events. Vermeide Leerzeichen, Sonderzeichen und Großbuchstaben in Event-Namen (Klaviyo macht ausnahmsweise eine eigene Konvention).HTTP API
Für Server-to-Server-Events oder Custom-Implementierungen. Keine Client-Side-Dependency.
Request
curl -X POST https://collect.trackhub.dev/collect/th_YOUR_API_KEY \ -H "Content-Type: application/json" \ -d '{ "event": "purchase", "order_id": "ORD-2024-001", "value": 99.80, "currency": "EUR", "user": { "email": "kunde@example.com" }, "client_id": "optional_if_available" }'
PHP Beispiel
$response = Http::post('https://collect.trackhub.dev/collect/' . $apiKey, [ 'event' => 'purchase', 'order_id' => $order->id, 'value' => $order->total, 'currency' => 'EUR', 'user' => [ 'email' => $order->email, // TrackHub hasht serverseitig ], ]); if ($response->successful()) { Log::info('TrackHub event accepted', ['event_id' => $response->json('event_id')]); }
Response
{
"ok": true,
"event_id": "a3f8b2c1-d4e5-f6a7-b8c9-d0e1f2a3b4c5"
}
Authentication
Der Collect-Endpoint benötigt keinen Authorization-Header — der API-Key ist Teil der URL. Management-API-Calls (Properties, Integrationen) nutzen Bearer-Token.
curl https://app.trackhub.dev/api/v1/properties \ -H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \ -H "Accept: application/json"
Payload Referenz
Alle Felder die im Event-Payload an /collect/{api_key} gesendet werden können.
| Feld | Typ | Status | Beschreibung |
|---|---|---|---|
| event | string | required | Event-Name (z.B. purchase) |
| value | float | optional | Monetärer Wert des Events |
| currency | string | optional | ISO 4217 (z.B. EUR) |
| order_id | string | optional | Für Deduplication bei Purchase-Events |
| content_id | string | optional | Produkt-SKU oder Content-Identifier |
| content_name | string | optional | Produktname oder Seitenbezeichnung |
| contents | array | optional | Warenkorb-Items (siehe E-Commerce Events) |
| user.email | string | optional | Wird SHA-256 gehasht |
| user.phone | string | optional | E.164 Format, wird gehasht |
| user.first_name | string | optional | Vorname, wird gehasht |
| client_id | string | optional | Browser-Client-ID für Event-Matching |
| event_id | string | optional | Eigene Event-ID für Deduplication |
Unterstützte Plattformen
Alle Integrationen werden im Dashboard konfiguriert. Das Routing passiert vollautomatisch.
Event-Mapping Beispiel: purchase
// TrackHub purchase event → // Meta CAPI { event_name: "Purchase", custom_data: { value: 99.80, currency: "EUR" } } // GA4 Measurement Protocol { name: "purchase", params: { transaction_id: "ORD-001", value: 99.80 } } // TikTok Events API { event: "CompletePayment", properties: { value: 99.80, currency: "EUR" } }
CNAME / First-Party Cookie Server
Mit CNAME-Setup laufen alle Requests über deine eigene Domain — maximale Browser-Kompatibilität, kein ITP-Blocking, HttpOnly First-Party Cookies.
DNS-Konfiguration
# Deinen Nameserver eintragen: metrics.yourshop.com. CNAME collect.trackhub.dev.
metrics.yourshop.com → collect.trackhub.devhttps://metrics.yourshop.com/v1/th.min.js ändern.Google Consent Mode v2
TrackHub liest den Consent-State aus dem gtag('consent', 'update', {...})-Hook automatisch aus. Events werden entsprechend gefiltert oder als Modeled Conversions weitergesendet.
// Standard GCM Default (vor Consent-Entscheidung) gtag('consent', 'default', { ad_storage: 'denied', analytics_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied', wait_for_update: 500, }) // Nach Nutzer-Bestätigung gtag('consent', 'update', { ad_storage: 'granted', analytics_storage: 'granted', ad_user_data: 'granted', ad_personalization: 'granted', }) // TrackHub reagiert automatisch auf gtag consent updates // Kein separater trackhub.setConsent() nötig wenn GCM aktiv
JTL-Shop Plugin
Native JTL-Shop Integration für automatisches E-Commerce Event-Tracking ohne eigenen JavaScript-Code.
Automatisch getrackte Events
WooCommerce Integration
Vollständiger E-Commerce-Funnel für WooCommerce via WordPress Hooks + Frontend-Script.
1. Script einbinden — functions.php
define('TH_API_KEY', 'th_YOUR_API_KEY'); add_action('wp_head', function() { echo '<script src="https://collect.trackhub.dev/v1/th.min.js" data-key="' . TH_API_KEY . '" async></script>'; });
2. view_content — Produktseite
add_action('woocommerce_after_single_product', function() { global $product; if (!$product) return; ?> <script> trackhub.track('view_content', { content_id: '<?= esc_js($product->get_sku() ?: $product->get_id()) ?>', content_name: '<?= esc_js($product->get_name()) ?>', content_type: 'product', value: <?= (float) $product->get_price() ?>, currency: '<?= get_woocommerce_currency() ?>', }); </script> <?php });
3. add_to_cart — Warenkorb
// WooCommerce AJAX ATC Event abfangen jQuery(document).on('added_to_cart', function(e, fragments, cart_hash, $btn) { trackhub.track('add_to_cart', { content_id: $btn.data('product_id')?.toString(), content_name: $btn.closest('.product').find('.woocommerce-loop-product__title').text().trim(), content_type: 'product', value: parseFloat($btn.data('product_price') || 0), currency: wc_add_to_cart_params?.currency || 'EUR', quantity: parseInt($btn.closest('form').find('[name="quantity"]').val() || 1), }) })
4. initiate_checkout — Checkout-Start
add_action('woocommerce_before_checkout_form', function() { $cart = WC()->cart; $items = []; foreach ($cart->get_cart() as $item) { $product = $item['data']; $items[] = [ 'content_id' => (string) ($product->get_sku() ?: $product->get_id()), 'content_name' => $product->get_name(), 'quantity' => (int) $item['quantity'], 'price' => (float) $product->get_price(), ]; } ?> <script> trackhub.track('initiate_checkout', { value: <?= (float) $cart->get_total('edit') ?>, currency: '<?= get_woocommerce_currency() ?>', num_items: <?= $cart->get_cart_contents_count() ?>, contents: <?= json_encode($items) ?>, }); </script> <?php });
5. purchase — Bestellabschluss (serverseitig)
add_action('woocommerce_payment_complete', function($order_id) { $order = wc_get_order($order_id); $items = []; foreach ($order->get_items() as $item) { $product = $item->get_product(); $items[] = [ 'content_id' => (string) ($product?->get_sku() ?: $item->get_product_id()), 'content_name' => $item->get_name(), 'quantity' => (int) $item->get_quantity(), 'price' => (float) ($item->get_total() / $item->get_quantity()), ]; } wp_remote_post('https://collect.trackhub.dev/collect/' . TH_API_KEY, [ 'headers' => ['Content-Type' => 'application/json'], 'body' => json_encode([ 'event' => 'purchase', 'order_id' => (string) $order_id, 'value' => (float) $order->get_total(), 'currency' => $order->get_currency(), 'contents' => $items, 'user' => [ 'email' => $order->get_billing_email(), 'phone' => $order->get_billing_phone(), 'first_name' => $order->get_billing_first_name(), 'last_name' => $order->get_billing_last_name(), 'zip' => $order->get_billing_postcode(), 'country' => $order->get_billing_country(), 'city' => $order->get_billing_city(), ], ]), ]); });
Übersicht: Alle Events
Shopify Integration
Vollständiger E-Commerce-Funnel für Shopify. Einbindung via theme.liquid für Storefront-Events und Shopify Web Pixels oder checkout.liquid für Checkout-Events.
1. Script einbinden — theme.liquid
{%- comment -%} TrackHub — so früh wie möglich im <head> {%- endcomment -%} <script src="https://collect.trackhub.dev/v1/th.min.js" data-key="th_YOUR_API_KEY" async ></script>
2. view_content — Produktseite
In sections/main-product.liquid oder am Ende von templates/product.liquid:
<script> trackhub.track('view_content', { content_id: '{{ product.selected_or_first_available_variant.sku }}', content_name: '{{ product.title | escape }}', content_type: 'product', content_category: '{{ product.type | escape }}', value: {{ product.selected_or_first_available_variant.price | divided_by: 100.0 }}, currency: '{{ shop.currency }}', }) </script>
3. add_to_cart — Warenkorb
Per JavaScript-Event beim Klick auf den ATC-Button:
// ATC via fetch() abfangen (Dawn Theme Pattern) document.addEventListener('click', (e) => { const btn = e.target.closest('[data-add-to-cart], .product-form__submit') if (!btn) return const form = btn.closest('form') const variantId = form?.querySelector('[name="id"]')?.value // Produktdaten aus data-Attribut oder Shopify global const price = parseFloat(btn.dataset.price || 0) / 100 trackhub.track('add_to_cart', { content_id: variantId, content_name: btn.dataset.productTitle || document.title, content_type: 'product', value: price, currency: window.Shopify?.currency?.active || 'EUR', quantity: parseInt(form?.querySelector('[name="quantity"]')?.value || 1), }) })
4. initiate_checkout — Checkout-Start
Auf der Cart-Seite beim Klick auf "Zur Kasse":
<script> // Shopify Cart-Objekt ist auf der Cart-Seite verfügbar document.querySelector('[name="checkout"]') ?.addEventListener('click', () => { const cart = {{ cart | json }} trackhub.track('initiate_checkout', { value: (cart.total_price / 100).toFixed(2), currency: cart.currency, num_items: cart.item_count, contents: cart.items.map(item => ({ content_id: item.variant_id.toString(), content_name: item.product_title, quantity: item.quantity, price: (item.price / 100).toFixed(2), })), }) }) </script>
5. purchase — Bestellabschluss
Auf der Order Status Page (Einstellungen → Checkout → Additional Scripts):
{% if first_time_accessed %}
<script
src="https://collect.trackhub.dev/v1/th.min.js"
data-key="th_YOUR_API_KEY"
async
></script>
<script>
trackhub.track('purchase', {
order_id: '{{ order.order_number }}',
value: {{ order.total_price | money_without_currency | remove: ',' }},
currency: '{{ shop.currency }}',
num_items: {{ order.line_items | size }},
contents: [
{% for line_item in order.line_items %}
{
content_id: '{{ line_item.variant_id }}',
content_name: '{{ line_item.title | escape }}',
quantity: {{ line_item.quantity }},
price: {{ line_item.price | money_without_currency | remove: ',' }},
}{% unless forloop.last %},{% endunless %}
{% endfor %}
],
user: {
email: '{{ customer.email }}',
phone: '{{ customer.phone }}',
first_name: '{{ customer.first_name | escape }}',
last_name: '{{ customer.last_name | escape }}',
zip: '{{ customer.default_address.zip }}',
country: '{{ customer.default_address.country_code }}',
city: '{{ customer.default_address.city | escape }}',
},
})
</script>
{% endif %}
6. search — Suche
{% if search.performed %}
<script>
trackhub.track('search', {
search_string: '{{ search.terms | escape }}',
results: {{ search.results_count }},
})
</script>
{% endif %}
Übersicht: Alle Events
Deduplication
TrackHub verhindert doppelte Events auf zwei Ebenen: client-seitig via Session-Storage und server-seitig via deterministischer event_id.
Automatische event_id
Das Script generiert für jeden Event eine deterministisch aus Kontext-Daten abgeleitete ID. Identische Events (gleicher Typ + gleiche Page + gleiches Zeitfenster) erhalten dieselbe ID — Plattformen wie Meta CAPI ignorieren Duplikate automatisch.
Eigene event_id übergeben
Für Server-Side Events immer eine eigene stabile ID mitgeben — z.B. order_id + event_name:
trackhub.track('purchase', { order_id: 'ORD-2024-001', event_id: 'purchase_ORD-2024-001', // stabile, reproduzierbare ID value: 99.80, currency: 'EUR', })
Http::post('https://collect.trackhub.dev/collect/' . $apiKey, [ 'event' => 'purchase', 'event_id' => 'purchase_' . $order->id, // verhindert Doppel-Billing 'order_id' => (string) $order->id, 'value' => $order->total, ]);
event_id senden. Meta CAPI und GA4 deduplizieren automatisch — kein doppeltes Reporting.Fehlerbehandlung & Retry
TrackHub verarbeitet Events queue-basiert via Laravel Horizon. Delivery-Fehler werden automatisch wiederholt.
Retry-Logik
| Versuch | Delay | Verhalten |
|---|---|---|
| 1 | sofort | Erster Delivery-Versuch |
| 2 | 60s | Exponential Backoff |
| 3 | 300s | Exponential Backoff |
| 4 | 900s | Letzter Versuch |
| — | — | Status → failed, Health-Check Alert |
HTTP Status Codes — Collect Endpoint
| Status | Bedeutung |
|---|---|
| 202 | Event akzeptiert und in Queue eingereiht |
| 400 | Ungültiger Payload (fehlendes event Feld) |
| 401 | Ungültiger oder unbekannter API-Key |
| 422 | Validierungsfehler (z.B. value ist kein Float) |
| 429 | Rate Limit überschritten (Plan-abhängig) |
Delivery-Status prüfen
Im Dashboard unter Live-Stream ist der Delivery-Status jedes Events pro Plattform in Echtzeit sichtbar. Fehlgeschlagene Deliveries mit Fehlermeldung der Ziel-API unter Properties → Health.
202 vom Collect-Endpoint bedeutet nur, dass TrackHub das Event akzeptiert hat — nicht dass die Weiterleitung erfolgreich war. Delivery-Status separat im Dashboard prüfen.Analytics API
Alle Dashboard-Daten sind per API abrufbar — für Custom-Dashboards, BI-Systeme oder automatisierte Reports.
KPI Summary
{
"data": {
"period": { "from": "2026-03-01", "to": "2026-03-31" },
"kpis": {
"purchases": 252,
"add_to_carts": 2605,
"pageviews": 190300,
"revenue": 37947.00,
"unique_visitors": 38400
}
}
}
Daily Stats
Event Stats
Parameter period: 24h · 7d · 30d — oder from / to als ISO-Datum.
Funnel
curl "https://app.trackhub.dev/api/v1/properties/PROP_ID/analytics/funnel?\ steps[]=pageview&steps[]=add_to_cart&steps[]=purchase" \ -H "Authorization: Bearer YOUR_TOKEN"
Attribution
Parameter model: first_touch · last_touch · linear
Postback URLs
Für Affiliate-Netzwerke (Affise, Everflow, HasOffers) oder Custom-Systeme ohne offizielle Server-API. Bei definierten Events wird automatisch ein HTTP-Request an die hinterlegte URL gefeuert.
Token-Referenz
| Token | Quelle | Beschreibung |
|---|---|---|
| {event_name} | Event | z.B. purchase |
| {event_id} | Event | Deterministisch generierte Event-ID |
| {order_id} | Payload | Bestellnummer |
| {value} | Payload | Monetärer Wert |
| {currency} | Payload | ISO 4217 (z.B. EUR) |
| {click_id} | Payload | Affiliate Click-ID |
| {client_id} | Payload | TrackHub Client-ID |
| {gclid} | UTM | Google Click-ID |
| {fbclid} | UTM | Meta Click-ID |
| {session_id} | Payload | Session-ID |
| {page_url} | Event | URL bei Event-Auslösung |
Beispiele nach Netzwerk
# Affise https://affise.com/postback?clickid={click_id}&goal=1&sum={value}¤cy={currency} # Everflow https://t.ev-af.com/pv?offer_id=123&transaction_id={order_id}&revenue={value} # HasOffers https://network.go2.com/?nid=1&oid=2&transactionId={order_id}&adv_sub={click_id} # Custom Webhook https://bi.example.com/webhook?event={event_name}&order={order_id}&rev={value}
Event Replay
Event Replay sendet gespeicherte Events nachträglich an eine Integration — z.B. nach dem Einrichten einer neuen Plattform, damit der Algorithmus sofort historische Daten hat.
Ablauf im Dashboard
replay-Tag.Retention nach Plan
| Plan | Retention | Replay-Fenster |
|---|---|---|
| Starter | 6 Monate | 6 Monate |
| Growth | 12 Monate | 12 Monate |
| Pro | 18 Monate | 18 Monate |
| Agency | 24 Monate | 24 Monate |