Monitoring API
تعكس Monitoring API سطح لوحة الإعدادات ← السجلات والمراقبة. استخدمها لإنشاء تنبيهات من CI، أو تدقيق مرات الإطلاق من برنامج نصي، أو تمرير السجل إلى SIEM.
تتطلب كل نقاط النهاية JWT لجلسة لوحة التحكم وصلاحية settings:read أو settings:write وفق الإجراء. لا تعمل بمفتاح API عادي لمساحة العمل؛ إدارة التنبيهات عملية على مستوى لوحة التحكم.
كل نقاط النهاية في هذه الصفحة نسبية إلى عنوان الأساس https://api-eu1.joryio.com. راجع نظرة عامة على API.
كائن التنبيه
هذا هو شكل التنبيه القياسي الذي تعيده كل نقطة 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 | مطلوب، ويظهر في لوحة التحكم ورسائل Email المُطلقة. |
description | string، حتى 2000 | اختياري، ويظهر في نص Email. |
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 | > | < | للوضع المطلق فقط؛ اتجاه الحد. |
threshold | string رقمي | مطلوب ويخزن كسلسلة رقمية. في deliverability يمثل نسبة مئوية، مثل "5" = 5%. |
duration | 1m | 5m | 10m | 30m | 1h | للوضع المطلق فقط؛ نافذة الخرق المستمر. ولـ deliverability تكون نافذة النظر إلى الخلف: 1h أو 4h أو 1d أو 7d. |
changeDir | increased | decreased | لوضع التغير فقط؛ اتجاه التغير. |
changeKind | percent | value | لوضع التغير فقط؛ يفسر threshold كنسبة أو عدد مطلق. |
vsWindow | 15m | 1h | 4h | 1d | 7d | لوضع التغير فقط؛ حجم نافذة المقارنة. |
vsComparison | previous | last_week | average | same_weekday_median | لوضع التغيّر فقط. previous النافذة السابقة مباشرةً (الافتراضي، والأقل تسامحًا: أحدٌ هادئ يبدو هبوطًا أمام السبت)، وlast_week النافذة نفسها قبل 7 أيام؛ يراعي الموسمية لكنه يوم واحد، فإن كان استثنائيًا أفسد المقارنة، وaverage متوسط النافذة نفسها خلال آخر avgDays يومًا (من 2 إلى 30، والافتراضي 7)؛ يخفف الضجيج لكن يومًا استثنائيًا واحدًا يرفع خط الأساس طوال المدة، وsame_weekday_median وسيط النافذة نفسها قبل 7 و14 و21 و28 يومًا - موصى به لتنبيهات الهبوط بالنسبة المئوية: يراعي الموسمية ولا تحرّكه حملة أو مقال أو جمعة بيضاء واحدة. ويلزم وجود بيانات في أسبوعين على الأقل من الأربعة، وإلا أبلغ التنبيه "not enough history yet" ولم يُطلق. |
scopeApiKeyPrefix | string | null | قصر على مفتاح API محدد باستخدام بادئته الظاهرة مثل jry_live_98f31a72؛ للوارد فقط. |
scopeEndpoint | string | null | قصر على مسار محدد مثل /users/:id بالشكل القياسي؛ للوارد فقط. |
scopeWebhookUrl | string | null | قصر على URL webhook محدد. تزال query string قبل المقارنة؛ للصادر فقط. |
scopeEventName | string | null | لاتجاه الأحداث؛ اسم event_name الذي يعد. null يعد كل الأحداث، ويتجاهل مع metric: total_events. |
notifyChannel | email | webhook | طريقة التسليم؛ الافتراضي email. |
recipients | string[]، 1–20 | عناوين Email تُشعَر عند الإطلاق؛ مطلوبة لقناة Email. |
webhookUrl | string | null | وجهة POST؛ مطلوبة لقناة webhook. |
webhookSecret | string | null | سر توقيع HMAC-SHA256 اختياري؛ يضاف معه الرأس X-Joryio-Signature. |
cooldown | 5m | 10m | 30m | 1h | أقل وقت بين إطلاقات جديدة. |
status | healthy | triggered | snoozed | paused | حالة تشغيلية للقراءة فقط عبر API؛ استخدم نقاط التأجيل والاستئناف للانتقال. |
نقاط النهاية
عرض التنبيهات
GET /monitoring/alerts
يعيد كل تنبيهات مساحة العمل الحالية، الأحدث أولاً.
الاستجابة: 200 OK - MonitoringAlert[].
الحصول على تنبيه
GET /monitoring/alerts/:id
الاستجابة: 200 OK - MonitoringAlert، أو 404 إذا لم يكن المعرّف في مساحة العمل.
إنشاء تنبيه
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 مطلوبة دائماً. وتتحقق الحقول الخاصة بالقناة والوضع دلالياً:
- تتطلب قناة Email،
notifyChannel: emailوهي الافتراضية، عنصراً واحداً على الأقل فيrecipients. - تتطلب قناة webhook،
notifyChannel: webhook،webhookUrlصالحاً من نوعhttp(s)؛ وتكونrecipientsاختيارية وwebhookSecretاختيارياً. - تُتحقق الحقول الخاصة بالوضع وفق
mode؛ لا يمكنك مثلاً ضبطopفي وضع التغير، ولا ينطبقvsComparisonإلا فيه. - مع
direction: eventsاضبطscopeEventNameلعد حدث واحد، أو احذفه لعد الكل. يعدmetric: total_eventsكل الأحداث دائماً. - مع
direction: deliverabilityاستخدمmode: absoluteمع مقياس*Rateوopوthresholdكنسبة مئوية وdurationمن1h/4h/1d/7d. تتجاهل حقول النطاق وcodes. وإذا لم تُرسل رسالة في النافذة فلا يطلق التنبيه.
الاستجابة: 201 Created - MonitoringAlert مع id مُعبأ.
يبدأ التنبيه الجديد بالحالة 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 وينقل الحالة إلى healthy. تعيد دورة المُقيّم التالية فحص المقياس وقد تنقله إلى triggered فوراً إن ظل في خرق.
الاستجابة: 200 OK - MonitoringAlert محدّث.
تكرار تنبيه
POST /monitoring/alerts/:id/duplicate
ينشئ تنبيهاً جديداً بالإعداد نفسه. يضيف الاسم (copy) وتبدأ النسخة بالحالة healthy وlastTriggeredAt: null مهما كانت حالة المصدر التشغيلية.
الاستجابة: 201 Created - MonitoringAlert الجديد.
معاينة مباشرة
POST /monitoring/preview
Content-Type: application/json
{
"direction": "inbound",
"metric": "calls",
"codes": ["5xx"],
"mode": "absolute",
"op": ">",
"threshold": "100",
"duration": "5m"
}
تقيّم مواصفات التنبيه المقدمة مقابل البيانات الحالية من دون تخزين أي شيء. لا يُنشأ تنبيه ولا يرسل إشعار. استخدمها للتحقق من الحدود قبل الإنشاء.
تقبل الحمولة حقول التقييم نفسها للإنشاء، لكن name وrecipients وenabled وcooldown غير مطلوبة وتُتجاهل.
الاستجابة: 200 OK
{
"currentValue": 142,
"displayValue": "142",
"thresholdLabel": "> 100 in 5m",
"wouldFire": true
}
| الحقل | المعنى |
|---|---|
currentValue | قيمة المقياس الخام من مصدره. |
displayValue | القيمة المنسقة للبشر. في وضع التغير تشمل الاتجاه، مثل ↓ 92%. |
thresholdLabel | تعبير حد مقروء يطابق القاعدة. |
wouldFire | true إذا كانت القاعدة ستصبح حالياً في حالة إطلاق. |
عرض السجل
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 لاتجاه الأحداث بمفردات العميل نفسها.
الاستجابة: 200 OK
[
{ "name": "purchase_complete", "count": 18422 },
{ "name": "add_to_cart", "count": 51904 },
{ "name": "signup", "count": 1203 }
]
عرض مصادر webhook
GET /monitoring/webhook-sources
يعيد URLs الوجهات المتميزة لعقد webhook الحية في الرحلات النشطة والمسودات، ولا يشمل Canvas المؤرشفة. يزوّد اختيار 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 طلب HTTP POST إلى webhookUrl. بخلاف Email الذي يطلق فقط عند triggered، تنشر قناة webhook عند 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 | قيمة منسقة؛ وفي وضع التغير تشمل الاتجاه مثل ↓ 92%. |
firedAt | string، ISO 8601 | وقت الانتقال. |
التحقق من التوقيع. عند ضبط webhookSecret يحسب Joryio HMAC-SHA256(rawBody) بالمفتاح السري ويرسله كسلسلة hex صغيرة بلا بادئة في X-Joryio-Signature. أعد حسابه فوق النص الخام الدقيق للطلب وقارنه بفحص ثابت الزمن قبل الوثوق بالحمولة.
دلالة التسليم. يتوقع Joryio استجابة 2xx. عند الفشل يعيد المحاولة حتى 3 مرات بتراجع أسي يقارب 0.5 ثانية ثم ثانية ثم ثانيتين، وبمهلة 10 ثوان لكل محاولة. بعد 3 إخفاقات يُسقط التسليم، لكن انتقال الحالة نفسه يبقى محفوظاً في السجل.
حماية SSRF. يتحقق من URL عند إنشاء التنبيه أو تحديثه ثم يعيد التحقق عند الإرسال، إذ يمكن لـ DNS تغيير الربط بين الكتابة والإطلاق. تُحظر العناوين الخاصة وlink-local وcloud metadata. لا تُتبع إعادة التوجيه، maxRedirects: 0، كي لا تتجاوز استجابة 3xx إلى عنوان داخلي هذا الفحص.
مصدر المقياس
تعيش مصادر المقاييس في مخزن أحداث التحليلات وتُملأ تلقائياً. وهي المصادر نفسها التي تقرأ منها مخططات لوحة التحكم، لذلك يشترك محرك التنبيهات وأي تحليلات مخصصة في مصدر حقيقة واحد.
يمكن تشغيل أو إيقاف سجل طلبات API الواردة وسجل تسليمات webhook الصادرة لكل منظمة، ولكل منهما مدة احتفاظ قابلة للضبط من 7 إلى 365 يوماً، الافتراضي 90، يديرها موظفو Joryio من وحدة الإدارة. عند تعطيل تدفق لمنظمة لا تُكتب صفوف وتتوقف تنبيهات ذلك الاتجاه عن التقييم. يُفرض الاحتفاظ لكل صف عبر العمود delete_at، وقد مُلئت الصفوف القديمة بـ ts + 90d.
api_request_logs
صف واحد لكل طلب مصادق عليه بمفتاح API إلى REST API في Joryio.
| العمود | النوع | ملاحظات |
|---|---|---|
ts | DateTime | طابع UTC عند انتهاء الطلب. |
organization_id | String | المنظمة المالكة. |
workspace_id | String | مساحة العمل المالكة. |
api_key_id | Nullable(String) | UUID لصف مفتاح API. |
api_key_prefix | String | بادئة المفتاح العامة، مثل jry_live_98f31a72. |
method | LowCardinality(String) | فعل HTTP. |
endpoint | LowCardinality(String) | المسار المعياري؛ تستبدل UUID والأجزاء الرقمية الطويلة بـ :id. |
raw_path | String | المسار الأصلي مع query string، بحد 512 حرفاً. |
status | UInt16 | حالة استجابة HTTP. |
duration_ms | UInt32 | زمن الاستجابة بالميلي ثانية. |
request_ip | Nullable(String) | IP المصدر بعد حل 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) | معرّف رحلة المستخدم المصدر. |
execution_id | Nullable(String) | معرّف تنفيذ الرحلة المصدر. |
node_id | Nullable(String) | معرّف عقدة webhook المصدر. |
url | String | URL الوجهة الكامل. |
url_canonical | String | URL بعد إزالة query string والشرطة الختامية؛ تستخدمه فلاتر التنبيه. |
method | LowCardinality(String) | فعل HTTP. |
status | UInt16 | حالة الاستجابة؛ 0 لأخطاء النقل كالمهلة وفشل DNS ورفض الاتصال. |
duration_ms | UInt32 | زمن الاستجابة بالميلي ثانية. |
attempt | UInt8 | رقم المحاولة، 1 في الأولى. |
error | Nullable(String) | رسالة الخطأ لاستجابات غير 2xx. |
- التقسيم: شهري.
- الاحتفاظ: TTL لكل صف بواسطة
delete_at؛ الافتراضي 90 يوماً ويمكن ضبطه لكل منظمة من 7 إلى 365، ويمكن إيقاف السجل لكل منظمة. - المستثنى: webhooks التي أُطلقت قبل إصدار الميزة، إذ تفتقر المهام القديمة إلى بيانات المستأجر اللازمة للإسناد.
events
يقرأ اتجاه الأحداث جدول events الموجود، الجدول نفسه الذي تصل إليه كل أحداث العملاء المتتبعة، بدلاً من تدفق مراقبة منفصل. يستخدم تجميعين:
| المقياس | الاستعلام |
|---|---|
event_count / total_events | count() فوق (organization_id, workspace_id, [event_name], time range). |
unique_users | uniqExact(user_id) فوق الفلتر نفسه. |
يضيف scopeEventName شرط event_name = …؛ وحذفه يعد كل أسماء الأحداث. يراقب ذلك عدد الأحداث المخزنة؛ الطلب المقبول الذي تُرفض حمولته يظهر في API الوارد لا هنا.
استجابات الأخطاء
| الحالة | متى تحدث |
|---|---|
400 | فشل التحقق، كغياب حقل مطلوب أو عدم توافق mode/op. يسرد النص الحقول المخالفة. |
401 | JWT مفقود أو غير صالح. |
403 | JWT صالح لكن بلا settings:read للعرض أو السجل أو المعاينة، أو بلا settings:write للإنشاء والتحديث والحذف والتأجيل والاستئناف والتكرار. |
404 | معرّف التنبيه غير موجود في مساحة العمل الحالية. |
مثال تكامل
إنشاء تنبيه ومعاينته وتأجيله من 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"}'