API Publik & Kunci API

Akses terprogram ke ruang kerja Anda — membaca proyek, sesi, peristiwa kustom, dan segmen, serta melampirkan ID pelanggan ke sesi — diamankan dengan kunci API yang dibatasi pada ruang kerja.

1. Ringkasan

API MousePlayer memungkinkan Anda mengambil data dari ruang kerja ke dasbor sendiri, gudang data, atau alat internal. Selain melampirkan ID pelanggan ke sesi (identify, memerlukan kunci dengan cakupan tulis, lihat Cakupan kunci), API bersifat hanya baca: tidak ada data yang dapat diubah atau dihapus melalui API.

  • URL Dasar: https://www.mouseplayer.com/api/v1/
  • Semua respons berupa JSON.
  • Setiap permintaan diautentikasi dengan kunci API dan otomatis dibatasi pada ruang kerja pemilik kunci — kunci dari satu ruang kerja tidak pernah dapat melihat data ruang kerja lain, bahkan secara tidak sengaja.
  • Rekaman pemutaran ulang sesi lengkap (gerakan mouse, snapshot DOM) tidak tersedia melalui API. Anda mendapatkan metadata sesi, tampilan halaman, peristiwa kustom, dan segmen — cukup untuk membuat laporan dan dasbor tanpa memindahkan payload pemutaran ulang mentah.

2. Autentikasi

Buat dan kelola kunci API Anda pada Kunci API di menu akun (/api-keys). Hanya pemilik dan admin ruang kerja yang dapat membuat atau mencabut kunci.

Rahasiakan Kunci Anda. Kunci memberikan akses baca ke semua yang ada di ruang kerja. Kunci lengkap ditampilkan tepat sekali, segera setelah dibuat — simpan dalam pengelola kata sandi atau brankas rahasia. Jika hilang, cabut dan buat kunci baru.

Kirim kunci sebagai token Bearer dalam header Authorization pada setiap permintaan:

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

Kunci yang tidak ada, salah format, atau dicabut menerima respons 401:

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

Persyaratan Paket

REST API merupakan bagian dari paket Business dan Enterprise. Paket diambil dari pemilik ruang kerja, sehingga anggota tim yang diundang mewarisinya. Pemeriksaan dijalankan pada setiap permintaan, bukan hanya saat kunci dibuat — jika paket ruang kerja diturunkan, kunci yang ada berhenti berfungsi dan mengembalikan 403.

Cakupan Kunci

Setiap kunci membawa cakupannya dalam prefiksnya sendiri, sehingga Anda dapat mengetahui fungsi kunci hanya dengan melihatnya — dalam .env, tiket, atau terminal.

PrefiksMakna
mp_ro_Hanya baca. Membaca proyek, sesi, peristiwa, dan segmen. Tidak dapat mengubah apa pun.
mp_rw_Baca dan tulis. Semua di atas, ditambah melampirkan ID pelanggan melalui endpoint identify.
Pilih cakupan saat membuat kunci; bawaannya hanya baca. Menggunakan kunci hanya baca pada endpoint tulis mengembalikan 403 dengan pesan yang menyebut jenis kunci dan kebutuhan endpoint. Cakupan tidak dapat diubah setelahnya — buat kunci baru dan cabut yang lama.

3. Batas Permintaan

Setiap kunci API dibatasi hingga 60 permintaan per menit, dihitung dalam rentang waktu bergulir. Setelah terlampaui, permintaan menerima respons 429 hingga rentang waktu berlalu:

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

Membuat sesuatu yang memerlukan batas lebih tinggi? Hubungi Dukungan dan jelaskan kasus penggunaan Anda.

4. Endpoint

GET/api/v1/projects

Mencantumkan setiap proyek (situs yang dilacak) dalam ruang kerja Anda.

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

Mencantumkan sesi pengunjung yang direkam untuk proyek, dari yang terbaru. Menggunakan paginasi.

Parameter kueriDeskripsi
pageNomor halaman, bawaan 1.
per_pageHasil per halaman, bawaan 25, maksimum 100.
sinceHanya sesi yang dimulai pada/setelah tanggal ini (YYYY-MM-DD).
untilHanya sesi yang dimulai pada/sebelum tanggal ini.
{ "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 satu sesi beserta tampilan halamannya. Sengaja tidak menyertakan payload pemutaran ulang lengkap — gunakan Pemutar pada dasbor untuk itu.

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

Peristiwa kustom yang dipicu selama sesi (peristiwa sama yang Anda kirim dengan mp('event', ...)), termasuk parameternya.

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

Mencantumkan segmen pengunjung yang ditentukan untuk proyek (segmen khusus proyek maupun seluruh ruang kerja).

{ "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. Melampirkan ID Pelanggan dari Backend Anda

Browser sering tidak mengetahui siapa penggunanya. Dalam produk B2B, identitas diketahui setelah masuk — di backend Anda. Dalam toko, diketahui saat konfirmasi pesanan. Endpoint ini untuk saat tersebut.

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}}

