דלג לתוכן הראשי

API לאנליטיקה

ה־API של האנליטיקה מספק גישה תכנותית ליכולות אנליטיקת מוצר, ובהן שאילתות אירועים, משפכים, ניתוח שימור וניתוח נתיבים.

כל נקודות הקצה בעמוד זה יחסיות לכתובת הבסיס: https://api-eu1.joryio.com/api - ראו סקירת API.

אימות​

כל נקודות הקצה דורשות אימות באמצעות מפתח API:

Authorization: Bearer YOUR_API_KEY
X-Workspace-Id: YOUR_WORKSPACE_ID

סייר אירועים​

רשימת אירועים​

מחזיר סיכום של כל האירועים שנמדדו.

GET /analytics/events

פרמטרי שאילתה:

פרמטרסוגתיאור
startDatestringתאריך התחלה (YYYY-MM-DD)
endDatestringתאריך סיום (YYYY-MM-DD)
searchstringסינון לפי שם אירוע
limitnumberמספר התוצאות המרבי (ברירת מחדל: 100)
channelsstringאופציונלי. ספירת אירועי הודעה ו-In-App רק בערוצים האלה, מופרדים בפסיקים - ראו סינון לפי ערוץ

תגובה:

{
"events": [
{
"eventName": "signup_completed",
"totalCount": 15420,
"uniqueUsers": 12350,
"lastSeen": "2024-01-15T14:30:00Z"
}
],
"total": 45
}

סינון לפי ערוץ​

GET /analytics/events, POST /analytics/events/trend ו-POST /analytics/events/query מקבלים סינון אופציונלי channels. הוא חל רק על אירועי הודעה (message.*) ועל אירועי In-App (in_app.*): אלה נספרים רק כשהערוץ שלהם נמצא ברשימה. אירועים ללא ערוץ - רכישות, סשנים, אירועים מותאמים אישית - נספרים תמיד, בלי קשר לרשימה.

  • ערוצים: email, sms, whatsapp, push, viber, webhook, wallet, in_app, connector. כל ערך אחר נדחה עם 400.
  • GET מקבל רשימה מופרדת בפסיקים (channels=email,sms); נתיבי ה-POST מקבלים מערך JSON ("channels": ["email", "sms"]).
  • בלי הפרמטר: אין סינון - אותם מספרים כמו לפני שהפרמטר נוסף. ריק (channels= או []): אף אירוע הודעה או In-App.

כש-channels נשלח, GET /analytics/events מחזיר גם hiddenByChannel: אירועי ההודעה וה-In-App שהסינון השמיט, לפי ערוץ.

{
"events": [],
"total": 45,
"hiddenByChannel": [{ "channel": "webhook", "count": 4012 }]
}

מגמת אירועים​

מחזיר ספירות אירועים לאורך זמן.

POST /analytics/events/trend

מקבל את הסינון האופציונלי channels - ראו סינון לפי ערוץ.

גוף בקשה:

{
"eventNames": ["signup_completed", "purchase_completed"],
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"timeGranularity": "day"
}

תגובה:

[
{
"date": "2024-01-01",
"count": 523,
"uniqueUsers": 498
}
]

מאפייני אירוע​

רשימת המאפיינים של אירוע ספציפי.

GET /analytics/events/:eventName/properties

תגובה:

[
{
"propertyName": "plan_type",
"valueCount": 4
},
{
"propertyName": "source",
"valueCount": 12
}
]

פילוח לפי מאפיין​

מחזיר את התפלגות הערכים של מאפיין אירוע.

POST /analytics/events/property-breakdown

גוף בקשה:

{
"eventName": "purchase_completed",
"property": "payment_method",
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}

תגובה:

{
"total": 5420,
"values": [
{ "value": "credit_card", "count": 3250, "percentage": 59.96 },
{ "value": "paypal", "count": 1520, "percentage": 28.04 },
{ "value": "bank_transfer", "count": 650, "percentage": 11.99 }
]
}

ניתוח משפכים​

יצירת משפך​

שומר הגדרת משפך חדשה.

POST /analytics/funnels

גוף בקשה:

{
"name": "Signup to Purchase",
"steps": [
{
"id": "step_1",
"order": 0,
"eventName": "signup_completed",
"filters": []
},
{
"id": "step_2",
"order": 1,
"eventName": "onboarding_completed",
"filters": []
},
{
"id": "step_3",
"order": 2,
"eventName": "purchase_completed",
"filters": []
}
],
"conversionWindowDays": 7
}

