9 Min. LesezeitTutorials

Link-Analytics-API: Klickstatistiken mit einem API-Schlüssel abrufen

Ein Leitfaden zur Link-Analytics-API: welche Klickberichte ein API-Schlüssel lesen kann, die Abfrageparameter, JSON-Antwortformate, Cursor-Seiten und ein Skript für tägliche Slack-Berichte.

Marius Voß
DevRel · edge infra
Cover zur Link-Analytics-API: eine curl-Anfrage mit einem Workspace-API-Schlüssel gibt Klick-Zeitreihen, Aufschlüsselungen und zusammenfassendes JSON neben einem Pixel-Balkendiagramm zurück

Die Elido Link-Analytics-API ist ein Endpunkt, GET /v1/workspaces/{workspace_id}/analytics/{report} auf https://api.elido.app, der mit einem Workspace-API-Schlüssel authentifiziert wird. Sie stellt 15 Berichte bereit: Klick-Zeitreihen, eine Engagement-Zusammenfassung, Top-Links, einen per Cursor paginierten Strom aktueller Klicks sowie Aufschlüsselungen nach Land, Referrer, Gerät, Browser, Host und Ziel. Datumswerte beziehen sich standardmäßig auf die letzten 30 Tage, link_id schränkt jeden Bericht auf einen Kurzlink ein, und der CSV-Export, Trichter, Kohorten und LTV bleiben im Dashboard.

Das ist die vollständige Antwort, wenn Sie nur die URL benötigt haben. Der Rest dieses Leitfadens enthält genau das, was meiner Meinung nach auf jeder Seite zu einer Klick-Analytics-API von Anfang an stehen sollte: die exakten Parameter, das zurückgegebene JSON, die Stelle, an der der Datumsbereich anders funktioniert als erwartet, und ein 30-zeiliges Skript, das jeden Morgen die Zahlen des Vortags an Slack sendet.

Die meisten Menschen, die Klickdaten abrufen, schließen eine Schleife, die mit Kampagnen-Tagging beginnt. Wenn Ihre Links noch keine einheitlichen UTMs enthalten, beheben Sie das zuerst mit UTM-Tracking von Anfang bis Ende. Saubere Eingaben machen die Statistiken erst nützlich.

Jeder Bericht liegt unter demselben Pfad, und der Berichtsname ist das letzte Segment. Namen mit einem Schrägstrich (links/top, clicks/recent, breakdown/country) werden nicht kodiert. Wenn Sie etwas außerhalb der Zulassungsliste anfordern, erhalten Sie einen 404-Fehler mit unknown analytics report.

BerichtAntwortformatGeeignet für
timeseries{items: [{ts, count}]}Diagramme, Vergleiche zum Vortag
summaryflaches Objekt mit fünf KennzahlenTageszusammenfassungen, KPI-Kacheln
links/top{items: [{link_id, slug, count}]}"Welche Links die Woche geprägt haben"
clicks/recent{items: [click rows], next_cursor}Feeds nahezu in Echtzeit, eigene Speicherung
breakdown/country, /referrer, /device, /browser, /host, /destination{items: [{key, count}]}Kreisdiagramme, Kanalaufteilungen
top-countries, top-referrers, top-destinations{items: [{key, count}]}Dieselben Daten, kürzere Namen
top-regions, top-cities{points: [{country, region or city, count}]}Geo-Drill-downs unterhalb der Länderebene

Beachten Sie die letzte Zeile. Die Berichte zu Regionen und Städten verpacken ihre Zeilen in points, nicht in items, weil jede Zeile statt eines einzelnen Schlüssels ein Land plus eine Region oder Stadt enthält. Ich habe genau einmal erlebt, dass ein generischer Parser daran scheiterte. Einmal reicht.

Dieselbe Oberfläche versorgt die APIs und SDKs, das Analytics-Tool des MCP-Servers und die Operation Get Analytics im n8n-Knoten. Was Sie hier lernen, lässt sich also übertragen.

Authentifizierung mit einem Workspace-API-Schlüssel

API-Schlüssel beginnen mit elido_ und gehören genau einem Workspace. Senden Sie den Schlüssel als Bearer-Token:

curl -s "https://api.elido.app/v1/workspaces/4821/analytics/summary" \
  -H "Authorization: Bearer $ELIDO_API_KEY"

Der Router prüft vor jeder Abfrage zwei Dinge: ob der Schlüssel zum Workspace 4821 gehört und ob er analytics.view besitzt. Jede integrierte Rolle verfügt über diese Berechtigung, auch Viewer. Erstellen Sie für Berichtsaufgaben daher einen Viewer-Schlüssel. Ein Berichtssystem muss keine Links löschen können, und ein Viewer-Schlüssel kann das nicht. Ein Schlüssel ohne Zugriff führt zu einem 403-Fehler.

Auch link_id erweitert den Zugriff nicht. Die Workspace-ID im Pfad wurde bereits geprüft. Eine aus dem Workspace einer anderen Person übernommene Link-ID findet daher null Zeilen und gibt eine leere Liste zurück. Das ist das richtige Fehlerverhalten: unspektakulär, ohne Datenleck.

Abfrageparameter für Klickstatistiken: Datum, Zeitzone, Filter

Sechs Parameter decken fast jeden Aufruf der API für Kurzlink-Statistiken ab:

  • from und to im Format YYYY-MM-DD. Wenn Sie beide weglassen, erhalten Sie die letzten 30 Tage bis jetzt. Wenn Sie nur to setzen, wird from standardmäßig auf 30 Tage davor gesetzt.
  • link_id, um jeden Bericht auf einen Link zu beschränken, und host, um ihn auf eine Redirect-Domain zu beschränken. Das ist praktisch, wenn ein Workspace mehrere gebrandete Domains betreibt.
  • interval für timeseries, entweder hour oder day (Standard). Jeder andere Wert lässt die Anfrage fehlschlagen.
  • limit für Aufschlüsselungen und Top-Listen, 1 bis 200, standardmäßig 50. links/top ist die Ausnahme: Der Bericht gibt 10 Ergebnisse zurück, sofern Sie nicht mehr anfordern.

Hier liegt die Tücke. Beide Daten werden als UTC-Mitternacht gelesen, und das Zeitfenster enthält from, endet aber vor to. Für den gesamten 21. September senden Sie from=2026-09-21&to=2026-09-22. Wenn Sie to=2026-09-21 senden, erhalten Sie überhaupt nichts von diesem Tag.

Die Zeitzone ist der nächste Punkt. Übergeben Sie tz als IANA-Zeitzonenname oder setzen Sie einen X-User-TZ-Header. Dann bildet timeseries seine Stunden- oder Tagesintervalle nach der Ortszeit. Nur die Intervalle verschieben sich. Das Fenster from/to bleibt UTC, daher benötigt ein Berliner "gestern" ein etwas breiteres Fenster, was das folgende Skript erledigt. Ein Tippfehler wie Europe/Berln gibt einen 400-Fehler mit unknown IANA timezone zurück. Das ist besser als ein stillschweigend falsches Diagramm.

curl -s -G "https://api.elido.app/v1/workspaces/4821/analytics/timeseries" \
  -H "Authorization: Bearer $ELIDO_API_KEY" \
  --data-urlencode "from=2026-09-01" \
  --data-urlencode "to=2026-09-22" \
  --data-urlencode "interval=day" \
  --data-urlencode "tz=Europe/Berlin" \
  --data-urlencode "link_id=918273"

Antwortformate, die Sie programmatisch verarbeiten können

Ein Zeitreihenpunkt enthält ts, einen RFC-3339-Zeitstempel für den Beginn des Intervalls, und count. Intervalle mit null Klicks fehlen einfach. Füllen Sie die Lücken vor dem Erstellen eines Diagramms selbst auf, sonst verschwindet ein ruhiger Sonntag von der x-Achse.

{
  "items": [
    { "ts": "2026-09-19T00:00:00Z", "count": 412 },
    { "ts": "2026-09-21T00:00:00Z", "count": 388 }
  ]
}

Aufschlüsselungen geben {"items": [{"key": "DE", "count": 1204}, ...]} zurück, nach Anzahl sortiert. Die Zusammenfassung ist ein flaches Objekt:

{
  "total_clicks": 5310,
  "unique_visitors": 3987,
  "returning_visitors": 611,
  "avg_clicks_per_visitor": 1.33,
  "bounce_rate": 0.85
}

Zwei Definitionen sind wichtig. Eindeutige Besucher werden anhand unterschiedlicher IP-Adressen im Zeitfenster gezählt, daher zählt ein Büro hinter einer gemeinsamen Verbindung einmal. Und bounce_rate ist ein Dezimalanteil, kein Prozentsatz: der Anteil eindeutiger Besucher, die im Zeitfenster nur einmal geklickt haben. Die Kennzahl sagt nichts darüber aus, was auf Ihrer Landingpage passiert ist. Deshalb stimmen diese Zahlen nie mit den GA4-Sitzungen überein (der Beitrag Klicks im Vergleich zu GA4-Sitzungen erklärt den Unterschied). Jede Zahl wird vor der Auslieferung an Sie um Bots bereinigt, mit denselben Zählungen, die Sie in der Elido Link-Analyse sehen.

Aktuelle Klicks mit einem Cursor paginieren

clicks/recent ist der Bericht der Link-Tracking-API, der einzelne Klicks zurückgibt, die neuesten zuerst. Jede Zeile enthält ts, link_id, slug, host, referer, country_code, device, browser, destination, user_agent und ip. Die Seitengröße reicht von 1 bis 500, standardmäßig 100.

Wenn eine Seite vollständig ist, enthält die Antwort einen next_cursor. Übergeben Sie ihn als ?cursor=, um die nächste, ältere Seite abzurufen; null bedeutet, dass Sie das Ende des Zeitfensters erreicht haben.

Cursor-Paginierung für den Bericht clicks/recent der Link-Analytics-API: Die erste Anfrage gibt die neueste Klickseite und next_cursor zurück, der Client übergibt ihn als ?cursor= für die nächste ältere Seite, und ein null in next_cursor beendet die Schleife

Der Cursor verweist auf den Zeitstempel und die Link-ID der letzten Zeile. Zwei Klicks auf denselben Link in derselben Millisekunde können an einer Seitengrenze gleichauf liegen. Im schlimmsten Fall gibt es eine doppelte Zeile, niemals eine übersprungene. Entfernen Sie Duplikate anhand der vollständigen Zeile, wenn Sie sie speichern. Das ist selten, aber zehn Zeilen Code beim Einfügen sind besser, als der Finanzabteilung einen Off-by-one-Fehler erklären zu müssen.

Diese Zeilen enthalten IP-Adressen und User-Agents und sind daher personenbezogene Daten. Wenn Sie sie in ein Data Warehouse kopieren, betreiben Sie es in der EU und legen Sie eine Aufbewahrungsfrist fest. Der Leitfaden zum EU-Datenstandort für Marketingteams erklärt die Gründe. Für die meisten Berichte benötigen Sie überhaupt keine Rohzeilen. Ein tägliches Aggregat ist für alle Beteiligten schonender.

Ein tägliches Klickbericht-Skript für Slack oder ein Tabellenblatt

Das ist die Aufgabe, die die meisten tatsächlich erledigen möchten: jeden Morgen die Klicks des Vortags und die fünf wichtigsten Links in einen Kanal senden. Es verwendet nur die Python-Standardbibliothek und einen eingehenden Slack-Webhook.

import datetime as dt, json, os, urllib.parse, urllib.request
from zoneinfo import ZoneInfo

BASE = "https://api.elido.app/v1/workspaces/{ws}/analytics/{report}"
WS, KEY = os.environ["ELIDO_WORKSPACE_ID"], os.environ["ELIDO_API_KEY"]
TZ = ZoneInfo("Europe/Berlin")

def report(name, **params):
    url = BASE.format(ws=WS, report=name) + "?" + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {KEY}"})
    with urllib.request.urlopen(req, timeout=20) as r:
        return json.load(r)

day = dt.datetime.now(TZ).date() - dt.timedelta(days=1)
# UTC window one day wider on each side, then keep only local hours of `day`
window = {"from": day - dt.timedelta(days=1), "to": day + dt.timedelta(days=2)}
hours = report("timeseries", interval="hour", tz="Europe/Berlin", **window)["items"]
total = sum(p["count"] for p in hours
            if dt.datetime.fromisoformat(p["ts"]).astimezone(TZ).date() == day)