ID kemudian muncul dalam daftar sesi, dapat dicari di sana, dan webhook session_identified dipicu — begitulah ID mencapai CRM Anda.

Aman Memanggil Dua Kali dengan ID yang Sama. Respons kembali dengan "changed": false dan tidak ada webhook yang dikirim. Pesanan berulang tidak membuat prospek kedua.
StatusKapan
400Kolom tidak ada, user_id melebihi 128 karakter, atau mengandung karakter kontrol. Kami menolak, bukan memotong — ID yang dipendekkan diam-diam tidak cocok dengan apa pun di CRM dan tetap tampak berhasil.
404Sesi tidak ada atau bukan milik ruang kerja Anda. Sengaja memberikan jawaban sama untuk keduanya.
403Paket ruang kerja tidak mencakup API.

6. Webhook: Memverifikasi Tanda Tangan

Webhook dikonfigurasi per proyek pada Integrasi, tempat Anda juga menemukan rahasia penandatanganan. Setiap pengiriman membawa header berikut:

HeaderMakna
X-MousePlayer-EventNama peristiwa, misalnya session_identified
X-MousePlayer-TimestampDetik Unix — bagian dari teks yang ditandatangani
X-MousePlayer-Attempt1 pada percobaan pertama, lebih tinggi pada percobaan ulang
X-MousePlayer-Signaturesha256=<hex>

Tanda tangan adalah HMAC-SHA256 atas timestamp + "." + raw body, menggunakan rahasia penandatanganan proyek Anda sebagai kunci.

// 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');
Tandatangani isi mentah, sebelum penguraian JSON apa pun. Serialisasi ulang mengubah urutan kunci dan spasi, sehingga tanda tangan tidak akan cocok. Tolak pula cap waktu yang lebih lama dari beberapa menit — itulah fungsi cap waktu.

Pengiriman dan Percobaan Ulang

Pengiriman gagal dicoba ulang setelah 1 menit, 5 menit, 15 menit, 1 jam, dan 6 jam, lalu dihentikan. Respons 4xx selain 408 dan 429 tidak dicoba ulang — berarti "bukan dengan cara ini", bukan "bukan sekarang". Balas 2xx dengan cepat dan kerjakan sesudahnya; pengiriman mencapai batas waktu setelah 10 detik.

Peristiwa yang Tersedia

PeristiwaDipicu
session_identifiedSaat sesi pertama kali mendapatkan ID pelanggan — dari browser atau API
session_endedSekali, saat sesi ditutup
goal_reachedSekali per sesi, saat peristiwa kustom memenuhi salah satu sasaran Anda. Hanya sasaran bertipe “event” — sasaran URL, durasi, tampilan halaman, dan funnel tidak dievaluasi. Membawa goal_id, goal_name, goal_value dan currency.
high_value_sessionSaat pengunjung pertama kali melewati ambang nilai proyek ini pada hari tertentu. Ambang tersebut diturunkan dari distribusi skor Anda sendiri (persentil ke-90 dari 90 hari terakhir), bukan angka tetap, dan belum tersedia hingga setidaknya 20 pengunjung dinilai. Membawa visitor_id, value_score, threshold dan sesi paling layak ditonton pada hari itu.
funnel_dropoffPada akhir sesi yang memasuki salah satu funnel Anda tetapi tidak menyelesaikannya. Menyebut langkah tempat sesi berhenti (dropped_at). Keluar dari funnel berarti tidak adanya peristiwa, sehingga hanya dapat diketahui setelah sesi berakhir. Sesi yang tidak pernah memasuki funnel bukan sesi yang keluar dan tidak memicu peristiwa.
high_friction_sessionSekali per sesi, saat skor hambatannya pertama kali mencapai ambang (bawaan 60 dari 100). Membawa friction_score, sinyal yang mendasarinya (reasons) dan sinyal yang melewati batas (trigger).
element_brokenSekali, saat elemen yang dilacak tidak menemukan apa pun dalam setiap tampilan halaman yang diperiksa selama beberapa hari — biasanya setelah peluncuran ulang. Dipicu lagi hanya setelah penandaan berhasil cocok lalu rusak lagi. Peristiwa ini tidak terkait dengan sesi apa pun: session_id dan session_url bernilai null, link_url membuka penandaan sebagai gantinya, dan subject_id menyebut penandaan — sama untuk setiap versi, sehingga selektor baru yang rusak lagi bergabung dengan insiden terbuka. Membawa rule_id, rule_name, selector, page, checked_page_views, window_days dan last_matched. Tanpa data pengunjung.
element_recoveredPemberitahuan pulih untuk element_broken: setelah penandaan benar-benar menemukan elemen lagi — tampilan halaman yang terlalu sedikit tidak cukup. Hanya dikirim jika element_broken telah dikirim melalui webhook, dan tidak memiliki sakelar sendiri: berlangganan element_broken menyertakannya. Nilai subject_id sama, sehingga PagerDuty menyelesaikan insiden dan Opsgenie menutup peringatan. Membawa matched_page_views dan checked_page_views sebagai tambahan.
anomaly_detectedSekali sehari, saat kemarin jelas berbeda dari 28 hari sebelumnya: sesi jauh lebih sedikit atau lebih banyak, tingkat pencapaian sasaran menurun, lebih banyak sesi dengan hambatan atau kesalahan JS. Metrik dan arah yang sama tidak memicu pemberitahuan selama seminggu (dapat diatur). Peristiwa ini tidak terkait dengan sesi apa pun: session_id dan session_url bernilai null, link_url membuka ringkasan proyek, dan subject_id menyebut metrik, arah, dan hari. Membawa metric (sessions, goal_rate, friction_rate, js_error_rate, lcp_p75, inp_p75, cls_p75), direction, day, value, expected, sessions, robust_z, z_score dan summary yang mudah dibaca serta hint. Tanpa data pengunjung. Untuk Web Vitals, measurements menggantikan sessions, dan page (kosong untuk seluruh situs) serta device (desktop atau mobil) menunjukkan tempat terjadinya; link_url kemudian membuka tab Web Vitals.
rage_clickSaat klik marah terdeteksi
error_detectedSaat pengecualian front-end terjadi
ceLangganan gabungan untuk peristiwa kustom Anda sendiri. Tidak mencakup peristiwa di atas — peristiwa tersebut memiliki sakelar sendiri.