רשימת משפכים​

GET /analytics/funnels

ניתוח משפך​

מריץ ניתוח של משפך שמור.

POST /analytics/funnels/:id/analyze

גוף בקשה:

{
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"breakdown": {
"type": "event_property",
"property": "utm_source"
}
}

תגובה:

{
"totalUsers": 10000,
"overallConversion": 12.5,
"steps": [
{
"id": "step_1",
"order": 0,
"eventName": "signup_completed",
"enteredCount": 10000,
"conversionRate": 100,
"dropOffRate": 0
},
{
"id": "step_2",
"order": 1,
"eventName": "onboarding_completed",
"enteredCount": 6500,
"conversionRate": 65,
"dropOffRate": 35
},
{
"id": "step_3",
"order": 2,
"eventName": "purchase_completed",
"enteredCount": 1250,
"conversionRate": 19.23,
"dropOffRate": 80.77
}
],
"breakdown": [
{
"breakdownValue": "google",
"overallConversion": 15.2,
"steps": [...]
}
]
}

ניתוח משפך מהיר​

ניתוח ללא שמירה.

POST /analytics/funnels/quick-analysis

ניתוח שימור​

ניתוח שימור​

POST /analytics/retention/analyze

גוף בקשה:

{
"startEvent": "signup_completed",
"returnEvent": "session_started",
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"timeUnit": "week",
"periods": 8
}

תגובה:

{
"timeUnit": "week",
"cohorts": [
{
"cohortDate": "2024-01-01",
"cohortSize": 1250,
"periods": [
{ "period": 0, "retained": 1250, "retentionRate": 100 },
{ "period": 1, "retained": 562, "retentionRate": 44.96 },
{ "period": 2, "retained": 375, "retentionRate": 30.0 }
]
}
],
"overallRetention": [100, 45.2, 31.5, 25.8, 22.1, 19.5, 17.8, 16.2]
}

ייצוא שימור​

POST /analytics/retention/export

מחזיר נתוני CSV.

השוואת שימור בין סגמנטים​

מריץ את אותו ניתוח שימור על 1 עד 10 סגמנטים שמורים ומחזיר שורה אחת לכל סגמנט, כדי שאפשר יהיה להשוות את העקומות שלהם. זה החליף את POST /analytics/retention/compare-cohorts, שכבר אינו קיים.

POST /analytics/retention/compare-segments

גוף הבקשה:

{
"segmentIds": ["seg_9f2a", "seg_71bc"],
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"entryEvent": "signup_completed",
"returnEvent": "session_started",
"timeUnit": "week",
"periods": 8
}
שדהחובהתיאור
segmentIdsכןבין מזהה סגמנט אחד ל־10.
startDate, endDateכןהחלון שממנו נקראים אירועי הכניסה.
entryEventלאהפעולה שמכניסה משתמש ל-Cohort.
returnEventלאהפעולה שנחשבת חזרה.
timeUnitלאday, week או month.
periodsלאכמה תקופות לעקוב.

תגובה:

[
{
"segmentId": "seg_9f2a",
"segmentName": "Power users",
"retention": { "timeUnit": "week", "cohorts": [], "overallRetention": [] },
"resolvedUsers": 4820,
"analyzedUsers": 4820,
"truncated": false
},
{
"segmentId": "seg_71bc",
"segmentName": "All customers",
"retention": { "timeUnit": "week", "cohorts": [], "overallRetention": [] },
"resolvedUsers": 480000,
"analyzedUsers": 50000,
"truncated": true
}
]
שדהתיאור
resolvedUsersהגודל האמיתי של הסגמנט - כל חבר שהוא נפרס אליו.
analyzedUsersמכמה חברים חושב retention. שווה ל-resolvedUsers אלא אם הסגמנט נחתך בתקרה.
truncatedtrue כשהסגמנט חרג מתקרת 50,000 החברים, ולכן retention מתאר מדגם אקראי דטרמיניסטי של analyzedUsers חברים - לעולם לא N הראשונים, שהיו מוטים. גלו את שני המספרים בכל מקום שבו אתם מציגים את השיעורים.
errorקיים כשדווקא הסגמנט הזה לא ניתן לניתוח. שאר השורות עדיין מוחזרות, והשורה שנכשלה אינה נושאת שיעורים - אל תציגו אותה כ-0%.

ניתוח נתיבים​

