Watchdog API
سعة الـ Slots، والمستلمون المسمّون، والتنبيهات، وWebhooks الموقّعة.
آخر تحديث: 30/09/2026استخدم GET /api/x402/pricing ونقطة نهاية عرض سعر الاشتراك للمنتجات الحالية وأنواع الـ watch والإشارات والقيم الافتراضية والخصومات. الأنواع المدفوعة تستهلك سعة منتجها الخاص؛ الأنواع المجانية لها حدود لكل محفظة. الـ watches المتوقفة مؤقتًا تظل محسوبة. اشترِ بصلاحية spend؛ وأنشئ الـ watches أو غيّرها بصلاحية write. إنشاء watch ليس شراء اشتراك.
curl 'https://ftso.app/api/x402/subscriptions/quote?product=watchdog-slot&quantity=5&periods=12' \
-H 'authorization: Bearer fbx_READ_TOKEN'
curl -X POST 'https://ftso.app/api/x402/subscriptions' \
-H 'authorization: Bearer fbx_SPEND_TOKEN' \
-H 'content-type: application/json' \
-H 'Idempotency-Key: purchase_20260930_001' \
-d '{"product":"watchdog-slot","quantity":5,"periods":12,"autoRenew":true}'يكرر Auto-Renew الكمية والمدة المشتراتين بالسعر الحالي. يتطلب تفعيله spend؛ ويتطلب إيقافه write. قد يكون قبول الشروط القائمة مطلوبًا قبل الشراء. تتوفر تجربة لمرة واحدة عبر POST /api/x402/subscriptions/trial، رهنًا بالأهلية.
curl -X POST 'https://ftso.app/api/x402/watches' \
-H 'authorization: Bearer fbx_WRITE_TOKEN' \
-H 'content-type: application/json' \
-H 'Idempotency-Key: watch_20260930_001' \
-d '{"type":"feed-move","label":"FLR swing",
"config":{"chainId":14,"symbol":"FLR","percent":2.5,"windowMinutes":60},
"signals":{"price-move":{"enabled":true}}}'
curl -X PATCH 'https://ftso.app/api/x402/watches/7' \
-H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
-d '{"action":"pause"}'يدعم PATCH الحقول config وsignals وrouting وlabel وcooldownSeconds وmessageTemplate وwebhookUrl وrotateSecret وإجراءي pause/resume. تغييرات config تعيد ضبط حالة المراقبة. تُدمج تجاوزات الإشارات حقلًا بحقل؛ وnull يعيد ضبط تجاوز. signalsMode: replace يستبدل التجاوزات، بينما كائن signals فارغ مع الدمج الافتراضي merge لا يفعل شيئًا. تدوير السر والإعداد الأولي للـ Webhook يكشفان سرًا: خزّنه بشكل آمن. قد تسترده إعادة بالمفتاح نفسه أثناء فترة الاحتفاظ بالـ Idempotency البالغة 24 ساعة.
يمكن إعادة استخدام المستلمين المسمّين عبر عدة watches. يمكن لعملاء الآلات إنشاء قنوات الإدخال؛ أما القنوات المرتبطة فتتبع قواعد التحقق والصلاحيات الخاصة بها. ربط Discord يبقى مقتصرًا على الجلسة. المستلمون المعلّقون لا يمكنهم تلقي التنبيهات أو الاختبارات. نقاط نهاية القنوات القديمة تخاطب أقدم مستلم من نوعها؛ فضّل معرّفات المستلمين للتحكم الدقيق. عناوين URL الخاصة بالـ Webhook تُقنَّع عند القراءة: إغفال الهدف يحافظ عليه، والإزالة المقصودة بقيمة فارغة/null تمسحه. لا تكتب قناع العرض مرة أخرى كعنوان URL جديد.
curl -X POST 'https://ftso.app/api/x402/recipients' \
-H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
-d '{"name":"Ops","type":"webhook","target":{"url":"https://example.com/hooks/ftsobest"}}'
# Use the returned recipient id in routing.
curl -X PATCH 'https://ftso.app/api/x402/watches/7' \
-H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
-d '{"routing":{"default":["inapp",12],"groups":{"alerts":[12]}}}'مسار مجموعة إشارات يتجاوز الافتراضي الخاص بالـ watch؛ المستلمون الافتراضيون هم البديل الاحتياطي. أحداث الحساب/النظام تصل دائمًا إلى الجرس وإلى المستلمين الافتراضيين المحددين صراحةً. يمكن تعطيل تسليم تنبيهات الإشارات إلى الجرس. ساعات الهدوء تحجز القنوات الشخصية؛ أما المجموعات وWebhooks والجرس فتواصل التسليم. فترة cooldown الخاصة بالـ watch تكبح تكرارات الحدث نفسه، لا حدثًا مختلفًا أو تعافيه.
curl -X PUT 'https://ftso.app/api/x402/settings' \
-H 'authorization: Bearer fbx_WRITE_TOKEN' -H 'content-type: application/json' \
-d '{"quietHours":{"start":"22:00","end":"07:00","timezone":"Europe/Berlin"},"notificationLocale":"de"}'
curl -X POST 'https://ftso.app/api/x402/message-preview' \
-H 'authorization: Bearer fbx_READ_TOKEN' -H 'content-type: application/json' \
-d '{"watchId":7,"notificationLocale":"de","scope":"wallet","messageTemplate":null}'تحتوي القوالب على title وbody وappendDetails. قوالب الـ watch تتجاوز قوالب المحفظة؛ وnull يستعيد الافتراضي. العناصر النائبة استبدالات حرفية، وليست ترميزًا قابلًا للتنفيذ أبدًا. العناصر النائبة المسموح بها: {watch} و{type} و{title} و{severity} و{emoji} و{network} و{identity} و{round} و{epoch} و{details} و{time} و{link}. المعاينة لا تسلّم رسالة.
curl 'https://ftso.app/api/x402/alerts?page=0&pageSize=20&watchId=7&severity=warning&delivery=failed&sort=time&direction=desc' \
-H 'authorization: Bearer fbx_READ_TOKEN'
curl 'https://ftso.app/api/x402/alerts/export?watchId=7' \
-H 'authorization: Bearer fbx_READ_TOKEN'يستخدم السجل صفحات تبدأ من الصفر مع pageSize بحد أقصى 100. يستخدم التصدير الفلاتر نفسها ويعيد 5,000 صف CSV على الأكثر. تستخدم قوائم الـ watches والحساب limit/cursor بدلًا من ذلك. معرّفات watch أو تنبيه غريبة تعيد 404. حذف watch لا يمسح سجل تنبيهاتها. حذف التنبيهات عملية write صريحة؛ التحديد وmaxId يحميان نافذة السجل المقصودة.
تضيف الحمولة v2 الحقول payloadVersion: 2 وsignal وgroup إلى شكل v1. أبقِ الحقول التقنية دون تغيير حتى عندما يكون النص المعروض مترجمًا. اقرأ مخطط v2 واقبل حقول بيانات أحداث إضافية. أزل التكرار حسب deliveryId. قائمة الأحداث المولَّدة أدناه تغطي أحداث الإشارات والتعافي المفهرسة؛ رسائل الحساب واختبارات القنوات أحداث نظام منفصلة.
يعرض مثال v2 المختصر هذا الغلاف؛ ويحتوي data على حقائق خاصة بالنوع. يستخدم مخطط v1 الحقول الأساسية نفسها للتسليم والتنبيه والـ watch والحدث وseverity وfiredAt وdata بدون إضافات v2 الثلاث. يمكن أن يوفر rendered وrenderedMessage نص عرض مترجمًا؛ احتفظ بـ deliveryId لإزالة التكرار.
{
"payloadVersion": 2,
"deliveryId": "unique-delivery-id",
"alertId": 41,
"watchId": 7,
"label": "FLR swing",
"type": "feed-move",
"event": "feed-move.threshold",
"signal": "price-move",
"group": "alerts",
"severity": "warning",
"firedAt": "2026-09-30T12:00:00.000Z",
"data": {}
}import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody is the exact request body Buffer, not parsed/re-serialized JSON.
const timestamp = req.headers["x-watchdog-timestamp"];
const signature = req.headers["x-watchdog-signature"];
if (
typeof timestamp !== "string" ||
!/^\d+$/.test(timestamp) ||
typeof signature !== "string" ||
Math.abs(Date.now() / 1000 - Number(timestamp)) > 300
)
throw new Error("invalid");
const expected = Buffer.from(
"sha256=" +
createHmac("sha256", secret)
.update(timestamp + ".")
.update(rawBody)
.digest("hex"),
);
const received = Buffer.from(signature);
if (received.length !== expected.length || !timingSafeEqual(expected, received))
throw new Error("invalid");يستخدم التحقق X-Watchdog-Signature وX-Watchdog-Timestamp؛ افحص X-Watchdog-Payload-Version لمعرفة عقد الحمولة. لا تستجب إلا بعد التحقق من التوقيع والحداثة. أقرّ بمعرّفات التسليم المكررة دون تكرار الآثار. راجع توثيق Watchdog للمستخدمين لمسار العمل الأوسع.
- credits.low-balance
- credits.recovered
- feed-move.threshold
- fsp.balance-low
- fsp.balance-low.recovered
- fsp.fast-updates
- fsp.fast-updates.recovered
- fsp.fdc-bitvote
- fsp.fdc-bitvote-length
- fsp.fdc-bitvote-length.recovered
- fsp.fdc-bitvote.recovered
- fsp.fdc-consensus
- fsp.fdc-consensus.recovered
- fsp.fdc-reveal-offence
- fsp.fdc-reveal-offence.recovered
- fsp.fdc-signature
- fsp.fdc-signature.recovered
- fsp.fdc-submit1
- fsp.fdc-submit1.recovered
- fsp.ftso-commit
- fsp.ftso-commit.recovered
- fsp.ftso-reveal
- fsp.ftso-reveal.recovered
- fsp.ftso-signature
- fsp.ftso-signature.recovered
- fsp.mc-anchor
- fsp.mc-anchor.recovered
- fsp.mc-fdc
- fsp.mc-fdc.recovered
- fsp.mc-uptime
- fsp.mc-uptime.recovered
- fsp.monitoring
- fsp.monitoring.recovered
- fsp.not-in-policy
- fsp.not-in-policy.recovered
- fsp.registration
- fsp.registration.recovered
- fsp.reveal-offence
- fsp.reveal-offence.recovered
- fsp.rewards-unclaimed
- fsp.rewards-unclaimed.recovered
- fsp.signature-grace
- fsp.signature-grace.recovered
- fsp.signature-mismatch
- fsp.signature-mismatch.recovered
- fsp.tx-failed
- fsp.tx-failed.recovered
- fsp.validator-not-listed
- fsp.validator-not-listed.recovered
- provider.eligibility-lost
- provider.recovered
- provider.unregistered
- signing.done
- signing.missed
- signing.rewards-open
- signing.rewards-reminder
- signing.uptime-open
- wallet-balance.moved