# TrackAny.Click — Dokumentation

Zuletzt geprüft: 9. September 2026

[HTML](https://docs.trackany.click/de)

Klare Zuordnung vom ersten Kontakt bis zum qualifizierten Lead.

## Getting Started

1. Erstelle und bestätige genau einen Cloud-Account. 2. Wähle oder erstelle die Organisation, der die Integration gehört. 3. Lege ein Projekt für die Website, den Shop oder die Marke an, deren Daten zusammenbleiben sollen. 4. Öffne den Produkt-Workspace und prüfe die Freischaltung, bevor du Zugangsdaten kopierst oder Produktionsverkehr sendest.

Damit ist die Account-Einrichtung abgeschlossen. Alle folgenden Abschnitte sind Implementierungsanleitungen. Zugangsdaten sind immer projektgebunden; Server-Secrets gehören niemals in Browsercode, öffentliche Repositories oder clientseitige Umgebungsvariablen.

## Vor der Integration

Die TrackAny.Click-Erfassung wird je Kundenprojekt aktiviert. Sende erst Produktivdaten, wenn der Projekt-Workspace einen öffentlichen Key, das Installationssnippet und eine aktive Collector-URL anzeigt. Vorbereitete URLs oder ein Script aus einem anderen Projekt aktivieren keine Erfassung.

## Öffentlicher und geheimer Projektschlüssel

Der öffentliche pub_tac_-Key gehört in den Browser und ist auf die aktiven Domains des Projekts begrenzt. Der sec_tac_-Key wird bei der Projekterstellung einmal angezeigt, gehört ausschließlich in einen serverseitigen Secret Manager und authentifiziert Server-Events sowie Identify-Aufrufe.

Wurde der Secret-Key nicht gespeichert, darfst du weder den Public Key als Ersatz nutzen noch einen Server-Key im Browser veröffentlichen. Fordere vor der Serverintegration einen kontrollierten Ersatz an; eine Self-Service-Rotation des Secret-Keys ist derzeit nicht verfügbar.

## Browser-Tracker installieren

Kopiere das projektspezifische Snippet unter TrackAny.Click → Installation. Das Beispiel lädt den Tracker von connect.trackany.click, sendet an denselben Collector und startet mit verweigertem Consent. Verwende die im Projekt angezeigte Script-URL, den Endpunkt und den öffentlichen Schlüssel; bei einer bestätigten eigenen Tracking-Domain gelten deren Adressen.

Der Tracker übernimmt nach Analytics-Consent standardmäßig auch künftige Meta-Pixel- und Google-dataLayer-/gtag-Events der Seite; die vorhandenen Tags laufen weiter. data-provider-events=false schaltet diese Übernahme ab, data-google-layer wählt einen eigenen Data-Layer-Namen. data-spa=true ergänzt den ersten und weitere History-API-Pageviews. Events vor dem Laden des Trackers lassen sich nicht nachträglich erfassen. data-track-outbound=true erfasst Klicks auf externe HTTP(S)-Links.

```html
<script>
  window.trackany = window.trackany || function () {
    (window.trackany.q = window.trackany.q || []).push(arguments);
  };
</script>
<script async
  src="https://connect.trackany.click/v1/t.js"
  data-project="PUBLIC_PROJECT_KEY"
  data-endpoint="https://connect.trackany.click"
  data-consent="denied"
  data-spa="true"
  data-web-vitals="true"
  data-provider-events="true"
  data-track-outbound="true">
</script>
```

## Consent korrekt anbinden

Vor Consent erzeugt der Tracker keine Kennungen, greift nicht auf persistenten Speicher zu und sendet keine Events. Rufe consent=granted erst auf, nachdem der Consent Manager der Website Analytics freigegeben hat. Rufe bei Widerruf consent=denied auf; das löscht den lokalen TrackAny.Click-Zustand und stoppt neue Events, ist aber kein serverseitiger Löschantrag.

Vermeide personenbezogene Daten in URLs, UTM-Werten und eigenen Properties. Querystrings und Fragmente werden aus Seiten-URLs entfernt, Referrer reduziert und das SDK verwendet kein Fingerprinting.

## Pageviews, Leads und Conversions erfassen

Nutze kleingeschriebene snake_case-Eventnamen. Markiere echte Ziele mit conversion=true und übergib Wert und dreistelligen Währungscode immer gemeinsam. Browser-Aufrufe tragen den consentgebundenen Besucher-, Session- und Attributionskontext automatisch.

Nutze ein Event für genau einen Geschäftsvorgang. Melde denselben Kauf nicht im Browser und erneut auf dem Server, wenn beide Events nicht bewusst unterschiedliche Fakten darstellen.

```javascript
window.trackany("consent", "granted");
window.trackany("pageview");
window.trackany(
  "event",
  "form_submit",
  { form: "demo_request" },
  { conversion: true }
);
```

## Browser-Events mit Beispielen

Bei data-spa=true sendet der Tracker für automatische SPA-Aufrufe page_view. Ein manueller pageview-Aufruf sendet denselben Eventtyp. Mit data-track-outbound=true erzeugen Klicks auf externe HTTP(S)-Links outbound_click; übertragen wird nur destination_origin. Sessions werden automatisch angelegt, aber session_start wird nicht automatisch gesendet. Der consent-Befehl ändert die lokale Tracking-Erlaubnis und ist kein Event.

Die übrigen Namen sind empfohlene Konventionen, keine abschließende Event-Liste: view_product, add_to_cart, begin_checkout, form_started und form_submit. Jeder window.trackany-Aufruf sendet nach Analytics-Consent ein Event. Nutze Properties für unkritische IDs oder Mengen und die Event-Option conversion für echte Ziele.

```javascript
window.trackany("pageview");

window.trackany("event", "view_product", { product_id: "sku_123" });
window.trackany("event", "add_to_cart", { product_id: "sku_123", quantity: 1 });
window.trackany("event", "begin_checkout", { cart_id: "cart_123" });
window.trackany("event", "form_started", { form_id: "demo" });
window.trackany("event", "form_submit", { form_id: "demo" }, { conversion: true });
window.trackany("event", "session_start");
```

## Server-Events mit Beispielen

Sende bestätigte Geschäftsvorgänge vom Backend mit einem Secret-Key: lead_created, lead_qualified, appointment_created, appointment_completed, order_created, purchase, refund, subscription_started, subscription_cancelled, deal_won und deal_lost. Dies sind Namensvorschläge; die API akzeptiert auch eigene kleingeschriebene snake_case-Namen mit bis zu 100 Zeichen.

Das Node.js-Beispiel erzeugt mit dem Paket ulid eine gültige eventId. Installiere dieses Paket im Serverprojekt. Bewahre eventId und den exakten JSON-Body für Wiederholungen auf. Ein Geldbetrag muss mindestens null sein und braucht einen dreistelligen Währungscode; erfasse eine Erstattung als eigenes Event statt als negativen Kauf. Markiere nur echte Ziele als Conversions.

```javascript
import { ulid } from "ulid";

const endpoint = "https://connect.trackany.click/v1/events";
const secretKey = process.env.TRACKANY_SECRET_KEY;

async function sendEvent(event, properties = {}, fields = {}) {
  const body = {
    eventId: `evt_${ulid()}`,
    event,
    timestamp: new Date().toISOString(),
    properties,
    ...fields,
  };
  const response = await fetch(endpoint, {
    method: "POST",
    headers: {
      authorization: `Bearer ${secretKey}`,
      "content-type": "application/json",
    },
    body: JSON.stringify(body),
  });
  if (!response.ok) throw new Error(`TrackAny event rejected: ${response.status}`);
  return response.json();
}

await sendEvent("lead_created", { lead_id: "lead_123" }, { contactId: "crm_123" });
await sendEvent("lead_qualified", { lead_id: "lead_123" }, { contactId: "crm_123" });
await sendEvent("appointment_created", { appointment_id: "appt_123" });
await sendEvent("appointment_completed", { appointment_id: "appt_123" });
await sendEvent("order_created", { order_id: "ord_123" });
await sendEvent("purchase", { order_id: "ord_123" },
  { value: 49.90, currency: "USD", conversion: true });
await sendEvent("refund", { order_id: "ord_123" },
  { value: 49.90, currency: "USD" });
await sendEvent("subscription_started", { subscription_id: "sub_123" });
await sendEvent("subscription_cancelled", { subscription_id: "sub_123" });
await sendEvent("deal_won", { deal_id: "deal_123" }, { conversion: true });
await sendEvent("deal_lost", { deal_id: "deal_123" });
```

## Vertrauenswürdiges Server-Event senden

Sende JSON per POST an /v1/events und nutze den Secret-Key als Bearer-Token. Server-Events können contactId oder externalId enthalten und werden getrennt von Browser-Events ausgewiesen. Halte eventId beim Retry stabil: identischer Inhalt wird dedupliziert, geänderter Inhalt unter derselben ID erzeugt HTTP 409 event_id_conflict.

### cURL

```bash
curl --request POST "https://connect.trackany.click/v1/events" \
  --header "Authorization: Bearer $TRACKANY_SECRET_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "eventId": "evt_01JZ8J2K9M7P4Q6R8S1T3V5W7X",
  "event": "purchase",
  "timestamp": "2026-09-08T17:00:00Z",
  "contactId": "crm_123",
  "value": 49.9,
  "currency": "USD",
  "conversion": true,
  "properties": {
    "plan": "pro"
  }
}'
```

### Node.js

```javascript
const response = await fetch("https://connect.trackany.click/v1/events", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRACKANY_SECRET_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "eventId": "evt_01JZ8J2K9M7P4Q6R8S1T3V5W7X",
    "event": "purchase",
    "timestamp": "2026-09-08T17:00:00Z",
    "contactId": "crm_123",
    "value": 49.9,
    "currency": "USD",
    "conversion": true,
    "properties": {
      "plan": "pro"
    }
  }),
});

if (!response.ok) throw new Error(`Request failed: ${response.status}`);
console.log(await response.json());
```

### Python

```python
import os
import requests

payload = {
    "eventId": "evt_01JZ8J2K9M7P4Q6R8S1T3V5W7X",
    "event": "purchase",
    "timestamp": "2026-09-08T17:00:00Z",
    "contactId": "crm_123",
    "value": 49.9,
    "currency": "USD",
    "conversion": True,
    "properties": {
        "plan": "pro",
    },
}

response = requests.post(
    "https://connect.trackany.click/v1/events",
    headers={
        "Authorization": f"Bearer {os.environ['TRACKANY_SECRET_KEY']}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=10,
)
response.raise_for_status()
print(response.json())
```

### PHP

```php
<?php

$payload = [
    'eventId' => 'evt_01JZ8J2K9M7P4Q6R8S1T3V5W7X',
    'event' => 'purchase',
    'timestamp' => '2026-09-08T17:00:00Z',
    'contactId' => 'crm_123',
    'value' => 49.9,
    'currency' => 'USD',
    'conversion' => true,
    'properties' => [
        'plan' => 'pro',
    ],
];
$curl = curl_init('https://connect.trackany.click/v1/events');

curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('TRACKANY_SECRET_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
    CURLOPT_TIMEOUT => 10,
]);

$response = curl_exec($curl);
if ($response === false) {
    throw new RuntimeException(curl_error($curl));
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
if ($status >= 400) {
    throw new RuntimeException("Request failed: $status");
}
echo $response;
```

## Besucher mit dem eigenen System verbinden

Lies nach Formularsendung oder Login die consentgebundene visitorId über window.trackany.getContext() und sende sie vom Backend an POST /v1/identify zusammen mit contactId, externalId oder beiden. Der Endpunkt verlangt den Secret-Key; öffentliche Browser-Keys werden abgewiesen.

### cURL

```bash
curl --request POST "https://connect.trackany.click/v1/identify" \
  --header "Authorization: Bearer $TRACKANY_SECRET_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "visitorId": "vis_01JZ8J2K9M7P4Q6R8S1T3V5W7X",
  "contactId": "crm_123"
}'
```

### Node.js

```javascript
const response = await fetch("https://connect.trackany.click/v1/identify", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TRACKANY_SECRET_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "visitorId": "vis_01JZ8J2K9M7P4Q6R8S1T3V5W7X",
    "contactId": "crm_123"
  }),
});

if (!response.ok) throw new Error(`Request failed: ${response.status}`);
console.log(await response.json());
```

### Python

```python
import os
import requests

payload = {
    "visitorId": "vis_01JZ8J2K9M7P4Q6R8S1T3V5W7X",
    "contactId": "crm_123",
}

response = requests.post(
    "https://connect.trackany.click/v1/identify",
    headers={
        "Authorization": f"Bearer {os.environ['TRACKANY_SECRET_KEY']}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=10,
)
response.raise_for_status()
print(response.json())
```

### PHP

```php
<?php

$payload = [
    'visitorId' => 'vis_01JZ8J2K9M7P4Q6R8S1T3V5W7X',
    'contactId' => 'crm_123',
];
$curl = curl_init('https://connect.trackany.click/v1/identify');

curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('TRACKANY_SECRET_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
    CURLOPT_TIMEOUT => 10,
]);

$response = curl_exec($curl);
if ($response === false) {
    throw new RuntimeException(curl_error($curl));
}
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
if ($status >= 400) {
    throw new RuntimeException("Request failed: $status");
}
echo $response;
```

## Eventmodell festlegen

Definiere vor der Implementierung ein kleines Vokabular, etwa page_view → form_submitted → qualified_lead → purchase. Halte Akquisitionsaktivitäten und spätere Kundenergebnisse als getrennte Events, damit Berichte die beobachtete Reihenfolge und Vertrauensquelle zeigen.

## Kampagnenattribution erhalten

Nutze konsistente utm_source, utm_medium und utm_campaign sowie stabile Provider-IDs wie utm_id, utm_adgroup_id und utm_ad_id. TrackAny.Click hält First Touch, aktuellen Session Touch und Last Non-Direct Touch getrennt; Kampagnennamen allein sind keine zuverlässigen Join-Schlüssel.

## Batching und Ergebnisse

Sende 1–100 Events an /v1/events/batch, wenn ein Serverprozess mehrere unabhängige Fakten besitzt. Der Dienst validiert zunächst den vollständigen Batch und kann HTTP 207 mit Ergebnissen je Event liefern, wenn nur ein Teil geschrieben wurde. Bewahre Event-ID und Payload für sichere Retries auf.

## Journeys lesen und Fehler behandeln

HTTP 202 bedeutet, dass das Event angenommen wurde. Behandle 400 als Vertrags- oder Zeitfehler, 401 als ungültigen Projektschlüssel, 402 als fehlendes Kontingent oder Guthaben, 403 als Origin-Sperre, 409 als geänderte Wiederverwendung einer Event-ID und 429 als Rate Limit. Wiederhole vorübergehende Fehler mit unveränderter Event-ID und Payload.

Journey- und Funnel-Berichte sind begrenzte Ansichten, kein Identity Graph. Sie zeigen Abdeckung und Kürzungen, halten Währungen und Vertrauensquellen getrennt und behaupten keine geräteübergreifende Gewissheit.

## Produkte

- [TrackMailer](https://docs.markengroup.cloud/de/trackmailer.md): Kunden zuverlässig erreichen und jede Zustellung klar im Blick behalten.
- [TrackAny.Click](https://docs.trackany.click/de.md): In Kampagnen und Customer Journeys mit echtem Wert investieren.
- [TrackPost](https://docs.markengroup.cloud/de/trackpost.md): Relevante Inhalte schnell erstellen und jede Entscheidung klar halten.
- [LeadScoutEngine](https://docs.markengroup.cloud/de/leadscoutengine.md): Finde und priorisiere Unternehmen nach eigenen Kriterien und schalte nur benötigte Intelligence frei.
