تخطّ إلى المحتوى الرئيسي

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

مرجع الحقول

الحقلالنوعملاحظات
namestring، 1–255مطلوب، ويظهر في لوحة التحكم ورسائل Email المُطلقة.
descriptionstring، حتى 2000اختياري، ويظهر في نص Email.
enabledbooleanافتراضه true. عند false تصبح الحالة paused ويتخطاه المُقيّم.
directioninbound | webhook | events | deliverabilityالتدفق المراقب. يعد events أحداث العملاء المخزنة في جدول events، وتراقب deliverability معدلات صحة الرسائل كنسبة من المرسل.
metriccalls | total_calls | rps | event_count | total_events | unique_users | bounceRate | hardBounceRate | softBounceRate | complaintRate | unsubscribeRate | deliveryRateما يُقاس. تنطبق الثلاثة الأولى على inbound وwebhook، والثلاثة التالية على events، ومقاييس *Rate الستة على deliverability.
codesstring[]رموز أو مجموعات HTTP مثل 2xx و4xx و5xx، وتكون ذات معنى فقط مع metric: calls.
modeabsolute | changeنموذج الحد. تستخدم deliverability الوضع absolute دائماً.
op> | <للوضع المطلق فقط؛ اتجاه الحد.
thresholdstring رقميمطلوب ويخزن كسلسلة رقمية. في deliverability يمثل نسبة مئوية، مثل "5" = 5%.
duration1m | 5m | 10m | 30m | 1hللوضع المطلق فقط؛ نافذة الخرق المستمر. ولـ deliverability تكون نافذة النظر إلى الخلف: 1h أو 4h أو 1d أو 7d.
changeDirincreased | decreasedلوضع التغير فقط؛ اتجاه التغير.
changeKindpercent | valueلوضع التغير فقط؛ يفسر threshold كنسبة أو عدد مطلق.
vsWindow15m | 1h | 4h | 1d | 7dلوضع التغير فقط؛ حجم نافذة المقارنة.
vsComparisonprevious | 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" ولم يُطلق.
scopeApiKeyPrefixstring | nullقصر على مفتاح API محدد باستخدام بادئته الظاهرة مثل jry_live_98f31a72؛ للوارد فقط.
scopeEndpointstring | nullقصر على مسار محدد مثل /users/:id بالشكل القياسي؛ للوارد فقط.
scopeWebhookUrlstring | nullقصر على URL webhook محدد. تزال query string قبل المقارنة؛ للصادر فقط.
scopeEventNamestring | nullلاتجاه الأحداث؛ اسم event_name الذي يعد. null يعد كل الأحداث، ويتجاهل مع metric: total_events.
notifyChannelemail | webhookطريقة التسليم؛ الافتراضي email.
recipientsstring[]، 1–20عناوين Email تُشعَر عند الإطلاق؛ مطلوبة لقناة Email.
webhookUrlstring | nullوجهة POST؛ مطلوبة لقناة webhook.
webhookSecretstring | nullسر توقيع HMAC-SHA256 اختياري؛ يضاف معه الرأس X-Joryio-Signature.
cooldown5m | 10m | 30m | 1hأقل وقت بين إطلاقات جديدة.
statushealthy | 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تعبير حد مقروء يطابق القاعدة.
wouldFiretrue إذا كانت القاعدة ستصبح حالياً في حالة إطلاق.

عرض السجل

GET /monitoring/history?alertId={id}&state={state}&limit={n}

يعيد سجل تدقيق انتقالات الإطلاق والحل، الأحدث أولاً.

المعاملالنوعالافتراضيملاحظات
alertIdstring-قصر على تنبيه واحد.
statefiring | resolved | snoozed-قصر على نوع انتقال.
limitinteger200حد الصفوف المعادة، وبحد صارم 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"
}
الحقلالنوعملاحظات
alertstringاسم التنبيه.
statustriggered | resolvedالانتقال الذي يمثله POST.
metricstringتسمية مقروءة للمقياس المراقب.
accountNamestringالحساب أو المنظمة التي يخصها التنبيه.
workspaceNamestringمساحة العمل التي يخصها التنبيه.
valuenumberقيمة المقياس الخام عند الانتقال.
displayValuestringقيمة منسقة؛ وفي وضع التغير تشمل الاتجاه مثل ↓ 92%.
firedAtstring، 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.