7. Kesalahan & Kode Status

StatusMakna
200Berhasil.
401Kunci API tidak ada, salah format, atau dicabut.
404Proyek atau sesi yang diminta tidak ada atau bukan milik ruang kerja Anda.
429Batas permintaan terlampaui — Anda mengirim lebih dari 60 permintaan/menit dengan kunci ini.
403Paket ruang kerja tidak mencakup REST API. Pesan menyebut paket yang diperlukan maupun paket saat ini.

8. Catatan Keamanan

  • Kunci hanya baca (mp_ro_) tidak dapat mengubah apa pun. Kunci tulis (mp_rw_) hanya dapat melampirkan ID pelanggan; tidak ada kunci yang dapat menghapus data atau mengekspor data pemutaran ulang mentah.
  • Setiap permintaan otomatis dibatasi pada ruang kerja kunci itu sendiri — tidak ada cara mengirim ID ruang kerja lain dan melihat data orang lain.
  • Cabut kunci kapan saja dari /api-keys; pencabutan langsung berlaku.
  • Perlakukan kunci API seperti kata sandi. Jika tidak sengaja memasukkannya ke repositori publik, segera cabut dan buat kunci baru.

Halaman Peristiwa Berbatas (API v1, 14 Oktober 2026)

GET /api/v1/sessions/{session_id}/events mengembalikan hingga 100 peristiwa secara bawaan. Tetapkan per_page ke bilangan bulat dari 1 hingga 100. Ikuti pagination.next_cursor dengan mengirim cursor tanpa perubahan pada permintaan berikutnya; pertahankan sesi dan ruang kerja yang sama. Peristiwa diurutkan menurut created_at dan event_id. Kursor ditandatangani serta terikat pada sesi dan ruang kerja tersebut. Tidak ada jumlah total atau nomor halaman yang dikembalikan.

Array data dan peta params yang ada tetap tersedia. pagination.returned adalah jumlah sebenarnya yang dikembalikan; pagination.has_more menunjukkan adanya halaman lain. next_cursor bernilai null saat selesai. Respons dibatasi hingga 524288 byte, sehingga halaman mungkin berisi lebih sedikit peristiwa daripada per_page. Per peristiwa, maksimum 128 baris parameter dikembalikan; params_truncated bernilai true jika ada lebih banyak. Parameter string individual tetap memiliki batas basis data 255 karakter. Parameter yang terpotong tidak tersedia melalui endpoint ini. Mengurangi per_page tidak menaikkan batas parameter.

Ukuran halaman tidak valid, kursor yang diubah, dan kursor untuk sesi/ruang kerja lain mengembalikan 400. Data peristiwa individual yang terlalu besar mengembalikan 413. Pemeriksaan akses yang ada tetap mengembalikan 401, 403, 404, atau 409 sesuai kondisi.

Batas tetap 60 permintaan terautentikasi per kunci API per menit. Saat habis, respons 429 diberikan dengan Retry-After: 60. Jika Redis atau pembatas tidak tersedia, permintaan mengembalikan 503 dengan Retry-After: 5; tidak pernah diterima tanpa batas. Patuhi Retry-After dan tambahkan jeda ulang acak; jangan mencoba ulang dalam loop rapat. Kegagalan basis data peristiwa juga mengembalikan 503. Kursor tidak membekukan snapshot: penyisipan bersamaan dengan cap waktu lebih lama mungkin memerlukan pemindaian baru.

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 adalah rute kontrol backend khusus Dev untuk pratinjau SDK native. Tetap dinonaktifkan dalam produksi. Kunci Bearer backend memerlukan cakupan baca untuk list/replay dan cakupan tulis untuk register/grant/delete/disable. Pemeriksaan tambahan ketersediaan pratinjau native berlaku. Jangan pernah menyematkan kunci API ruang kerja permanen dalam aplikasi seluler.