top = report("links/top", limit=5, **{"from": day, "to": day + dt.timedelta(days=1)})
lines = [f"• {l['slug']}: {l['count']}" for l in top["items"]]
text = f"Clicks on {day} (Berlin): {total}\nTop links (UTC day):\n" + "\n".join(lines)

body = json.dumps({"text": text}).encode()
urllib.request.urlopen(urllib.request.Request(
    os.environ["SLACK_WEBHOOK_URL"], data=body,
    headers={"Content-Type": "application/json"}))

Führen Sie es um 07:00 Uhr Ortszeit über cron aus. Der Trick mit den Stunden macht aus der Summe einen echten Berliner Tag statt eines UTC-Tages. links/top kennt kein tz, daher bleibt seine Rangliste auf den UTC-Tag bezogen, und die Nachricht sagt das ausdrücklich.

Möchten Sie stattdessen ein Tabellenblatt? Dieselben beiden Aufrufe funktionieren über Google Apps Script mit UrlFetchApp und einem täglichen Trigger, der jeden Tag eine Zeile anhängt. Das ist auch der günstigste Weg zu einem Looker-Studio-Dashboard.

Wenn Sie montags noch immer Zahlen aus Screenshots abtippen, geben Sie einem Skript einen Viewer-Schlüssel und gewinnen Sie Ihre Morgen zurück.

Was ausschließlich im Dashboard bleibt

Die API-Schlüssel-Oberfläche ist schreibgeschützt und bewusst enger gefasst als das Dashboard. Diese Funktionen sind mit einem Schlüssel nicht erreichbar:

  • Der CSV-Klick-Export (clicks.csv). Die Schaltfläche "CSV herunterladen" im Dashboard ist der Weg für umfangreiche Dateien.
  • Trichter, Kohorten, der LTV-Bericht, Zeit- und Geo-Heatmaps sowie die Ansicht zur Traffic-Qualität.

Wenn Ihnen eine Datei genügt, die nach einem Zeitplan irgendwo abgelegt wird, erledigen die geplanten E-Mail-Berichte des Dashboards das ohne Code. Für einen vollständigen Export beim Offboarding lesen Sie, was Sie aus einem Kurzlink-Konto exportieren können und wie Sie die Vollständigkeit prüfen. Einen kombinierten Aufruf für "alles zu einem Link" gibt es außerdem noch nicht. Für ein Dashboard pro Link ist daher eine Anfrage je Bericht nötig. Der SDK-Schnellstart erklärt, wie Sie diese parallel ausführen und bei Erreichen der Ratenlimits die Anfragen langsamer wiederholen.

Klick-Analytics-API abfragen oder Webhooks für Echtzeit verwenden

Die ehrliche Antwort lautet: Heute werden Klickdaten nur abgerufen. Elido-Webhooks senden signierte und erneut zugestellte Link- und Domain-Ereignisse, aber ein Ereignis click.created pro Klick ist geplant und wird noch nicht gesendet. Alles, was bei Klicks in Echtzeit geschehen soll, bedeutet daher, clicks/recent abzufragen.

Vergleich zwischen dem Abfragen der Link-Analytics-API und Webhooks für Klickdaten: Das Abfragen von clicks/recent mit einem gespeicherten Cursor funktioniert heute, während Webhooks Link- und Domain-Ereignisse abdecken und das Ereignis click.created pro Klick geplant, aber noch nicht gesendet wird

Das ist weniger mühsam, als es klingt. Fragen Sie jede Minute oder alle zwei Minuten ab, beenden Sie den Vorgang, sobald Sie eine bereits gespeicherte Zeile erreichen, und die Last bleibt winzig, weil eine ruhige Minute nur eine kleine Seite bedeutet. Wenn click.created verfügbar ist, wird es dem Handler, der eine Zeile verarbeitet, egal sein, ob sie aus einer Seite oder per Push kam. Die allgemeinen Abwägungen sind in Webhooks im Vergleich zu Abfragen für Klick-Tracking beschrieben. Wenn Sie entscheiden, welche dieser Zahlen überhaupt einen Bericht verdienen, ist Was Sie in Kurzlink-Analysen messen sollten die kürzere Lektüre.

