API عمومی & کلیدهای API

دسترسی برنامه‌نویسی به فضای کاری — خواندن پروژه، نشست، رویداد اختصاصی و بخش و افزودن شناسهٔ مشتری به نشست — با کلید API محدود به فضای کاری.

1. نمای کلی

API MousePlayer امکان می‌دهد دادهٔ فضای کاری را به داشبورد، انبار داده یا ابزار داخلی خودتان ببرید. جز افزودن شناسهٔ مشتری به نشست (identify، نیازمند کلید با دامنهٔ نوشتن؛ دامنهٔ کلید را ببینید)، این API فقط‌خواندنی است: داده را نمی‌توان با آن تغییر داد یا حذف کرد.

  • نشانی پایه: https://www.mouseplayer.com/api/v1/
  • همهٔ پاسخ‌ها JSON هستند.
  • هر درخواست با کلید API احراز هویت و خودکار به فضای کاری همان کلید محدود می‌شود — کلید یک فضای کاری هرگز حتی تصادفی دادهٔ دیگری را نمی‌بیند.
  • ضبط کامل بازپخش نشست (حرکت ماوس، تصویر DOM) از API ارائه نمی‌شود . فرادادهٔ نشست، بازدید صفحه، رویداد اختصاصی و بخش می‌گیرید — برای ساخت گزارش و داشبورد بدون جابه‌جایی دادهٔ خام بازپخش کافی است.

2. احراز هویت

کلید API را در این بخش بسازید و مدیریت کنید: کلیدهای API در منوی حساب (/api-keys). فقط مالک و مدیر فضای کاری می‌توانند کلید بسازند یا پس بگیرند.

کلید را محرمانه نگه دارید. دسترسی خواندن به همهٔ فضای کاری می‌دهد. کلید کامل دقیقاً یک بار پس از ساخت نشان داده می‌شود — در مدیر رمز یا مخزن راز ذخیره کنید. اگر گم شد پس بگیرید و جدید بسازید.

کلید را به‌صورت توکن Bearer در این هدر بفرستید: Authorization در هر درخواست:

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

کلید گمشده، بدشکل یا پس‌گرفته‌شده این پاسخ را می‌گیرد: 401 به‌صورت زیر:

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

طرح مورد نیاز

REST API بخشی از طرح Business و Enterprise است. طرح از این فرد گرفته می‌شود: مالک فضای کاری؛ پس عضو دعوت‌شده آن را به ارث می‌برد. بررسی روی هر درخواست انجام می‌شود، نه فقط ساخت کلید — با کاهش طرح فضای کاری کلید موجود متوقف می‌شود و این را می‌دهد: 403.

دامنهٔ کلید

هر کلید دامنه را در پیشوند دارد تا با نگاه به آن معلوم شود چه می‌کند — در این محل: .env، در تیکت یا پایانه.

پیشوندمعنی
mp_ro_فقط خواندن. پروژه، نشست، رویداد و بخش را می‌خواند و چیزی تغییر نمی‌دهد.
mp_rw_خواندن و نوشتن. همهٔ موارد بالا و افزودن شناسهٔ مشتری از نقطهٔ پایانی identify.
هنگام ساخت دامنه را انتخاب کنید؛ پیش‌فرض فقط خواندن است. کلید فقط‌خواندنی روی نقطهٔ نوشتن این را می‌دهد: 403 با پیامی که دامنهٔ کلید و نیاز نقطهٔ پایانی را می‌گوید. دامنه بعداً عوض نمی‌شود — کلید جدید بسازید و قبلی را پس بگیرید.

3. محدودیت نرخ

هر کلید API محدود است به 60 درخواست در دقیقه، در پنجرهٔ متحرک. پس از عبور درخواست‌ها این پاسخ را می‌گیرند: 429 تا پنجره خالی شود:

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

چیزی با سقف بیشتر می‌سازید؟ از این مسیر تماس بگیرید: پشتیبانی و کاربردتان را بگویید.

4. نقطه‌های پایانی

GET/api/v1/projects

همهٔ پروژه‌های (ملک ردیابی‌شدهٔ) فضای کاری را فهرست می‌کند.

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

