Öffentliche API & API-Keys

Programmatischer Zugriff auf deinen Workspace — Projekte, Sessions, Custom Events und Segmente lesen und Sessions Kundenkennungen zuordnen — abgesichert durch workspace-gebundene API-Keys.

1. Überblick

Mit der MousePlayer-API kannst du Daten aus deinem Workspace in eigene Dashboards, ein Data Warehouse oder interne Tools übernehmen. Bis auf das Zuordnen von Kundenkennungen zu Sessions (Identify, braucht einen Key mit Schreibrecht, siehe Key-Scopes) ist sie rein lesend: Über die API lassen sich keine Daten verändern oder löschen.

  • Basis-URL: https://www.mouseplayer.com/api/v1/
  • Alle Antworten sind im JSON-Format.
  • Jede Anfrage wird über einen API-Key authentifiziert und automatisch auf den zugehörigen Workspace beschränkt — ein Key aus einem Workspace kann niemals Daten eines anderen Workspace sehen, auch nicht versehentlich.
  • Die vollständige Session-Replay-Aufzeichnung (Mausbewegungen, DOM-Snapshots) wird über die API nicht bereitgestellt. Du bekommst Session-Metadaten, Pageviews, Custom Events und Segmente — genug, um Reports und Dashboards zu bauen, ohne den vollen Replay-Payload zu übertragen.

2. Authentifizierung

Erstelle und verwalte deine API-Keys unter API-Keys in deinem Konto-Menü (/api-keys). Nur Workspace-Owner und -Admins können Keys erstellen oder widerrufen.

Halte deinen Key geheim. Er gewährt Lesezugriff auf alles in deinem Workspace. Der vollständige Key wird genau einmal angezeigt, direkt nach der Erstellung — speichere ihn in einem Passwort-Manager oder Secrets-Vault. Falls du ihn verlierst, widerrufe ihn und erstelle einen neuen.

Sende den Key als Bearer-Token im Authorization-Header jeder Anfrage:

# Projekte im Workspace auflisten curl -H "Authorization: Bearer mp_live_..." \ https://www.mouseplayer.com/api/v1/projects

Fehlende, fehlerhafte oder widerrufene Keys erhalten eine 401-Antwort:

{ "error": "Invalid or missing API key. Use: Authorization: Bearer <key>" }

Tarifvoraussetzung

Die REST-API gehört zu den Tarifen Business und Enterprise. Maßgeblich ist der Tarif des Eigentümers des Workspace — eingeladene Teammitglieder erben ihn. Geprüft wird bei jeder Anfrage, nicht nur beim Anlegen eines Keys: wird ein Workspace herabgestuft, liefern bestehende Keys 403.

Geltungsbereich der Keys

Jeder Key trägt seinen Geltungsbereich im eigenen Präfix. Man sieht einem Key damit an, was er darf — in einer .env, in einem Ticket, im Terminal.

PräfixBedeutung
mp_ro_Nur lesen. Liest Projekte, Sessions, Events und Segmente. Verändert nichts.
mp_rw_Lesen und schreiben. Alles davon, zusätzlich das Anhängen von Kundenkennungen über den Identify-Endpunkt.
Der Geltungsbereich wird beim Anlegen gewählt; die Vorgabe ist nur lesen. Ein Nur-Lese-Key auf einem schreibenden Endpunkt bekommt 403 mit einer Meldung, die nennt, was der Key ist und was der Endpunkt braucht. Nachträglich ändern lässt er sich nicht — lege einen neuen Key an und widerrufe den alten.

3. Rate-Limits

Jeder API-Key ist auf 60 Anfragen pro Minute begrenzt (gleitendes Zeitfenster). Wird das überschritten, erhältst du 429-Antworten, bis sich das Fenster wieder leert:

{ "error": "Rate limit exceeded. Max 60 requests per minute." }

Du baust etwas, das ein höheres Limit braucht? Melde dich über Support und beschreib uns deinen Anwendungsfall.

4. Endpunkte

GET/api/v1/projects

Listet alle Projekte (getrackte Properties) in deinem Workspace auf.

{ "data": [ { "channelid": "955a45df5ee842cb", "domain": "deinedomain.de", "status": "active", "total_traffic_bytes": 27304765, "created_at": "2026-07-19 22:06:39", "last_used": "2026-08-05 01:12:55" } ] }

GET/api/v1/projects/{channelid}/sessions

Listet die für ein Projekt aufgezeichneten Besucher-Sessions auf, neueste zuerst. Paginiert.