ניתוח נתיבים​

POST /analytics/paths/analyze

גוף בקשה:

{
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"startEvent": "landing_page_view",
"direction": "forward",
"maxSteps": 5,
"minPathCount": 10,
"minPathPercent": 0.5,
"maxBranchesPerStep": 5,
"excludeEvents": ["heartbeat", "scroll"]
}

תגובה:

{
"totalUsers": 25000,
"totalPaths": 342,
"paths": [
{
"path": ["landing_page_view", "signup_started", "signup_completed"],
"count": 3250,
"percentage": 13.0
}
],
"sankey": {
"nodes": [
{ "id": "landing_page_view_0", "name": "landing_page_view" }
],
"links": [
{ "source": "landing_page_view_0", "target": "signup_started_1", "value": 5200 }
]
}
}

לוחות בקרה​

יצירת לוח בקרה​

POST /analytics/dashboards

גוף בקשה:

{
"name": "Executive Dashboard",
"description": "Key metrics overview",
"widgets": [
{
"id": "widget-1",
"type": "metric",
"title": "Active Users",
"config": {
"eventName": "session_started",
"metric": "unique_users"
},
"layout": { "x": 0, "y": 0, "width": 3, "height": 2 }
}
]
}

רשימת לוחות בקרה​

GET /analytics/dashboards

קבלת לוח בקרה​

GET /analytics/dashboards/:id

עדכון לוח בקרה​

PUT /analytics/dashboards/:id

מחיקת לוח בקרה​

DELETE /analytics/dashboards/:id

אנליטיקה בזמן אמת​

משתמשים פעילים​

GET /analytics/realtime/active-users

תגובה:

{
"count": 1523,
"trend": 5.2
}

זרם אירועים חי (SSE)​

GET /analytics/realtime/events/stream

מחזיר זרם Server-Sent Events של אירועים חיים.


מדידת תוספת​

שתי נקודות קצה עונות על שאלות שהדוחות הרגילים לא יכולים לענות עליהן: האם ההודעות גרמו למשהו, והאם אני שולח יותר מדי. שתיהן נשענות על קבוצת הביקורת הגלובלית - פלח אנשי קשר שנבחר באקראי ומוחזק מחוץ לכל השיווק, כדי שיהיה מול מה להשוות באופן כנה.

תוספת מול קבוצת ביקורת גלובלית​

GET /analytics/global-holdout?startDate=2026-08-01&endDate=2026-08-31

המרות והכנסות של כל מי שקיבל שיווק בתקופה, מול הקבוצה שהוחזקה באקראי.

התוצאה עטופה במעטפת uplift. היא { "uplift": null } כשאין קבוצת ביקורת גלובלית פעילה - אין מול מה להשוות, ותוצאה שלא נמדדה אינה אפס.

תגובה:

{
"uplift": {
"treatmentRecipients": 41280,
"treatmentConverters": 1650,
"treatmentRevenue": 82560,
"treatmentRevenuePerRecipient": 2.0,
"controlRecipients": 4600,
"controlConverters": 138,
"controlRevenue": 6900,
"controlRevenuePerRecipient": 1.5,
"incrementalRevenue": 20640,
"upliftPct": 33.3,
"significance": {
"controlRate": 0.03,
"treatmentRate": 0.04,
"pValue": 0.002,
"significant": true,
"controlInterval": [0.0255, 0.0353],
"treatmentInterval": [0.0381, 0.0419],
"reason": "significant",
"minConvertersPerArm": 10
},
"currency": "EUR",
"mixedCurrency": false,
"windowHours": 168
}
}

השדה significance.significant בודק את שיעור ההמרה, לא את ההכנסה: הכנסה לנמען היא רציפה ובעלת זנב כבד, ומבחן פרופורציה עליה מפיק מספרים שנראים בטוחים ואינם אומרים דבר. יש להתייחס אל incrementalRevenue ((treatmentRevenuePerRecipient - controlRevenuePerRecipient) x treatmentRecipients) כאל אומדן שהאמינות שלו מגיעה מ־significance.significant, לא מהדיוק שלו עצמו. significance הוא null כשלאחת הזרועות אין נמענים; reason מסביר מדוע התוצאה עדיין לא מובהקת (not_enough_conversions, no_difference_detected). upliftPct הוא null כשזרוע הביקורת לא הניבה הכנסה. windowHours הוא חלון ההתנהגות שבו נמדדו שתי הזרועות (ברירת מחדל 168), ו-mixedCurrency הוא true כשהרכישות חוצות יותר ממטבע אחד - לא מבוצעת המרת מטבע.