نشست بازدیدکنندهٔ ضبط‌شدهٔ پروژه را از جدید به قدیم با صفحه‌بندی فهرست می‌کند.

پارامتر پرس‌وجوشرح
pageشمارهٔ صفحه، پیش‌فرض 1.
per_pageنتیجه در صفحه، پیش‌فرض 25، حداکثر 100.
sinceفقط نشست آغازشده در این تاریخ یا بعد (YYYY-MM-DD).
untilفقط نشست آغازشده در این تاریخ یا پیش از آن.
{ "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}

فرادادهٔ یک نشست با بازدید صفحه‌هایش. عمداً دادهٔ کامل بازپخش را ندارد — برای آن از پخش‌کنندهٔ داشبورد استفاده کنید.

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

رویداد اختصاصی اجراشده در نشست (همان رویداد ارسالی با mp('event', ...)) همراه پارامترهایش.

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

بخش‌های بازدیدکنندهٔ تعریف‌شدهٔ پروژه را فهرست می‌کند (اختصاصی پروژه و سراسری فضای کاری).

{ "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. افزودن شناسهٔ مشتری از سمت سرور شما

مرورگر اغلب هویت فرد را نمی‌داند. در محصول B2B هویت پس از ورود در سمت سرور شما مشخص می‌شود — و در فروشگاه با تأیید سفارش. این نقطهٔ پایانی برای همان لحظه است.

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

سپس شناسه در فهرست نشست ظاهر و قابل جستجو می‌شود و این وب‌هوک session_identified اجرا می‌شود — و از همین راه به CRM می‌رسد.

دو بار فراخوانی با یک شناسه امن است. پاسخ با این مورد برمی‌گردد: "changed": false و وب‌هوکی نمی‌رود. سفارش تکراری سرنخ دوم نمی‌سازد.
وضعیتزمان
400فیلد گمشده، user_id بیش از 128 نویسه یا دارای نویسهٔ کنترلی. به‌جای بریدن رد می‌کنیم — شناسهٔ بی‌صدا کوتاه‌شده در CRM با چیزی منطبق نیست و باز موفق به نظر می‌رسد.
404نشست وجود ندارد یا متعلق به فضای کاری شما نیست. عمداً برای هر دو پاسخ یکسان است.
403طرح فضای کاری API را ندارد.

6. وب‌هوک: بررسی امضا

وب‌هوک برای هر پروژه در این بخش تنظیم می‌شود: یکپارچه‌سازی‌ها، و راز امضا را هم آنجا می‌یابید. هر تحویل این هدرها را دارد:

هدرمعنی
X-MousePlayer-Eventنام رویداد، مثلاً session_identified
X-MousePlayer-Timestampثانیهٔ Unix — بخشی از متن امضاشده
X-MousePlayer-Attempt1 در تلاش اول و بیشتر در تلاش دوباره
X-MousePlayer-Signaturesha256=<hex>

امضا یک HMAC-SHA256 روی این مورد است: timestamp + "." + raw body، با راز امضای پروژهٔ شما به‌عنوان کلید.

// 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');
بدنهٔ خام را پیش از تجزیهٔ JSON امضا کنید. سریال‌سازی دوباره ترتیب کلید و فاصله را تغییر می‌دهد و امضا هرگز منطبق نمی‌شود. زمان بیش از چند دقیقه قبل را هم رد کنید — هدف زمان همین است.

تحویل و تلاش دوباره

تحویل ناموفق پس از این فاصله‌ها تکرار می‌شود: 1 دقیقه، 5 دقیقه، 15 دقیقه، 1 ساعت و 6 ساعت، سپس کنار گذاشته می‌شود. پاسخ‌های ردهٔ 4xx به‌جز 408 و 429 تکرار نمی‌شوند — می‌گویند "نه به این شکل"، نه "نه در این لحظه". پاسخ بدهید: 2xx سریع و کار را بعد انجام دهید؛ مهلت تحویل پس از 10 ثانیه تمام می‌شود.

رویداد موجود

رویدادزمان اجرا
session_identifiedوقتی نشست نخستین بار شناسهٔ مشتری می‌گیرد — از مرورگر یا API
session_endedیک بار هنگام بسته شدن نشست
goal_reachedیک بار به‌ازای نشست وقتی رویداد اختصاصی یکی از هدف‌ها را محقق کند. فقط هدف نوع «event» — هدف نشانی، مدت، بازدید صفحه و قیف ارزیابی نمی‌شود. این را دارد: goal_id، goal_name، goal_value و currency.
high_value_sessionوقتی بازدیدکننده نخستین بار در یک روز از آستانهٔ ارزش این پروژه بگذرد. آستانه از توزیع امتیاز خودتان به دست می‌آید (صدک 90 از 90 روز اخیر)، عدد ثابت نیست و تا امتیازدهی حداقل 20 بازدیدکننده وجود ندارد. این را دارد: visitor_id، value_score، threshold و دیدنی‌ترین نشست آن روز.
funnel_dropoffدر پایان نشستی که وارد یکی از قیف‌ها شده و تمام نکرده است. مرحلهٔ توقف را نام می‌برد (dropped_at). ریزش نبود رویداد است و فقط پس از پایان نشست معلوم می‌شود. نشستی که هرگز وارد قیف نشده ریزش نیست و اجرا نمی‌کند.
high_friction_sessionیک بار به‌ازای نشست، نخستین رسیدن امتیاز اصطکاک به آستانه (پیش‌فرض 60 از 100). این را دارد: friction_score، نشانه‌های پشت آن (reasons) و نشانهٔ عبوردهنده از مرز (trigger).
element_brokenیک بار وقتی عنصر ردیابی‌شده چند روز در هیچ بازدید صفحهٔ بررسی‌شده چیزی نیافته باشد — معمولاً پس از راه‌اندازی دوباره. فقط پس از تطبیق و خرابی دوبارهٔ نشان‌گذاری دوباره اجرا می‌شود. این رویداد متعلق به هیچ نشستی نیست: session_id و session_url دارای مقدار null هستند، link_url به‌جای آن نشان‌گذاری را باز می‌کند و subject_id نشان‌گذاری را نام می‌برد — یکسان برای هر نسخه تا انتخابگر جدیدی که دوباره خراب شود به رخداد باز بپیوندد. این را دارد: rule_id، rule_name، selector، page، checked_page_views، window_days و last_matched. بدون دادهٔ بازدیدکننده.
element_recoveredرفع هشدار برای element_broken: یک بار وقتی نشان‌گذاری واقعاً دوباره عنصر بیابد — تعداد کم بازدید صفحه کافی نیست. فقط وقتی فرستاده می‌شود که element_broken با وب‌هوک رفته باشد و کلید مستقل ندارد: اشتراک این مورد element_broken شاملش می‌شود. همان مقدار subject_id است تا PagerDuty رخداد را حل و Opsgenie هشدار را ببندد. این مورد را دارد: matched_page_views و checked_page_views را هم دارد.
anomaly_detectedیک بار در روز وقتی دیروز آشکارا با 28 روز پیش فرق داشته باشد: نشست بسیار کمتر یا بیشتر، افت نرخ هدف، نشست بیشتر با اصطکاک یا خطای JS. همان سنجه و جهت یک هفته ساکت می‌ماند (قابل تنظیم). این رویداد متعلق به هیچ نشستی نیست: session_id و session_url دارای مقدار null هستند، link_url نمای پروژه را باز می‌کند و subject_id نام سنجه، جهت و روز را مشخص می‌کند. این را دارد: metric (sessions، goal_rate، friction_rate، js_error_rate، lcp_p75، inp_p75، cls_p75)، direction، day، value، expected، sessions، robust_z، z_score و این متن خوانا را دارد: summary و hint. بدون دادهٔ بازدیدکننده. برای Web Vitals، measurements جایگزین این مورد می‌شود: sessions، و page (خالی برای کل سایت) و device (desktop یا mobil) محل وقوع را می‌گویند؛ link_url سپس برگهٔ Web Vitals را باز می‌کند.
rage_clickهنگام تشخیص کلیک خشمگینانه
error_detectedهنگام استثنای سمت کاربر
ceاشتراک جمعی رویداد اختصاصی خودتان. این موارد بالا را شامل نمی‌شود — آن‌ها کلید مستقل دارند.

7. خطاها & کد وضعیت

وضعیتمعنی
200موفق.
401کلید API گمشده، بدشکل یا پس‌گرفته‌شده.
404پروژه یا نشست درخواستی نیست یا متعلق به فضای کاری شما نیست.
429عبور از سقف نرخ — با این کلید بیش از 60 درخواست/دقیقه می‌فرستید.
403طرح فضای کاری REST API را ندارد. پیام طرح لازم و فعلی را نام می‌برد.

8. نکات امنیت

  • کلید فقط‌خواندنی (mp_ro_) چیزی تغییر نمی‌دهد. کلید نوشتن (mp_rw_) فقط شناسهٔ مشتری می‌افزاید؛ هیچ کلیدی داده حذف یا دادهٔ خام بازپخش صادر نمی‌کند.
  • هر درخواست خودکار به فضای کاری کلید محدود است — راهی برای دادن شناسهٔ فضای کاری دیگر و دیدن دادهٔ شخص دیگر نیست.
  • کلید را هر زمان از این بخش پس بگیرید: /api-keys؛ پس گرفتن فوراً اثر می‌کند.
  • با کلید API مثل رمز رفتار کنید. اگر تصادفی در مخزن عمومی ثبت کردید فوری پس بگیرید و جدید بسازید.

صفحهٔ محدود رویداد (API v1، 14 اکتبر 2026)

GET /api/v1/sessions/{session_id}/events پیش‌فرض تا 100 رویداد می‌دهد. per_page را عدد صحیح از 1 تا 100 تنظیم کنید. با فرستادن cursor بدون تغییر در درخواست بعد، pagination.next_cursor را دنبال کنید؛ نشست و فضای کاری را یکسان نگه دارید. رویداد بر پایهٔ created_at و event_id مرتب است. مکان‌نما امضاشده و به همان نشست و فضای کاری محدود است. تعداد کل یا صفحهٔ عددی داده نمی‌شود.

آرایهٔ data و نگاشت params موجود در دسترس می‌ماند. pagination.returned تعداد واقعی بازگشتی است؛ pagination.has_more صفحهٔ دیگر را مشخص می‌کند. در پایان next_cursor برابر null است. پاسخ سقف 524288 بایت دارد، پس صفحه شاید رویداد کمتر از per_page داشته باشد. برای هر رویداد حداکثر 128 ردیف پارامتر می‌آید؛ با وجود بیشتر params_truncated برابر true است. متن پارامتر منفرد محدودیت پایگاه دادهٔ 255 نویسه را دارد. پارامتر بریده‌شده از این نقطهٔ پایانی در دسترس نیست. کم کردن per_page سقف پارامتر را بالا نمی‌برد.

اندازهٔ نامعتبر صفحه، مکان‌نمای دستکاری‌شده یا متعلق به نشست/فضای کاری دیگر 400 می‌دهد. دادهٔ بیش از اندازهٔ یک رویداد 413 می‌دهد. بررسی دسترسی موجود همچنان حسب مورد 401، 403، 404 یا 409 می‌دهد.

سقف همچنان 60 درخواست احرازشده به‌ازای کلید API در دقیقه است. اتمام سهمیه 429 با Retry-After: 60 می‌دهد. اگر Redis یا محدودکننده در دسترس نباشد، درخواست 503 با Retry-After: 5 می‌گیرد؛ هرگز بدون محدودیت پذیرفته نمی‌شود. به Retry-After احترام بگذارید و انتظار تصادفی بیفزایید؛ در حلقهٔ فشرده دوباره تلاش نکنید. خطای پایگاه رویداد هم 503 می‌دهد. مکان‌نما تصویر ثابتی منجمد نمی‌کند؛ درج هم‌زمان با زمان قدیمی‌تر شاید اسکن تازه بخواهد.

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 مسیر کنترل سمت سرور فقط Dev برای پیش‌نمایش SDK بومی است. در تولید خاموش می‌ماند. کلید Bearer سمت سرور برای list/replay دامنهٔ خواندن و برای register/grant/delete/disable نوشتن می‌خواهد. بررسی اضافهٔ دسترس‌پذیری پیش‌نمایش بومی اعمال می‌شود. هرگز کلید API دائمی فضای کاری را در برنامهٔ همراه جاسازی نکنید.