Query-ParameterBeschreibung
pageSeitenzahl, Standard 1.
per_pageErgebnisse pro Seite, Standard 25, max. 100.
sinceNur Sessions ab diesem Datum (YYYY-MM-DD).
untilNur Sessions bis zu diesem Datum.
{ "data": [ { "session_id": "s_kfmist058_1785795295504", "visitor_id": "v_sv90jdpzo_1785795296042", "custom_user_id": null, "country": "DE", "device_type": "desktop", "is_bot": 0, "start_time": "2026-08-04 00:14:56", "end_time": "2026-08-04 00:16:41", "duration_seconds": 105 } ], "pagination": { "page": 1, "per_page": 25, "total": 142, "total_pages": 6 } }

GET/api/v1/sessions/{session_id}

Metadaten zu einer einzelnen Session, plus ihre Pageviews. Der volle Replay-Payload ist bewusst ausgeschlossen — nutze dafür den Player im Dashboard.

{ "data": { "session_id": "s_kfmist058_1785795295504", "channelid": "955a45df5ee842cb", "visitor_id": "v_sv90jdpzo_1785795296042", "country": "DE", "asn_org": "Deutsche Telekom AG", "referrer": "https://duckduckgo.com/", "device_type": "desktop", "start_time": "2026-08-04 00:14:56", "end_time": "2026-08-04 00:16:41", "duration_seconds": 105, "pageviews": [ { "pageview_id": 1199, "url": "https://deinedomain.de/preise", "page_title": "Preise", "start_time": "2026-08-04 00:14:56", "end_time": "2026-08-04 00:16:41" } ] } }

GET/api/v1/sessions/{session_id}/events

Custom Events, die während einer Session ausgelöst wurden (dieselben Events, die du mit mp('event', ...) sendest), inklusive ihrer Parameter.

{ "data": [ { "event_id": 61, "pageview_id": 1199, "event_name": "add_to_cart", "created_at": "2026-08-04 00:14:59", "params": { "item_id": "SKU_98765", "price": 299.99 } } ] }

GET/api/v1/projects/{channelid}/segments

Listet die für ein Projekt definierten Besuchersegmente auf (sowohl projekt-spezifische als auch workspace-weite Segmente).

{ "data": [ { "segment_id": 4, "name": "Besucher mit hoher Kaufabsicht", "description": "Pageviews > 5", "badge_color": "cyan", "is_global": 0, "created_at": "2026-08-03 00:00:43" } ] }

5. Kundenkennung aus dem eigenen Backend anhängen

Der Browser weiss oft gar nicht, wer da sitzt. In einem B2B-Produkt steht die Zuordnung erst nach der Anmeldung fest — und die passiert im Backend. In einem Shop erst mit der Bestellbestätigung. Genau für diesen Moment ist dieser Endpunkt da.

POST /api/v1/sessions/{session_id}/identify
Authorization: Bearer mp_live_xxxxxxxxxxxx
Content-Type: application/json

{"user_id": "customer-4711"}

// 200 OK
{"data": {"session_id": "s_a1b2c3", "user_id": "customer-4711",
          "changed": true, "previous": null, "webhook_queued": true}}

Die Kennung erscheint danach in der Sitzungsliste, ist dort durchsuchbar, und der Webhook session_identified feuert — so gelangt sie ins CRM.

Zweimal mit derselben Kennung aufzurufen ist unbedenklich. Die Antwort kommt mit "changed": false zurück, und es wird kein Webhook versendet. Eine wiederholte Bestellung erzeugt keinen zweiten Lead.
StatusWann
400Feld fehlt, user_id länger als 128 Zeichen oder Steuerzeichen darin. Wir lehnen ab statt zu kürzen — eine stillschweigend gekürzte Kennung passt zu keinem Datensatz im CRM und sieht trotzdem nach Erfolg aus.
404Die Sitzung gibt es nicht oder sie gehört nicht zu deinem Workspace. Bewusst dieselbe Antwort für beides.
403Der Tarif des Workspace enthält die API nicht.

6. Webhooks: die Signatur prüfen

Webhooks werden je Projekt unter Integrationen eingerichtet; dort steht auch das Signaturgeheimnis. Jede Zustellung traegt diese Kopfzeilen:

KopfzeileBedeutung
X-MousePlayer-EventName des Ereignisses, z.B. session_identified
X-MousePlayer-TimestampUnix-Sekunden — Teil des signierten Textes
X-MousePlayer-Attempt1 beim ersten Versuch, hoeher bei Wiederholungen
X-MousePlayer-Signaturesha256=<hex>

Die Signatur ist ein HMAC-SHA256 über Zeitstempel + "." + Rohdaten, mit dem Signaturgeheimnis des Projekts als Schlüssel.

