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:

# List projects in your workspace curl -H "Authorization: Bearer mp_live_..." \ https://www.mouseplayer.com/api/v1/projects

Ontbrekende, onjuist gevormde of ingetrokken sleutels krijgen een 401 antwoord:

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

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.

PrefixBetekenis
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.
Kies het bereik wanneer u de sleutel maakt; standaard is dit alleen lezen. Een alleen-lezen sleutel op een schrijfendpoint retourneert 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:

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

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.

{ "data": [ { "channelid": "955a45df5ee842cb", "domain": "yourdomain.com", "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

Toont opgenomen bezoekerssessies voor een project, de nieuwste eerst. Met paginering.

QueryparameterBeschrijving
pagePaginanummer, standaard 1.
per_pageResultaten per pagina, standaard 25, maximaal 100.
sinceAlleen sessies die op of na deze datum beginnen (YYYY-MM-DD).
untilAlleen sessies die op of vóór deze datum beginnen.
{ "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}

Metadata van één sessie, inclusief de paginaweergaven. De volledige opnamegegevens zijn bewust uitgesloten — gebruik daarvoor de speler in het 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://yourdomain.com/pricing", "page_title": "Pricing", "start_time": "2026-08-04 00:14:56", "end_time": "2026-08-04 00:16:41" } ] } }

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.

{ "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

Toont de bezoekerssegmenten die voor een project zijn gedefinieerd, zowel projectspecifieke als werkruimtebrede segmenten.

{ "data": [ { "segment_id": 4, "name": "High Intent Visitors", "description": "Pageviews > 5", "badge_color": "cyan", "is_global": 0, "created_at": "2026-08-03 00:00:43" } ] }

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.

Twee keer aanroepen met dezelfde ID is veilig. Het antwoord komt terug met "changed": false en er wordt geen webhook verstuurd. Een herhaalde bestelling maakt geen tweede lead aan.
StatusWanneer
400Ontbrekend 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.
404De sessie bestaat niet of hoort niet bij uw werkruimte. Bewust hetzelfde antwoord voor beide gevallen.
403Het 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:

HeaderBetekenis
X-MousePlayer-EventGebeurtenisnaam, bijvoorbeeld session_identified
X-MousePlayer-TimestampUnix-seconden — onderdeel van de ondertekende tekst
X-MousePlayer-Attempt1 bij de eerste poging, hoger bij nieuwe pogingen
X-MousePlayer-Signaturesha256=<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');
Bereken de handtekening over de ruwe inhoud, voordat u JSON verwerkt. Opnieuw serialiseren verandert de sleutelvolgorde en witruimte, waardoor de handtekening nooit overeenkomt. Weiger ook alles waarvan het tijdstempel meer dan enkele minuten oud is — daar dient het tijdstempel voor.

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

GebeurtenisWordt geactiveerd
session_identifiedWanneer een sessie voor het eerst een klant-ID krijgt — vanuit de browser of via de API
session_endedEenmalig, wanneer de sessie sluit
goal_reachedEenmaal 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_sessionWanneer 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_dropoffAan 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_sessionEenmaal 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_brokenEenmalig, 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_recoveredHet 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_detectedEenmaal 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_clickBij een gedetecteerde woedeklik
error_detectedBij een uitzondering in de frontend
ceGezamenlijk abonnement op uw eigen aangepaste gebeurtenissen. Het omvat niet de bovenstaande gebeurtenissen — die hebben hun eigen schakelaars.

7. Fouten & statuscodes

StatusBetekenis
200Geslaagd.
401Ontbrekende, onjuist gevormde of ingetrokken API-sleutel.
404Het gevraagde project of de sessie bestaat niet of hoort niet bij uw werkruimte.
429Verzoeklimiet overschreden — u verstuurt meer dan 60 verzoeken per minuut met deze sleutel.
403Het 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.