Monitoring API
Monitoring API משקף את המסך Settings → Logs & Monitoring בלוח הבקרה. השתמשו בו כדי ליצור התראות מ־CI, לבדוק הפעלות באמצעות סקריפט או להזרים את ההיסטוריה ל־SIEM.
כל נקודות הקצה דורשות JWT של סשן לוח הבקרה ואת ההרשאה settings:read או settings:write, בהתאם לפעולה. אי אפשר לקרוא להן באמצעות מפתח API רגיל של סביבת עבודה - ניהול התראות הוא פעולה ברמת לוח הבקרה.
כל נקודות הקצה בעמוד זה יחסיות לכתובת הבסיס: https://api-eu1.joryio.com - ראו סקירת API.
אובייקט Alert
המבנה התקני של התראה שמוחזר מכל נקודת קצה של CRUD:
{
"id": "ak_01HXYZ...",
"organizationId": "org_...",
"workspaceId": "ws_...",
"name": "Server rejecting payloads",
"description": "Joryio returned 5xx on ingestion.",
"enabled": true,
"direction": "inbound",
"metric": "calls",
"codes": ["5xx"],
"mode": "absolute",
"op": ">",
"threshold": "100",
"duration": "5m",
"changeDir": null,
"changeKind": null,
"vsWindow": null,
"vsComparison": "previous",
"scopeApiKeyPrefix": null,
"scopeEndpoint": null,
"scopeWebhookUrl": null,
"scopeEventName": null,
"notifyChannel": "email",
"recipients": ["ops@your-company.com"],
"webhookUrl": null,
"webhookSecret": null,
"cooldown": "10m",
"status": "healthy",
"lastTriggeredAt": null,
"snoozedUntil": null,
"createdBy": "usr_...",
"createdAt": "2026-05-29T05:00:00.000Z",
"updatedAt": "2026-05-29T05:00:00.000Z"
}
תיעוד שדות
| שדה | טיפוס | הערות |
|---|---|---|
name | string (1–255) | חובה. מוצג בלוח הבקרה ובאימיילים שנשלחים בעת הפעלה. |
description | string (≤2000) | אופציונלי. מוצג בגוף האימייל. |
enabled | boolean | ברירת המחדל היא true. כשהערך false, המצב משתנה ל־paused והמעריך מדלג על ההתראה. |
direction | inbound | webhook | events | deliverability | הזרם שיש לנטר. events סופר אירועי לקוחות במעקב מטבלת events. deliverability מנטר שיעורי יכולת מסירה (אחוז מתוך ההודעות שנשלחו). |
metric | calls | total_calls | rps | event_count | total_events | unique_users | bounceRate | hardBounceRate | softBounceRate | complaintRate | unsubscribeRate | deliveryRate | המדד שיש למדוד. שלושת הראשונים חלים על inbound או webhook; שלושת הבאים על events; וששת מדדי *Rate על deliverability. |
codes | string[] | קודי מצב HTTP או קבוצות (2xx, 4xx, 5xx). רלוונטי רק כאשר metric: calls. |
mode | absolute | change | מודל הסף. deliverability הוא תמיד absolute. |
op | > | < | רק במצב absolute. כיוון הסף. |
threshold | string (numeric) | חובה. נשמר כמחרוזת מספרית. עבור deliverability, אחוז (לדוגמה "5" = 5%). |
duration | 1m | 5m | 10m | 30m | 1h | רק במצב absolute. חלון חריגה רציפה. עבור deliverability, חלון המבט לאחור של השיעור - השתמשו ב-1h | 4h | 1d | 7d. |
changeDir | increased | decreased | רק במצב change. כיוון השינוי. |
changeKind | percent | value | רק במצב change. לפרש את ה-threshold כאחוז או ספירה מוחלטת. |
vsWindow | 15m | 1h | 4h | 1d | 7d | רק במצב change. גודל חלון ההשוואה. |
vsComparison | previous | last_week | average | same_weekday_median | רק במצב change. הבסיס להשוואה: previous = החלון שקדם מיד (ברירת מחדל, והפחות סלחני - יום ראשון שקט נראה כירידה מול שבת); last_week = אותו חלון לפני 7 ימים, מודע לעונתיות אך יום בודד, כך שיום חריג מרעיל את ההשוואה; average = הממוצע של אותו חלון ב-avgDays הימים האחרונים (2-30, ברירת מחדל 7), מחליק רעש אך יום חריג אחד מרים את קו הבסיס לכל התקופה; same_weekday_median = החציון של אותו חלון 7/14/21/28 ימים אחורה - מומלץ להתראות על ירידה באחוזים: מודע לעונתיות וגם לא מושפע מקמפיין, כתבה או בלאק פריידיי בודדים. נדרשים נתונים בלפחות שניים מארבעת השבועות, אחרת ההתראה מדווחת "אין עדיין מספיק היסטוריה" ולא נורית. |
scopeApiKeyPrefix | string | null | צמצום למפתח API מסוים. השתמשו ב־prefix הגלוי של המפתח (לדוגמה jry_live_98f31a72). לכיוון נכנס בלבד. |
scopeEndpoint | string | null | צמצום לנתיב מסוים (לדוגמה /users/:id). השתמשו בצורה התקנית. לכיוון נכנס בלבד. |
scopeWebhookUrl | string | null | צמצום לכתובת Webhook מסוימת. מחרוזת השאילתה מוסרת לפני ההשוואה. לכיוון יוצא בלבד. |
scopeEventName | string | null | כיוון events. איזה event_name לספור. null = ספירת כל האירועים. מוזנח כש-metric: total_events. |
notifyChannel | email | webhook | כיצד ההתראה נמסרת. ברירת מחדל email. |
recipients | string[] (1–20) | כתובות אימייל שיקבלו התראה. חובה כש-notifyChannel: email. |
webhookUrl | string | null | כתובת היעד ל-POST. חובה כש-notifyChannel: webhook. |
webhookSecret | string | null | סוד חתימה אופציונלי ל־HMAC-SHA256. כשהוא מוגדר, הבקשות כוללות את הכותרת X-Joryio-Signature. |
cooldown | 5m | 10m | 30m | 1h | זמן מינימלי בין הפעלות חוזרות. |
status | healthy | triggered | snoozed | paused | מצב בזמן הריצה. לקריאה בלבד דרך ה־API - השתמשו בנקודות הקצה של snooze ו־resume כדי לעבור בין מצבים. |
Endpoints
רשימת התראות
GET /monitoring/alerts
מחזיר את כל ההתראות בסביבת העבודה הנוכחית, מהחדש לישן.
תגובה: 200 OK - MonitoringAlert[]
קבלת התראה בודדת
GET /monitoring/alerts/:id
תגובה: 200 OK - MonitoringAlert, או 404 אם ה-ID לא בסביבת העבודה הזו.
יצירת התראה
POST /monitoring/alerts
Content-Type: application/json
{
"name": "5xx error rate",
"direction": "inbound",
"metric": "calls",
"codes": ["5xx"],
"mode": "absolute",
"op": ">",
"threshold": "100",
"duration": "5m",
"recipients": ["ops@example.com"],
"cooldown": "10m"
}
השדות name, direction, metric, mode ו-threshold תמיד חובה. שדות ספציפיים לערוץ ולמצב נבדקים סמנטית:
- ערוץ אימייל (
notifyChannel: email, ברירת המחדל) דורש לפחות רשומה אחת ב-recipients. - ערוץ Webhook (
notifyChannel: webhook) דורשwebhookUrlתקין בפרוטוקולhttp(s); recipientsו־webhookSecretאופציונליים. - שדות ספציפיים למצב נבדקים מול
mode(לדוגמה לא ניתן לשיםopבמצב change;vsComparisonחל רק במצב change). - עבור
direction: events, הגדירוscopeEventNameכדי לספור אירוע אחד (או השמיטו אותו כדי לספור הכל).metric: total_eventsתמיד סופר את כל האירועים ללא תלות ב-scopeEventName. - עבור
direction: deliverability, השתמשו ב־mode: absoluteעם אחד ממדדי*Rate, עםop, עםthresholdבאחוזים ועםdurationשל1h/4h/1d/7d(חלון המבט לאחור של השיעור). המערכת מתעלמת משדות ההיקף ומ־codes. אם לא נשלחו הודעות בחלון, ההתראה אינה מופעלת.
תגובה: 201 Created - MonitoringAlert עם id מאוכלס.
ההתראה החדשה מתחילה ב־status: healthy (או paused אם enabled: false) ונבדקת במחזור הבא של המעריך, בתוך 60 שניות.
עדכון התראה
PATCH /monitoring/alerts/:id
Content-Type: application/json
{ "threshold": "200" }
כל השדות אופציונליים. שלחו רק את אלה שברצונכם לשנות. שינוי ל־enabled: false מעביר את ההתראה ל־paused; החזרה ל־true מחזירה אותה ל־healthy (המחזור הבא של המעריך יפעיל אותה שוב אם המדד עדיין חורג).
תגובה: 200 OK - MonitoringAlert מעודכן.
מחיקת התראה
DELETE /monitoring/alerts/:id
מחיקה קשה של ההתראה. שורות ההיסטוריה שלה גם נמחקות במקביל.
תגובה: 200 OK - { "ok": true }.
השהיית התראה
POST /monitoring/alerts/:id/snooze
Content-Type: application/json
{ "window": "1h" }
window אופציונלי. עם חלון, ההתראה זזה ל-snoozed עם snoozedUntil מוגדר, ומתחדשת אוטומטית כשהזמן עובר. ללא חלון, ההתראה זזה ל-paused (ללא הגבלת זמן).
ערך window | התנהגות |
|---|---|
1h | השהיה לשעה. |
4h | השהיה ל-4 שעות. |
24h | השהיה ל-24 שעות. |
until_morning | השהיה עד 09:00 שעת שרת ביום הבא. |
| (הושמט) | השהיה ללא הגבלה. |
תגובה: 200 OK - MonitoringAlert מעודכן.
חידוש התראה
POST /monitoring/alerts/:id/resume
מנקה את snoozedUntil, מגדיר enabled: true ומעביר ל־status: healthy. המחזור הבא של המעריך בודק שוב את המדד ועשוי להעביר את ההתראה מיד ל־triggered אם הוא עדיין חורג.
תגובה: 200 OK - MonitoringAlert מעודכן.
שכפול התראה
POST /monitoring/alerts/:id/duplicate
יוצר התראה חדשה עם אותה תצורה. לשם העותק מתווספת הסיומת (copy). העותק מתחיל ב־status: healthy עם lastTriggeredAt: null, ללא תלות במצב הריצה של המקור.
תגובה: 201 Created - ה-MonitoringAlert החדש.
Live preview
POST /monitoring/preview
Content-Type: application/json
{
"direction": "inbound",
"metric": "calls",
"codes": ["5xx"],
"mode": "absolute",
"op": ">",
"threshold": "100",
"duration": "5m"
}
מעריך את המפרט הנשלח על נתונים נוכחיים בלי לשמור כלום. לא נוצרת שורת alert. לא נשלחת התראה. השתמשו בזה כדי לאמת ספים לפני יצירה.
המטען מקבל את אותם שדות הערכה כמו פעולת היצירה - אין צורך ב־name, recipients, enabled או cooldown, והמערכת מתעלמת מהם.
תגובה: 200 OK
{
"currentValue": 142,
"displayValue": "142",
"thresholdLabel": "> 100 in 5m",
"wouldFire": true
}
| שדה | משמעות |
|---|---|
currentValue | הערך הגולמי של המדד ממקור המדד. |
displayValue | גרסה אנושית של הערך. במצב change, כולל את הכיוון (לדוגמה ↓ 92%). |
thresholdLabel | ביטוי קריא של הסף שתואם לכלל. |
wouldFire | true אם הכלל היה נמצא כעת במצב triggered. |
רשימת היסטוריה
GET /monitoring/history?alertId={id}&state={state}&limit={n}
מחזיר את יומן הביקורת של מעברי הפעלה ופתרון, מהחדש לישן.
פרמטרי שאילתה:
| פרמטר | טיפוס | ברירת מחדל | הערות |
|---|---|---|---|
alertId | string | - | הגבלה להתראה בודדת. |
state | firing | resolved | snoozed | - | הגבלה לסוג מעבר אחד. |
limit | integer | 200 | מגבלה על מספר השורות שמוחזרות. מוגבל קשיח ל-1000. |
תגובה: 200 OK - MonitoringAlertHistoryEvent[]
[
{
"id": "ev_...",
"alertId": "ak_...",
"alertName": "Server rejecting payloads",
"metric": "Calls returning 5xx",
"valueAtFire": "184",
"valueLabel": "184",
"thresholdLabel": "> 100 in 5m",
"state": "firing",
"resolvedAt": null,
"recipients": ["ops@example.com"],
"notificationsSent": 1,
"firedAt": "2026-05-29T14:38:00.000Z"
}
]
שורות ההיסטוריה הן תמונות מצב - הן לוכדות את שם ההתראה, המדד, הסף והנמענים ברגע המעבר. שינוי השם או מחיקת ההתראה מאוחר יותר אינם משנים את שורות ההיסטוריה.
נקודות קצה מסייעות
אלה מזינים את הבוררים של לוח הבקרה ואת פעמון ההתראות. כולם דורשים settings:read.
רשימת שמות אירועים
GET /monitoring/event-names
מחזיר את שמות האירועים הייחודיים שנצפו בסביבת העבודה ב־30 הימים האחרונים, ממוינים לפי תדירות (200 הנפוצים ביותר). התוצאה מזינה את הבורר scopeEventName בכיוון Events, כך שהלקוחות רואים את שמות האירועים שלהם.
תגובה: 200 OK
[
{ "name": "purchase_complete", "count": 18422 },
{ "name": "add_to_cart", "count": 51904 },
{ "name": "signup", "count": 1203 }
]
רשימת מקורות Webhook
GET /monitoring/webhook-sources
מחזיר את כתובות היעד הייחודיות של Webhooks שמוגדרות בצומתי Webhook פעילים במסעות הפעילים ובטיוטות של סביבת העבודה (מסעות בארכיון אינם נכללים). התוצאה מזינה את הבורר scopeWebhookUrl בכיוון היוצא.
תגובה: 200 OK
[
{
"url": "https://hooks.your-company.com/joryio",
"canvasId": "cv_...",
"canvasName": "Win-back flow",
"nodeId": "node_...",
"nodeLabel": "Notify CRM"
}
]
התראות אחרונות
GET /monitoring/notifications/recent
מחזיר את ההפעלות האחרונות בסביבת העבודה עבור פעמון ההתראות שבכותרת לוח הבקרה.
מספר הפעלות שלא נקראו
GET /monitoring/notifications/unread-count
תגובה: 200 OK - { "count": 3 }. המספר שמוצג בתג של הפעמון.
מטען התראת Webhook
כשהתראה עם notifyChannel: webhook עוברת למצב אחר, Joryio שולחת בקשת POST אל webhookUrl. בניגוד לאימייל (שנשלח רק במעבר ל־triggered), ערוץ ה־Webhook שולח POST בשני המעברים, triggered ו־resolved, כדי שהמערכת המקבלת תוכל להתאים תקריות מקצה לקצה.
בקשה:
POST {webhookUrl}
Content-Type: application/json
User-Agent: Joryio-Monitoring/1.0
X-Joryio-Signature: {hex hmac-sha256, only when a signing secret is set}
{
"alert": "Server rejecting payloads",
"status": "triggered",
"metric": "Calls returning 5xx",
"value": 184,
"displayValue": "184",
"accountName": "Acme Inc",
"workspaceName": "Production",
"firedAt": "2026-05-29T14:38:00.000Z"
}
| שדה | טיפוס | הערות |
|---|---|---|
alert | string | שם ההתראה. |
status | triggered | resolved | איזה מעבר ה-POST הזה מייצג. |
metric | string | תווית קריאה של המדד שנמדד. |
accountName | string | החשבון (הארגון) שאליו ההתראה שייכת. |
workspaceName | string | סביבת העבודה שאליה ההתראה שייכת. |
value | number | הערך הגולמי של המדד בעת המעבר. |
displayValue | string | ערך בפורמט אנושי (במצב change, כולל כיוון, לדוגמה ↓ 92%). |
firedAt | string (ISO 8601) | מתי המעבר קרה. |
אימות חתימה. כאשר webhookSecret מוגדר, Joryio מחשבת HMAC-SHA256(rawBody) באמצעות הסוד ושולחת את התוצאה כמחרוזת הקסדצימלית באותיות קטנות (ללא prefix) בכותרת X-Joryio-Signature. חשבו אותה מחדש על גוף הבקשה הגולמי המדויק והשוו באמצעות בדיקה בזמן קבוע לפני שתתנו אמון במטען.
התנהגות המסירה. Joryio מצפה לתגובת 2xx. בכישלון היא מנסה שוב עד 3 פעמים בהשהיה מעריכית (כ־0.5, 1 ו־2 שניות); לכל ניסיון יש פסק זמן של 10 שניות. לאחר שלושה כשלים המסירה ננטשת, אך מעבר המצב עצמו עדיין נשמר ב־History.
הגנת SSRF. כתובת ה־URL מאומתת בעת יצירת ההתראה או עדכונה, ומאומתת מחדש בזמן השליחה (רשומת DNS עלולה להשתנות בין הכתיבה להפעלה). מסירה לכתובת פרטית, מקומית לקישור או לכתובת מטא־נתונים של ספק ענן נחסמת. המערכת אינה עוקבת אחר הפניות (maxRedirects: 0), מפני שהפניית 3xx לכתובת פנימית הייתה עוקפת את הבדיקה.
מקור המדד
מקורות המדדים נמצאים במאגר אירועי האנליטיקה ומתעדכנים אוטומטית. אלה אותם מקורות שמהם קוראים התרשימים בלוח הבקרה, ולכן מנוע ההתראות והאנליטיקה המותאמת חולקים מקור אמת יחיד.
אפשר להפעיל או להשבית לכל ארגון בנפרד את יומן בקשות ה־API הנכנסות ואת יומן מסירות ה־Webhook היוצאות. לכל אחד מהם חלון שמירה ניתן להגדרה (7–365 ימים, ברירת מחדל 90), שמנוהל בידי צוות Joryio במסוף הניהול. כשזרם מושבת עבור ארגון, לא נכתבות שורות וההתראות בכיוון הזה מפסיקות להיבדק. השמירה נאכפת לכל שורה באמצעות העמודה delete_at (שורות קיימות עודכנו ל־ts + 90d).
api_request_logs
שורה אחת לכל בקשה ל־REST API של Joryio שאומתה באמצעות מפתח API.
| עמודה | טיפוס | הערות |
|---|---|---|
ts | DateTime | חותמת זמן UTC של סיום הבקשה. |
organization_id | String | הארגון הבעלים. |
workspace_id | String | סביבת העבודה שאליה הרשומה שייכת. |
api_key_id | Nullable(String) | UUID של שורת המפתח. |
api_key_prefix | String | Prefix ציבורי של המפתח (לדוגמה jry_live_98f31a72). |
method | LowCardinality(String) | HTTP verb. |
endpoint | LowCardinality(String) | נתיב תקני. מזהי UUID ומקטעים מספריים ארוכים מוחלפים ב־:id. |
raw_path | String | הנתיב המקורי עם מחרוזת השאילתה, מוגבל ל־512 תווים. |
status | UInt16 | סטטוס תגובת HTTP. |
duration_ms | UInt32 | זמן תגובה במילישניות. |
request_ip | Nullable(String) | IP המקור (לאחר resolve של X-Forwarded-For). |
- חלוקה: חודשית (
toYYYYMM(ts)). - שמירה: TTL לכל שורה דרך עמודת
delete_at, מוגדר ל-ts + retentionDaysבזמן הכתיבה. ברירת מחדל 90 ימים, ניתן להגדרה לכל ארגון (7–365). ניתן לכבות לוגינג לכל ארגון. - מה לא נכלל: תעבורה מלוח הבקרה המאומתת באמצעות JWT; נתיבי בדיקות תקינות (
/health,/metrics).
webhook_delivery_logs
שורה אחת לכל ניסיון מסירה של Webhook יוצא, בין שהצליח ובין שנכשל.
| עמודה | טיפוס | הערות |
|---|---|---|
ts | DateTime | חותמת זמן UTC של סיום הניסיון. |
organization_id | String | הארגון הבעלים. |
workspace_id | String | סביבת העבודה הבעלים. |
canvas_id | Nullable(String) | ID של ה-User Journey המקורי. |
execution_id | Nullable(String) | ID של ההרצה. |
node_id | Nullable(String) | המזהה של צומת ה־Webhook המקורי. |
url | String | URL היעד המלא. |
url_canonical | String | כתובת URL ללא מחרוזת שאילתה וללא לוכסן מסיים. משמשת את מסנני ההתראות. |
method | LowCardinality(String) | HTTP verb. |
status | UInt16 | סטטוס התגובה. 0 עבור שגיאות ברמת ה-transport (timeout, DNS failure, חיבור נדחה). |
duration_ms | UInt32 | זמן תגובה במילישניות. |
attempt | UInt8 | מספר הניסיון (1 בניסיון הראשון). |
error | Nullable(String) | הודעת שגיאה על תגובות שאינן 2xx. |
- חלוקה: חודשית.
- שמירה: TTL לכל שורה דרך
delete_at. ברירת מחדל 90 ימים, ניתן להגדרה לכל ארגון (7–365). ניתן לכבות לוגינג לכל ארגון. - מה לא נכלל: Webhooks שנשלחו לפני שהיכולת פורסמה (למשימות ישנות בתור חסרים המטא־נתונים הנדרשים של הלקוח).
events
כיוון Events קורא מטבלת events הקיימת - אותה טבלה שאליה מגיע כל אירוע לקוח במעקב - ולא מזרם ניטור ייעודי. נעשה שימוש בשתי פעולות צבירה:
| מדד | שאילתה |
|---|---|
event_count / total_events | count() על (organization_id, workspace_id, [event_name], טווח זמן). |
unique_users | uniqExact(user_id) על אותו סינון. |
scopeEventName מוסיף תנאי event_name = …; אם משמיטים אותו, הספירה כוללת את כל שמות האירועים. הספירה היא של האירועים שנשמרו - בקשה ש־Joryio מקבלת אך דוחה את המטען שלה מופיעה תחת Inbound API, ולא כאן.
תגובות שגיאה
| סטטוס | מתי |
|---|---|
400 | התיקוף נכשל - שדה חובה חסר, אי־התאמה בין mode ל־op וכדומה. גוף התגובה מציין את השדות הבעייתיים. |
401 | JWT חסר או לא תקין. |
403 | ה-JWT תקין אבל חסר settings:read (list/get/history/preview) או settings:write (create/update/delete/snooze/resume/duplicate). |
404 | ID של ההתראה לא נמצא בסביבת העבודה הנוכחית. |
דוגמת אינטגרציה
יצירה, preview והשהיה של התראה מ-shell:
TOKEN=eyJ...
BASE=https://api-eu1.joryio.com
# 1) Preview before saving - would it fire right now?
curl -sX POST "$BASE/monitoring/preview" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"direction":"inbound","metric":"calls","codes":["5xx"],"mode":"absolute","op":">","threshold":"100","duration":"5m"}'
# → {"currentValue":42,"displayValue":"42","thresholdLabel":"> 100 in 5m","wouldFire":false}
# 2) Looks good - create the alert.
ALERT_ID=$(curl -sX POST "$BASE/monitoring/alerts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"5xx error rate","direction":"inbound","metric":"calls","codes":["5xx"],"mode":"absolute","op":">","threshold":"100","duration":"5m","recipients":["ops@example.com"]}' \
| jq -r .id)
# 3) Snooze it for 4 hours during a known maintenance window.
curl -sX POST "$BASE/monitoring/alerts/$ALERT_ID/snooze" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"window":"4h"}'