// PHP
$erwartet = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
if (!hash_equals($erwartet, $signature)) { http_response_code(401); exit; }

// Node
const expected = 'sha256=' + crypto.createHmac('sha256', secret)
                                     .update(timestamp + '.' + rawBody).digest('hex');
Signiere über die Rohdaten, vor jedem JSON-Parsen. Neu serialisiert ändern sich Schlüsselreihenfolge und Leerzeichen, und die Signatur passt nie mehr. Weise außerdem alles zurück, dessen Zeitstempel mehr als ein paar Minuten alt ist — dafür ist er da.

Zustellung und Wiederholung

Eine fehlgeschlagene Zustellung wird nach 1 min, 5 min, 15 min, 1 h und 6 h wiederholt, danach aufgegeben. 4xx-Antworten außer 408 und 429 werden nicht wiederholt — sie sagen "so nicht", nicht "gerade nicht". Antworte schnell mit 2xx und arbeite danach; nach 10 Sekunden läuft die Zustellung ab.

Verfügbare Ereignisse

EreignisFeuert
session_identifiedSobald eine Sitzung erstmals eine Kundenkennung bekommt — aus dem Browser oder über die API
session_endedEinmal, wenn die Sitzung endet
goal_reachedEinmal pro Session, wenn ein Custom Event eines deiner Ziele erfüllt. Nur Ziele vom Typ „Event" — URL-, Dauer-, Seitenaufruf- und Funnel-Ziele werden hier nicht ausgewertet. Enthält goal_id, goal_name, goal_value und currency.
high_value_sessionWenn ein Besucher an einem Tag erstmals die Wertschwelle dieses Projekts überschreitet. Die Schwelle wird aus deiner eigenen Punkteverteilung abgeleitet (90. Perzentil der letzten 90 Tage), nicht fest gesetzt, und es gibt sie erst ab 20 bewerteten Besuchern. Enthält visitor_id, value_score, threshold und die sehenswerteste Sitzung dieses Tages.
funnel_dropoffAm Ende einer Sitzung, die einen deiner Funnel betreten, aber nicht abgeschlossen hat. Nennt den Schritt, an dem sie hängen blieb (dropped_at). Ein Abbruch ist die Abwesenheit eines Ereignisses und deshalb erst nach Sitzungsende bekannt. Sitzungen, die den Funnel nie betreten haben, sind keine Abbrüche und lösen nichts aus.
high_friction_sessionEinmal je Sitzung, sobald ihr Reibungswert die Schwelle erreicht (Vorgabe 60 von 100). Trägt friction_score, die Signale dahinter (reasons) und das Signal, das die Schwelle überschritten hat (trigger).
element_brokenEinmal, wenn eine Element-Markierung mehrere Tage lang in keiner geprüften Seitenansicht etwas gefunden hat — meist nach einem Relaunch. Erneut erst, wenn sie wieder etwas getroffen hat und danach noch einmal bricht. Das Ereignis gehört zu keiner Sitzung: session_id und session_url sind null, stattdessen öffnet link_url die Markierung, und subject_id nennt die Markierung — für jeden Stand dieselbe, damit ein neuer Selektor, der wieder bricht, im offenen Vorfall landet. Trägt rule_id, rule_name, selector, page, checked_page_views, window_days und last_matched. Keine Besucherdaten.
element_recoveredDie Entwarnung zu element_broken: sobald die Markierung tatsächlich wieder ein Element findet — zu wenig Seitenansichten genügen nicht. Nur, wenn element_broken per Webhook hinausging, und ohne eigenen Schalter: wer element_broken abonniert, bekommt sie mit. Dieselbe subject_id, damit PagerDuty den Vorfall auflöst und Opsgenie den Alarm schließt. Trägt zusätzlich matched_page_views und checked_page_views.
anomaly_detectedEinmal am Tag, wenn der Vortag deutlich von den 28 Tagen davor abwich: deutlich weniger oder mehr Sitzungen, eine gefallene Zielquote, mehr Sitzungen mit Reibung oder mit JS-Fehlern. Dieselbe Kennzahl in derselben Richtung meldet sich danach eine Woche lang nicht (einstellbar). Dieses Ereignis gehört zu keiner Sitzung: session_id und session_url sind null, link_url öffnet die Projektübersicht, und subject_id nennt Kennzahl, Richtung und Tag. Enthält metric (sessions, goal_rate, friction_rate, js_error_rate, lcp_p75, inp_p75, cls_p75), direction, day, value, expected, sessions, robust_z, z_score sowie lesbar summary und hint. Keine Besucherdaten. Bei Web Vitals steht measurements statt sessions, und page (leer für die ganze Website) und device (desktop oder mobil) sagen, wo es war; link_url öffnet dann den Reiter Web Vitals.
rage_clickBei einem erkannten Wutklick
error_detectedBei einem Fehler im Frontend
ceSammelabonnement für eigene Custom Events. Es schließt die Ereignisse oben nicht ein — die haben eigene Schalter.