العمودالنوعملاحظات
tsDateTimeطابع UTC عند انتهاء الطلب.
organization_idStringالمنظمة المالكة.
workspace_idStringمساحة العمل المالكة.
api_key_idNullable(String)UUID لصف مفتاح API.
api_key_prefixStringبادئة المفتاح العامة، مثل jry_live_98f31a72.
methodLowCardinality(String)فعل HTTP.
endpointLowCardinality(String)المسار المعياري؛ تستبدل UUID والأجزاء الرقمية الطويلة بـ :id.
raw_pathStringالمسار الأصلي مع query string، بحد 512 حرفاً.
statusUInt16حالة استجابة HTTP.
duration_msUInt32زمن الاستجابة بالميلي ثانية.
request_ipNullable(String)IP المصدر بعد حل X-Forwarded-For.
  • التقسيم: شهري، toYYYYMM(ts).
  • الاحتفاظ: TTL لكل صف عبر delete_at، مضبوط إلى ts + retentionDays وقت الكتابة. الافتراضي 90 يوماً وقابل للضبط لكل منظمة من 7 إلى 365، ويمكن إيقاف السجل لكل منظمة.
  • المستثنى: حركة لوحة التحكم المصادق عليها بـ JWT ومسارات فحص الصحة، /health و/metrics.

webhook_delivery_logs

صف واحد لكل محاولة تسليم webhook صادرة، ناجحة أو فاشلة.

العمودالنوعملاحظات
tsDateTimeطابع UTC عند انتهاء المحاولة.
organization_idStringالمنظمة المالكة.
workspace_idStringمساحة العمل المالكة.
canvas_idNullable(String)معرّف رحلة المستخدم المصدر.
execution_idNullable(String)معرّف تنفيذ الرحلة المصدر.
node_idNullable(String)معرّف عقدة webhook المصدر.
urlStringURL الوجهة الكامل.
url_canonicalStringURL بعد إزالة query string والشرطة الختامية؛ تستخدمه فلاتر التنبيه.
methodLowCardinality(String)فعل HTTP.
statusUInt16حالة الاستجابة؛ 0 لأخطاء النقل كالمهلة وفشل DNS ورفض الاتصال.
duration_msUInt32زمن الاستجابة بالميلي ثانية.
attemptUInt8رقم المحاولة، 1 في الأولى.
errorNullable(String)رسالة الخطأ لاستجابات غير 2xx.
  • التقسيم: شهري.
  • الاحتفاظ: TTL لكل صف بواسطة delete_at؛ الافتراضي 90 يوماً ويمكن ضبطه لكل منظمة من 7 إلى 365، ويمكن إيقاف السجل لكل منظمة.
  • المستثنى: webhooks التي أُطلقت قبل إصدار الميزة، إذ تفتقر المهام القديمة إلى بيانات المستأجر اللازمة للإسناد.

events

يقرأ اتجاه الأحداث جدول events الموجود، الجدول نفسه الذي تصل إليه كل أحداث العملاء المتتبعة، بدلاً من تدفق مراقبة منفصل. يستخدم تجميعين:

المقياسالاستعلام
event_count / total_eventscount() فوق (organization_id, workspace_id, [event_name], time range).
unique_usersuniqExact(user_id) فوق الفلتر نفسه.

يضيف scopeEventName شرط event_name = …؛ وحذفه يعد كل أسماء الأحداث. يراقب ذلك عدد الأحداث المخزنة؛ الطلب المقبول الذي تُرفض حمولته يظهر في API الوارد لا هنا.

استجابات الأخطاء

الحالةمتى تحدث
400فشل التحقق، كغياب حقل مطلوب أو عدم توافق mode/op. يسرد النص الحقول المخالفة.
401JWT مفقود أو غير صالح.
403JWT صالح لكن بلا 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"}'