Openbare API & API-sleutels
Programmatische toegang tot uw werkruimte — lees projecten, sessies, aangepaste gebeurtenissen en segmenten en koppel klant-ID’s aan sessies — beveiligd met API-sleutels die tot de werkruimte zijn beperkt.
1. Overzicht
Met de MousePlayer-API haalt u gegevens uit uw werkruimte op voor uw eigen dashboards, datawarehouse of interne tools. Afgezien van het koppelen van klant-ID’s aan sessies (identify, waarvoor een sleutel met schrijfrechten nodig is; zie Sleutelbereik) is deze alleen-lezen: er kunnen geen gegevens via de API worden gewijzigd of verwijderd.
- Basis-URL:
https://www.mouseplayer.com/api/v1/ - Alle antwoorden zijn JSON.
- Elk verzoek wordt met een API-sleutel geauthenticeerd en automatisch beperkt tot de werkruimte waartoe die sleutel behoort — een sleutel uit de ene werkruimte kan nooit gegevens uit een andere zien, ook niet per ongeluk.
- De volledige sessie-opname (muisbewegingen, DOM-momentopnamen) is niet beschikbaar via de API. U krijgt sessiemetadata, paginaweergaven, aangepaste gebeurtenissen en segmenten — genoeg om rapporten en dashboards te bouwen zonder de ruwe opnamegegevens rond te sturen.
2. Authenticatie
Maak en beheer uw API-sleutels onder API-sleutels in uw accountmenu (/api-keys). Alleen eigenaren en beheerders van de werkruimte kunnen sleutels maken of intrekken.
Houd uw sleutel geheim. Deze geeft leestoegang tot alles in uw werkruimte. De volledige sleutel wordt precies één keer getoond, direct nadat u deze hebt gemaakt — bewaar deze in een wachtwoordmanager of geheimenkluis. Als u de sleutel kwijtraakt, trekt u deze in en maakt u een nieuwe.
Stuur de sleutel als Bearer-token mee in de Authorization header van elk verzoek:
Ontbrekende, onjuist gevormde of ingetrokken sleutels krijgen een 401 antwoord:
Vereist abonnement
De REST-API is beschikbaar bij Business en Enterprise . Het abonnement van de eigenaar van de werkruimte is bepalend, dus uitgenodigde teamleden erven dit. De controle vindt plaats bij elk verzoek, niet alleen bij het maken van een sleutel — als een werkruimte naar een lager abonnement gaat, werken bestaande sleutels niet meer en retourneren ze 403.
Sleutelbereik
Elke sleutel vermeldt het bereik in zijn eigen prefix. U ziet dus meteen wat een sleutel kan — in een .env, een ticket of een terminal.
| Prefix | Betekenis |
|---|---|
mp_ro_ | Alleen lezen. Leest projecten, sessies, gebeurtenissen en segmenten. Kan niets wijzigen. |
mp_rw_ | Lezen en schrijven. Alles hierboven, plus het koppelen van klant-ID's via het identify-endpoint. |
403 met een melding die aangeeft wat de sleutel kan en wat het endpoint vereist. Het bereik kan achteraf niet worden gewijzigd — maak een nieuwe sleutel en trek de oude in.3. Verzoeklimieten
Elke API-sleutel is beperkt tot 60 verzoeken per minuut, bijgehouden in een voortschrijdend tijdvenster. Zodra u dit overschrijdt, krijgen verzoeken een 429 antwoord totdat er weer ruimte in het tijdvenster is:
Bouwt u iets dat een hogere limiet nodig heeft? Neem contact op via Support en vertel ons over uw toepassing.
4. Endpoints
GET/api/v1/projects
Toont alle projecten (gevolgde property’s) in uw werkruimte.
GET/api/v1/projects/{channelid}/sessions
Toont opgenomen bezoekerssessies voor een project, de nieuwste eerst. Met paginering.
| Queryparameter | Beschrijving |
|---|---|
page | Paginanummer, standaard 1. |
per_page | Resultaten per pagina, standaard 25, maximaal 100. |
since | Alleen sessies die op of na deze datum beginnen (YYYY-MM-DD). |
until | Alleen sessies die op of vóór deze datum beginnen. |
GET/api/v1/sessions/{session_id}
Metadata van één sessie, inclusief de paginaweergaven. De volledige opnamegegevens zijn bewust uitgesloten — gebruik daarvoor de speler in het dashboard.
GET/api/v1/sessions/{session_id}/events
Aangepaste gebeurtenissen die tijdens een sessie zijn geactiveerd (dezelfde die u verstuurt met mp('event', ...)), inclusief hun parameters.
GET/api/v1/projects/{channelid}/segments
Toont de bezoekerssegmenten die voor een project zijn gedefinieerd, zowel projectspecifieke als werkruimtebrede segmenten.
5. Een klant-ID koppelen vanuit uw backend
De browser weet vaak niet wie erachter zit. Bij een B2B-product wordt de identiteit na het inloggen vastgesteld — in uw backend. Bij een winkel gebeurt dat bij de bestelbevestiging. Dit endpoint is precies voor dat moment.
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}}De ID verschijnt vervolgens in de sessielijst, is daar doorzoekbaar en de webhook session_identified wordt geactiveerd — zo bereikt de informatie uw CRM.
"changed": false en er wordt geen webhook verstuurd. Een herhaalde bestelling maakt geen tweede lead aan.| Status | Wanneer |
|---|---|
400 | Ontbrekend veld, user_id langer dan 128 tekens of met controletekens. We weigeren in plaats van af te kappen — een stilzwijgend verkorte ID past nergens in uw CRM bij en lijkt toch op succes. |
404 | De sessie bestaat niet of hoort niet bij uw werkruimte. Bewust hetzelfde antwoord voor beide gevallen. |
403 | Het abonnement van de werkruimte bevat de API niet. |
6. Webhooks: de handtekening controleren
Webhooks worden per project ingesteld onder Integraties, waar u ook het ondertekeningsgeheim vindt. Elke aflevering bevat deze headers:
| Header | Betekenis |
|---|---|
X-MousePlayer-Event | Gebeurtenisnaam, bijvoorbeeld session_identified |
X-MousePlayer-Timestamp | Unix-seconden — onderdeel van de ondertekende tekst |
X-MousePlayer-Attempt | 1 bij de eerste poging, hoger bij nieuwe pogingen |
X-MousePlayer-Signature | sha256=<hex> |
De handtekening is een HMAC-SHA256 over timestamp + "." + raw body, met het ondertekeningsgeheim van uw project als sleutel.
// 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');
Aflevering en nieuwe pogingen
Een mislukte aflevering wordt opnieuw geprobeerd na 1 min, 5 min, 15 min, 1 uur en 6 uur, daarna wordt gestopt. Antwoorden met status 4xx anders dan 408 en 429 worden niet opnieuw geprobeerd — ze betekenen "niet op deze manier", in plaats van "niet op dit moment". Antwoord snel met 2xx en voer het werk daarna uit; de aflevering verloopt na 10 seconden.
Beschikbare gebeurtenissen
| Gebeurtenis | Wordt geactiveerd |
|---|---|
session_identified | Wanneer een sessie voor het eerst een klant-ID krijgt — vanuit de browser of via de API |
session_ended | Eenmalig, wanneer de sessie sluit |
goal_reached | Eenmaal per sessie, wanneer een aangepaste gebeurtenis een van uw doelen vervult. Alleen doelen van het type “event” — doelen voor URL, duur, paginaweergaven en trechters worden niet geëvalueerd. Bevat goal_id, goal_name, goal_value en currency. |
high_value_session | Wanneer een bezoeker op een bepaalde dag voor het eerst de waardedrempel van dit project overschrijdt. De drempel is afgeleid van uw eigen scoreverdeling (90e percentiel van de laatste 90 dagen), geen vast getal, en bestaat pas nadat minstens 20 bezoekers een score hebben gekregen. Bevat visitor_id, value_score, threshold en de sessie van die dag die het meest de moeite waard is om te bekijken. |
funnel_dropoff | Aan het einde van een sessie die een van uw trechters binnenging, maar niet voltooide. Vermeldt de stap waar de sessie stopte (dropped_at). Uitval is het ontbreken van een gebeurtenis en kan daarom pas worden vastgesteld als de sessie voorbij is. Sessies die de trechter nooit binnengingen, tellen niet als uitval en activeren niets. |
high_friction_session | Eenmaal per sessie, wanneer de frictiescore voor het eerst de drempel bereikt (standaard 60 van 100). Bevat friction_score, de achterliggende signalen (reasons) en het signaal dat de drempel overschreed (trigger). |
element_broken | Eenmalig, wanneer een gevolgd element meerdere dagen in geen enkele gecontroleerde paginaweergave is gevonden — meestal na een herlancering. Wordt pas opnieuw geactiveerd nadat de markering weer een overeenkomst heeft gevonden en vervolgens opnieuw is uitgevallen. Deze gebeurtenis hoort bij geen enkele sessie: session_id en session_url zijn null, link_url opent in plaats daarvan de markering en subject_id identificeert de markering — dezelfde waarde voor elke versie, zodat een nieuwe selector die opnieuw uitvalt bij het open incident wordt gevoegd. Bevat rule_id, rule_name, selector, page, checked_page_views, window_days en last_matched. Geen bezoekersgegevens. |
element_recovered | Het herstelbericht voor element_broken: zodra de markering daadwerkelijk weer een element vindt — te weinig paginaweergaven zijn niet voldoende. Wordt alleen verstuurd als element_broken via een webhook is verstuurd en heeft geen eigen schakelaar: een abonnement op element_broken omvat ook deze gebeurtenis. Dezelfde subject_id, zodat PagerDuty het incident oplost en Opsgenie de melding sluit. Bevat daarnaast matched_page_views en checked_page_views . |
anomaly_detected | Eenmaal per dag, wanneer gisteren duidelijk afweek van de 28 voorafgaande dagen: veel minder of veel meer sessies, een gedaald doelpercentage, meer sessies met frictie of JS-fouten. Dezelfde meetwaarde en richting blijven een week stil (instelbaar). Deze gebeurtenis hoort bij geen enkele sessie: session_id en session_url zijn null, link_url opent het projectoverzicht en subject_id identificeert meetwaarde, richting en dag. Bevat metric (sessions, goal_rate, friction_rate, js_error_rate, lcp_p75, inp_p75, cls_p75), direction, day, value, expected, sessions, robust_z, z_score en leesbare waarden voor summary en hint. Geen bezoekersgegevens. Voor Web Vitals vervangt measurements de waarde van sessions, en page (leeg voor de hele site) en device (desktop of mobil) geven aan waar het gebeurde; link_url opent dan het tabblad Web Vitals. |
rage_click | Bij een gedetecteerde woedeklik |
error_detected | Bij een uitzondering in de frontend |
ce | Gezamenlijk abonnement op uw eigen aangepaste gebeurtenissen. Het omvat niet de bovenstaande gebeurtenissen — die hebben hun eigen schakelaars. |
7. Fouten & statuscodes
| Status | Betekenis |
|---|---|
200 | Geslaagd. |
401 | Ontbrekende, onjuist gevormde of ingetrokken API-sleutel. |
404 | Het gevraagde project of de sessie bestaat niet of hoort niet bij uw werkruimte. |
429 | Verzoeklimiet overschreden — u verstuurt meer dan 60 verzoeken per minuut met deze sleutel. |
403 | Het abonnement van de werkruimte bevat de REST-API niet. De melding noemt zowel het vereiste als het huidige abonnement. |
8. Beveiligingsopmerkingen
- Alleen-lezen sleutels (mp_ro_) kunnen niets wijzigen. Schrijfsleutels (mp_rw_) kunnen alleen klant-ID’s koppelen; geen enkele sleutel kan gegevens verwijderen of ruwe opnamegegevens exporteren.
- Elk verzoek wordt automatisch beperkt tot de eigen werkruimte van de sleutel — u kunt geen andere werkruimte-ID meegeven om gegevens van iemand anders te zien.
- Trek een sleutel op elk moment in via /api-keys; dit gaat onmiddellijk in.
- Behandel uw API-sleutel als een wachtwoord. Als u er per ongeluk een in een openbare repository commit, trekt u deze direct in en maakt u een nieuwe.
Begrensde gebeurtenispagina’s (API v1, 14 oktober 2026)
GET /api/v1/sessions/{session_id}/events retourneert standaard maximaal 100 gebeurtenissen. Stel per_page in op een geheel getal van 1 tot 100. Volg pagination.next_cursor door cursor ongewijzigd mee te sturen bij het volgende verzoek; behoud dezelfde sessie en werkruimte. Gebeurtenissen worden gesorteerd op created_at en event_id. Cursors zijn ondertekend en aan die sessie en werkruimte gebonden. Er wordt geen totaalaantal of numeriek paginanummer teruggegeven.
Het bestaande data-array en de params-map blijven beschikbaar. pagination.returned is het werkelijk geretourneerde aantal; pagination.has_more geeft aan dat er nog een pagina is. next_cursor is null wanneer alles is opgehaald. Een antwoord is beperkt tot 524288 bytes, dus een pagina kan minder gebeurtenissen bevatten dan per_page. Per gebeurtenis worden maximaal 128 parameterrijen teruggegeven; params_truncated is true als er meer zijn. Voor afzonderlijke tekstparameters blijft de databaselimiet van 255 tekens gelden. Afgekapte parameters zijn niet beschikbaar via dit endpoint. Een lagere per_page verhoogt de parameterlimiet niet.
Ongeldige paginagroottes, gewijzigde cursors en cursors voor een andere sessie of werkruimte retourneren 400. Te grote gegevens van een afzonderlijke gebeurtenis retourneren 413. Bestaande toegangscontroles blijven waar van toepassing 401, 403, 404 of 409 retourneren.
De limiet blijft 60 geauthenticeerde verzoeken per API-sleutel per minuut. Bij uitputting volgt 429 met Retry-After: 60. Als Redis of de limietbewaking niet beschikbaar is, retourneren verzoeken 503 met Retry-After: 5; verzoeken worden nooit zonder limiet toegelaten. Respecteer Retry-After en voeg een willekeurige wachttijd toe; probeer niet opnieuw in een lus zonder pauze. Storingen in de gebeurtenisdatabase retourneren ook 503. Cursors bevriezen geen momentopname: gelijktijdige invoegingen met oudere tijdstempels kunnen een nieuwe scan vereisen.
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 is een backendbesturingsroute die alleen in Dev beschikbaar is voor de preview van de native SDK. In productie blijft deze uitgeschakeld. Bearer-sleutels voor de backend hebben leesbereik nodig voor list/replay en schrijfbereik voor register/grant/delete/disable. Er gelden aanvullende beschikbaarheidscontroles voor de native preview. Sluit nooit permanente API-sleutels van een werkruimte in een mobiele app in.