7. Fehler & Statuscodes

StatusBedeutung
200Erfolg.
401Fehlender, fehlerhafter oder widerrufener API-Key.
404Das angefragte Projekt oder die Session existiert nicht oder gehört nicht zu deinem Workspace.
429Rate-Limit überschritten — du sendest mit diesem Key mehr als 60 Anfragen/Minute.
403Der Tarif des Workspace enthält die REST-API nicht. Die Meldung nennt den nötigen und den aktuellen Tarif.

8. Sicherheitshinweise

  • Lese-Keys (mp_ro_) können nichts verändern. Schreib-Keys (mp_rw_) können nur Kundenkennungen zuordnen; kein Key kann Daten löschen oder Replay-Rohdaten exportieren.
  • Jede Anfrage wird automatisch auf den eigenen Workspace des Keys beschränkt — es gibt keine Möglichkeit, eine andere Workspace-ID zu übergeben und fremde Daten zu sehen.
  • Widerrufe einen Key jederzeit unter /api-keys; der Widerruf greift sofort.
  • Behandle deinen API-Key wie ein Passwort. Falls du versehentlich einen in ein öffentliches Repository committest, widerrufe ihn sofort und erstelle einen neuen.

Begrenzte Ereignisseiten (API v1, 14. Oktober 2026)

GET /api/v1/sessions/{session_id}/events liefert standardmaessig bis zu 100 Ereignisse. per_page erlaubt ganze Zahlen von 1 bis 100. Fuer die naechste Seite pagination.next_cursor unveraendert als cursor mitsenden; Sitzung und Workspace beibehalten. Die Reihenfolge ist created_at, danach event_id. Cursor sind signiert und an Sitzung und Workspace gebunden. Eine Gesamtzahl oder numerische Seite wird nicht berechnet.

Das bestehende data-Array und die params-Map bleiben erhalten. pagination.returned nennt die gelieferte Anzahl, pagination.has_more zeigt eine weitere Seite an. next_cursor ist am Ende null. Die Antwort ist auf 524288 Bytes begrenzt; deshalb kann eine Seite weniger als per_page Ereignisse enthalten. Pro Ereignis werden maximal 128 Parameterzeilen ausgegeben; weitere Parameter werden durch params_truncated=true kenntlich gemacht. Zeichenketten behalten die Datenbankgrenze von 255 Zeichen. Abgeschnittene Parameter lassen sich ueber diesen Endpunkt nicht abrufen. Ein kleineres per_page hebt diese Parametergrenze nicht auf.

Ungueltige Seitengroessen, veraenderte Cursor und Cursor einer anderen Sitzung/eines anderen Workspace ergeben 400. Ein einzelnes zu grosses Ereignis ergibt 413. Die bisherigen Zugriffspruefungen liefern weiterhin gegebenenfalls 401, 403, 404 oder 409.

Es gelten weiterhin 60 authentifizierte Anfragen pro API-Schluessel und Minute. Ueberschreitung: 429 mit Retry-After: 60. Ist Redis oder die Limit-Pruefung nicht verfuegbar, gilt 503 mit Retry-After: 5; die API wird nicht unbegrenzt freigegeben. Retry-After beachten und mit Zufallsversatz wiederholen; keine enge Wiederholungsschleife. Datenbankfehler beim Ereignisabruf ergeben ebenfalls 503. Cursor frieren keinen Datenstand ein: parallel eingefuegte Ereignisse mit aelteren Zeitstempeln koennen einen neuen Durchlauf erfordern.

GET /api/v1/sessions/s_example/events?per_page=25
GET /api/v1/sessions/s_example/events?per_page=25&cursor=SIGNED_CURSOR

/api/v1/native ist ein nur in Dev verfuegbarer Backend-Steuerweg fuer die Native-SDK-Vorschau. In Produktion bleibt er deaktiviert. Backend-Bearer-Schluessel brauchen read fuer list/replay und write fuer register/grant/delete/disable. Zusaetzlich gelten die Verfuegbarkeitspruefungen der Native-Vorschau. Dauerhafte Workspace-API-Schluessel niemals in eine mobile App einbauen.