Meine Empfehlung: Beginnen Sie mit der täglichen Zusammenfassung. Fast jedes Team, das mich nach Klicks in Echtzeit fragt, ist mit den Zahlen des Vortags zufrieden, wenn sie vor dem ersten Kaffee eintreffen.

Lesen Sie den Grundlagenartikel → UTM-Kampagnen von Anfang bis Ende verfolgen

Verwandte Beiträge im Blog

Häufig gestellte Fragen

Hat Elido eine Analytics-API für Klicks auf Kurzlinks?

Ja. Ein Workspace-API-Schlüssel kann GET /v1/workspaces/{workspace_id}/analytics/{report} auf api.elido.app aufrufen und 15 Berichte lesen: Zeitreihe, Zusammenfassung, Top-Links, aktuelle Klicks, sechs Aufschlüsselungen und fünf Top-Listen. Der Schlüssel benötigt die Berechtigung analytics.view, über die jede integrierte Rolle, einschließlich Viewer, bereits verfügt.

Wie erhalte ich über die API Klickstatistiken für einen einzelnen Kurzlink?

Fügen Sie link_id an die Abfragezeichenfolge jedes Berichts an. Die numerische Link-ID schränkt Zeitreihe, Zusammenfassung, Aufschlüsselungen und aktuelle Klicks auf diesen einzelnen Link ein. Der Workspace im Pfad bestimmt weiterhin den Zugriff. Eine Link-ID aus einem anderen Workspace gibt daher einfach keine Zeilen zurück, statt Daten offenzulegen.

Kann ich Klickdaten über die API als CSV exportieren?

Nicht mit einem API-Schlüssel. Der CSV-Klick-Export, Trichter, Kohorten und der LTV-Bericht sind nur im Dashboard verfügbar. Für einen automatisierten Datenstrom blättern Sie mit dem Cursor durch den Bericht clicks/recent und schreiben die Zeilen selbst, oder planen Sie einen E-Mail-Bericht im Dashboard, wenn eine Datei in einem Posteingang ausreicht.

Welche Zeitzone verwendet die Link-Analytics-API?

Die Werte from und to werden als UTC-Kalendertage gelesen. Für den Zeitreihenbericht können Sie tz als IANA-Namen wie Europe/Berlin übergeben oder einen X-User-TZ-Header senden. Die Stunden- oder Tagesintervalle werden dann in dieser Zone gebildet. Ein unbekannter Zonenname gibt einen 400-Fehler zurück.

Kann ich für jeden Klick auf einen Kurzlink einen Webhook erhalten?

Noch nicht. Ein Webhook click.created pro Klick ist geplant, wird derzeit aber nicht gesendet. Webhooks decken momentan nur Link- und Domain-Ereignisse ab. Für Klickdaten nahezu in Echtzeit rufen Sie den Bericht clicks/recent in kurzen Abständen ab und behalten den letzten Cursor zwischen den Durchläufen.

Welche API-Schlüsselrolle kann Klickanalysen lesen?

Jede integrierte Rolle. Zum Lesen von Analysen ist analytics.view erforderlich, und die Rolle Viewer verfügt bereits darüber. Daher ist ein Viewer-Schlüssel die sicherste Wahl für ein Berichtsskript. Er kann jeden zulässigen Bericht lesen, aber keine Links erstellen, bearbeiten oder löschen, falls der Schlüssel einmal aus einem Cron-System abhandenkommt.

Elido testen

URL einfügen, kurzer Link in Sekunden

Kein Konto nötig. Link bleibt 30 Tage aktiv. Konto erstellen, um ihn dauerhaft zu behalten.

Kostenlos, keine Anmeldung erforderlich · 2 pro Tag

Elido testen

URL-Shortener mit EU-Hosting: eigene Domains, tiefe Analytik und eine offene API. Kostenloser Tarif - keine Kreditkarte nötig.

Tags
link analytics api
click analytics api
short link stats api
url shortener analytics api
link tracking api
click data export

Weiterlesen