תדירות הודעות​

GET /analytics/message-frequency?startDate=2026-08-01&endDate=2026-08-31

המרות לפי כמות ההודעות שאדם קיבל, מפוצל לפי האם הוא כבר היה פעיל לפני התקופה.

תגובה:

{
"buckets": [
{ "bucket": "0", "tier": "engaged", "people": 2300, "buyers": 69, "purchaseRate": 3.0, "converters": 69, "conversionRate": 3.0,
"revenue": 3450, "revenuePerPerson": 1.5, "randomised": true },
{ "bucket": "1", "tier": "engaged", "people": 8100, "buyers": 405, "purchaseRate": 5.0, "converters": 405, "conversionRate": 5.0,
"revenue": 20250, "revenuePerPerson": 2.5 },
{ "bucket": "6-9", "tier": "engaged", "people": 1200, "buyers": 48, "purchaseRate": 4.0, "converters": 48, "conversionRate": 4.0,
"revenue": 4800, "revenuePerPerson": 4.0 }
],
"anchored": true,
"currency": "EUR",
"mixedCurrency": false,
"priorWindowDays": 90
}

הדליים הם 0, 1, 2, 3, 4-5, 6-9, 10+. השדה tier הוא engaged או quiet, ונקבע לפי פתיחות ולחיצות ב־priorWindowDays שלפני התקופה - אף פעם לא בתוכה, מה שהיה מעגלי.

שני שדות קובעים כיצד מותר לקרוא את המספרים:

  • randomised מופיע רק על דלי 0 שנבנה מקבוצת הביקורת הגלובלית. אפס שנבנה בכל דרך אחרת הוא אנשים שבמקרה לא קיבלו דבר, והם לא קיבלו מסיבות שגם מקטינות את הסיכוי שירכשו.
  • anchored הוא true כשקיים אפס כזה. כשהוא false אין דלי 0 כלל, וזה בכוונה: בסיס מומצא היה יושב בדיוק בנקודה שמולה נמדד כל מספר אחר.

יש לקרוא את העקומה מתוך ידיעה שההטיה פועלת לכיוון אחד. אנשים שמקבלים יותר הודעות פעילים יותר מלכתחילה, ולכן הקו נדחף כלפי מעלה יהיה אשר יהיה. קו עולה אינו מוכיח דבר, ואילו קו שמתיישר או יורד בתדירויות גבוהות הוא אמין - הוא הופיע למרות הטיה שפועלת נגדו.

השדה converters סופר הזמנות בכל מטבע; revenue מסכם רק את המטבע הדומיננטי, ששמו ב־currency. כאשר mixedCurrency הוא true עמודת הכסף היא פלח אחד ולא סכימת המרות מטבע.

buyers ו-purchaseRate הם רכישות (הזמנות), לא המרות: העקומה חלה על כל סביבת העבודה, ולכן אין יעד של קמפיין או מסע לספור. converters ו-conversionRate הם אותם שני מספרים בשמות הישנים, שנשמרו עבור לקוחות קיימים.


ביצועי תוכן​

GET /analytics/content-performance?startDate=2026-08-01&endDate=2026-08-31&channel=email

שיעורי פתיחה, קליקים ורכישה אחרי שליחה לפי מה שההודעה היא - הטון, סוג ההצעה, הקריאה לפעולה, האורך, ההתאמה האישית, התמונות והנושא - על פני כל תבנית, וריאציית קמפיין והודעת מסע. channel אופציונלי.

תגובה:

{
"startDate": "2026-08-01",
"endDate": "2026-08-31",
"channel": null,
"minReached": 100,
"conversionWindowHours": 168,
"taxonomyVersion": "t1",
"totals": { "sent": 18400, "reached": 12100, "labelledSent": 17900, "unlabelledSent": 500, "identities": 42, "labelledIdentities": 40, "noGoalSent": 2300 },
"fields": {
"tone": [
{ "value": "friendly", "sent": 9100, "reached": 6000, "opened": 2520, "clicked": 420, "converted": 150, "goalReached": 5000, "bought": 180, "openRate": 42.0, "clickRate": 7.0, "conversionRate": 3.0, "purchaseRate": 3.0 },
{ "value": "urgent", "sent": 2200, "reached": 1500, "opened": 720, "clicked": 150, "converted": 0, "goalReached": 0, "bought": 60, "openRate": 48.0, "clickRate": 10.0, "conversionRate": null, "purchaseRate": 4.0 },
{ "value": "premium", "sent": 90, "reached": 80, "opened": 30, "clicked": 4, "converted": 1, "goalReached": 80, "bought": 1, "openRate": null, "clickRate": null, "conversionRate": null, "purchaseRate": null }
],
"offerType": [ "..." ],
"ctaType": [ "..." ]
},
"mergeFields": {
"version": "m2",
"measuredSent": 17400,
"pendingSent": 500,
"buckets": [
{
"field": "user.first_name", "placement": "subject", "usage": "merge", "channels": ["email"],
"with": { "sent": 6100, "reached": 4200, "opened": 1932, "clicked": 315, "converted": 120, "goalReached": 3800, "bought": 130, "openRate": 46.0, "clickRate": 7.5, "conversionRate": 3.16, "purchaseRate": 3.1 },
"without": { "sent": 8800, "reached": 5900, "opened": 2242, "clicked": 354, "converted": 140, "goalReached": 5200, "bought": 160, "openRate": 38.0, "clickRate": 6.0, "conversionRate": 2.69, "purchaseRate": 2.71 }
}
],
"other": null
}
}

ב-fields יש רשימה לכל תיוג (tone, urgency, offerType, ctaType, lengthBand, personalizationDepth, imageryPresent, primaryTopic), ממוינת לפי אנשים שהגיעו אליהם. השיעורים סופרים אנשים ייחודיים, ללא בוטים; openRate ו-clickRate הם חלק מהאנשים שההודעה נמסרה להם (Push: מתוך reached; In-app: מתוך שהוצגו) - אותו כלל כמו בשיעורי הקמפיינים (ראו איך מחושבים שיעורי הפתיחה וההקלקה). שיעור הוא null מתחת ל-minReached אנשים, ובערוץ שלא יכול למדוד אותו (לפוש אין פתיחות). conversionRate ו-purchaseRate מתוארים בהמשך. totals.unlabelledSent הוא תעבורה שלתוכן שלה אין עדיין תיוג; POST /ai/content/backfill (דשבורד) מתייג תוכן קיים.

conversionRate ו-converted הם יעד ההמרה של כל הודעה עצמה - היעד של הקמפיין או המסע שלה, נספר עם החלון ומודל הייחוס של אותו יעד ונזקף לגרסה או להודעה במסע שהמודל זוקף לה - מתוך goalReached, האנשים שהגיעו אליהם הודעות שיש להן יעד. בשורה שאין בה אף הודעה עם יעד conversionRate: null, ותבנית שנשלחה לבד לעולם אינה נספרת כהמרה. totals.noGoalSent הוא התעבורה בלי יעד. purchaseRate ו-bought הם נתון ההזמנות: רכישה של אותו אדם בתוך conversionWindowHours אחרי השליחה, חלון פשוט בלי קשר ליעד. עד 2026-10-14 conversionRate היה שיעור הרכישה הזה.

mergeFields משווה תוכן לפי שדה מיזוג: דלי אחד לכל שם שדה, placement (subject, preheader, title, body, cta, link - כתובת של קישור; משתני {{n}} של WhatsApp נספרים כשדה שהם מקושרים אליו) ו-usage (merge = מוצג בטקסט, conditional = רק קובע מה יוצג), עם אותם ספירות ושיעורים לשליחות המתויגות שמשתמשות בו (with) ולשליחות המתויגות באותם channels שלא משתמשות בו (without). הרף minReached חל על כל צד. רק שמות שדות, אף פעם לא ערכים. מוצגים עד 100 צירופים, מהרבים ביותר באנשים שהגיעו אליהם; השאר מסוכמים ב-other ולא נזרקים. pendingSent הוא תעבורה מתויגת ששדות המיזוג שלה עוד לא נקראו; היא לא בשום צד. ההשוואה היא מתאם, לא סיבה.


תגובות שגיאה​

כל נקודות הקצה מחזירות תגובות שגיאה סטנדרטיות:

{
"statusCode": 400,
"message": "Invalid date range",
"error": "Bad Request"
}
קוד סטטוסתיאור
400בקשה שגויה / שגיאת תיקוף
401לא מורשה
403גישה אסורה
404משאב לא נמצא
500שגיאת שרת פנימית