الأدلة الأساسية
واجهة برمجة تطبيقات إدارة الـ Webhook
قم بتهيئة إشعارات المهام من خلال لوحة التحكم (Dashboard) أو واجهة برمجة التطبيقات (API) أو MCP، وتحقق من التوقيعات، وقم باستكشاف أخطاء التسليم وإصلاحها.
تقوم الـ Webhooks بإخطار تطبيقك عند اكتمال مهمة غير متزامنة، أو فشلها، أو انتهاء مهلتها الزمنية. يمكنك تهيئتها في Dashboard → API → Webhooks، أو من خلال Management API، أو عبر ملف تعريف full الخاص بـ TokenLab MCP. تشترك جميعها في نفس نقاط نهاية مساحة العمل (workspace endpoints) وسجل التسليم.
أي بيانات اعتماد يجب استخدامها
| بيانات الاعتماد | الغرض | أين تُستخدم |
|---|---|---|
Management Token mt-… | إنشاء، سرد، تحديث، حذف، اختبار، وتدوير الـ webhooks | Authorization: Bearer mt-… على /v1/management/webhooks* |
API key sk-… | إرسال طلبات النماذج والاستعلام عن حالة المهمة | واجهات برمجة تطبيقات النماذج و /v1/tasks/{id} |
Signing secret whsec_… | التحقق من أن الإشعار المستلم أصلي | في جهاز الاستقبال الخاص بك؛ لا تستخدمه أبداً كـ API Bearer token |
قم بإنشاء Management Token من Dashboard → API → Management Tokens. الرموز مرتبطة بنطاق مساحة العمل: اختر نفس مساحة العمل الخاصة بـ API key التي ترسل المهام. لا يمكن للرمز قراءة أو تعديل نقاط نهاية مساحة عمل أخرى. يتم رفض API keys و Signing secrets بواسطة Management API. تستخدم تهيئة لوحة التحكم جلسة مسؤول مساحة العمل التي سجلت دخولك بها.
قم بتخزين mt-… و whsec_… في الواجهة الخلفية (backend) الخاصة بك. لا تقم بتضمينها في كود المتصفح، أو المطالبات (prompts)، أو ملفات المستودع، أو عناوين URL. تمنح Management Tokens أيضاً صلاحية إجراء عمليات إدارة أخرى لمساحة العمل؛ فهي ليست بيانات اعتماد مخصصة للـ webhooks فقط.
تهيئة نقطة نهاية
export TOKENLAB_MANAGEMENT_TOKEN="mt-your-management-token"
curl https://api.tokenlab.sh/v1/management/webhooks \
-H "Authorization: Bearer $TOKENLAB_MANAGEMENT_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"url":"https://your-app.example/webhooks/tokenlab","events":["task.completed","task.failed","task.timeout"],"description":"Production task results"}'تتضمن استجابة 201 كلاً من id و secret لمرة واحدة يبدأ بـ whsec_. قم بتخزين الـ secret قبل مغادرة هذه الخطوة. لا تكشف استجابات السرد/الجلب/التحديث عن هذا الـ secret أبداً. يمكن تهيئة ما يصل إلى 10 نقاط نهاية لكل مساحة عمل. يجب أن تستخدم عناوين URL بروتوكول HTTPS عاماً ولا يمكن أن تحتوي على بيانات اعتماد، أو سلاسل استعلام (query strings)، أو أجزاء (fragments). لا يتم اتباع عمليات إعادة التوجيه (Redirects).
| العملية | نقطة النهاية |
|---|---|
| سرد / إنشاء | GET / POST /v1/management/webhooks |
| جلب / تحديث / حذف | GET / PATCH / DELETE /v1/management/webhooks/{webhookId} |
| تدوير الـ signing secret | POST /v1/management/webhooks/{webhookId}/rotate-secret |
| إرسال اختبار | POST /v1/management/webhooks/{webhookId}/test |
| سجل التسليم | GET /v1/management/webhooks/{webhookId}/deliveries?page=1&limit=50 |
قم بالإيقاف المؤقت باستخدام PATCH {"is_active":false}؛ واستأنف العمل باستخدام PATCH {"is_active":true}. تؤدي الاستئناف إلى إعادة تعيين عداد الفشل المتتالي. تقوم عملية التدوير بإرجاع secret جديد لمرة واحدة؛ قم بتهيئته في جهاز الاستقبال الخاص بك على الفور. قد تحمل الطلبات التي لا تزال قيد التنفيذ التوقيع السابق، لذا اقبل كلا الـ secrets لفترة وجيزة أثناء التدوير. عملية التدوير غير قابلة للتراجع.
الأحداث والحمولات (Payloads)
تغطي الاشتراكات أحداث المهام غير المتزامنة النهائية المستقبلية؛ لا يتم إعادة تشغيل النتائج المتزامنة والمهام التاريخية. استقبل جميع مهام مساحة العمل لأنواع الأحداث المحددة وقم بمطابقة data.taskId مع المعرف الذي تم إرجاعه عند إنشاء المهمة. تستخدم حقول الاستدعاء (Callback) تنسيق camelCase؛ بينما تستخدم حقول استجابة الإدارة تنسيق snake_case.
{
"id": "event-unique-id",
"type": "task.completed",
"created": 1790000000,
"data": {
"taskType": "video",
"taskId": "ldtask_0123456789abcdef0123456789abcdef",
"model": "your-selected-model",
"durationMs": 42000,
"resultUrls": ["https://api.tokenlab.sh/v1/media-results/7c9e6679-7425-40de-944b-e07fc1f90ae7.mp4?token=…"],
"settledCost": 0.12
}
}| الحدث | البيانات |
|---|---|
task.completed | taskType, taskId, model (اختياري), durationMs, resultUrls, settledCost |
task.failed | taskType, taskId, error, errorCode, retryable, refundOutcome |
task.timeout | taskType, taskId, expectedTimeoutMs, actualWaitMs, refundIssued, resolutionSource, refundOutcome |
webhook.test | رسالة اختبار والاشتراكات المكونة؛ تُرسل فقط بواسطة عملية الاختبار |
كل عنصر في resultUrls هو رابط نتيجة وسائط من TokenLab يظل صالحاً لمدة 30 يوماً. راجع الاحتفاظ بالبيانات.
بالنسبة لـ task.timeout، فإن expectedTimeoutMs هو حد المهلة المكون، و actualWaitMs هو وقت الانتظار المنقضي، كلاهما بالمللي ثانية. تعني refundIssued: true أن استرداد الأموال قد نجح أو تم إصداره بالفعل؛ ولا يعني false استبعاد حدوث استرداد لاحق. يصف refundOutcome نتيجة معالجة استرداد الأموال. لا تحتوي أحداث المهلة على durationMs.
تعتمد الحقول على المهمة وقد تكون غائبة. استخدم GET /v1/tasks/{id} مع مفتاح sk-… الخاص بمساحة العمل الأصلية للحصول على النتيجة الموثوقة وحالة الفوترة. يصف حقل retryable الخاص بالحدث فشل الإنشاء؛ وهو ليس تعليمات للاستقصاء (poll) عن مهمة نهائية إلى أجل غير مسمى أو إرسال مهمة جديدة قابلة للفوترة تلقائياً. في task.failed، تكون error و errorCode و retryable هي error_details.message و code و retryable العامة للمهمة، وهي نفس القيم التي تُرجعها قراءة الحالة.
التحقق قبل المعالجة
يتضمن كل طلب POST كلاً من X-Webhook-ID و X-Webhook-Timestamp (بالثواني بنظام Unix) و X-Webhook-Signature (sha256=<hex>). قم بحساب HMAC-SHA256 عبر سلسلة الطابع الزمني الدقيقة، ونقطة، و بايتات نص الطلب الخام، باستخدام الـ secret الكامل whsec_…. لا تقم بتحليل وإعادة تسلسل JSON قبل التحقق.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWebhook(rawBody, headers, secrets) {
const timestamp = headers['x-webhook-timestamp'];
const signature = headers['x-webhook-signature'];
if (typeof timestamp !== 'string' || !/^\d+$/.test(timestamp)) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
if (typeof signature !== 'string' || !/^sha256=[a-f0-9]{64}$/.test(signature)) return false;
const received = Buffer.from(signature.slice(7), 'hex');
return secrets.some(secret => {
const expected = createHmac('sha256', secret).update(timestamp + '.').update(rawBody).digest();
return timingSafeEqual(expected, received);
});
}بعد التحقق، تأكد من أن id في نص الطلب يطابق X-Webhook-ID ، وقم بحفظ معرف الحدث مع عنصر العمل الخاص بك بشكل ذري (atomically)، وقم بإرجاع 2xx بسرعة. قم بمعالجة المهام الثقيلة من طابورك الخاص. قم بإلغاء التكرار (Deduplicate) حسب معرف الحدث داخل نقطة النهاية المستقبلة: قد تتكرر عمليات التسليم ولا نضمن الترتيب. يحد تفاوت الطابع الزمني لمدة خمس دقائق من عمر إعادة التشغيل؛ ويمنع إلغاء تكرار المعرف المعالجة المتكررة ضمن تلك النافذة.
عمليات إعادة المحاولة والاسترداد
تقوم كل دورة تسليم بإجراء ما يصل إلى ثلاث محاولات، مع انتظار ثانية واحدة ثم 4 ثوانٍ. كل محاولة HTTP لها مهلة 10 ثوانٍ وطابع زمني/توقيع جديد. فشل الشبكة، و 429، و 5xx هي حالات قابلة لإعادة المحاولة. تؤدي حالات 4xx الأخرى، وإعادة التوجيه، وأهداف الشبكة غير الصالحة إلى إيقاف تلك الدورة دون إعادة المحاولة. يمكن أن تؤدي الإخفاقات العابرة إلى إعادة محاولة الحدث لاحقاً بنفس معرف التسليم. تؤدي عشر دورات فاشلة متتالية إلى إيقاف نقطة النهاية مؤقتاً تلقائياً.
استخدم عملية الاختبار وسجل التسليم لرؤية outcome و http_status و attempts و delivered_at. استجابة API الاختبار الناجحة (200) تعني فقط أنه تم تسجيل المحاولة: تحقق من outcome == "delivered". قم بإصلاح جهاز الاستقبال، واستأنف نقطة النهاية، ثم أرسل اختباراً آخر. يحتوي السجل على بيانات وصفية للتسليم، وليس الحمولات؛ إعادة التشغيل اليدوية للأحداث القديمة غير متاحة. احتفظ بمعرفات المهام وقم بالمطابقة مع حالة المهمة إذا كان جهاز الاستقبال الخاص بك متوقفاً مؤقتاً أو غير متاح.
تهيئة MCP
أدوات إدارة الـ Webhook متاحة في ملف التعريف full. بيانات اعتماد الإدارة منفصلة عن مفتاح الاستدلال (inference key)؛ يمكن أن تعمل إدارة الكتالوج والـ webhook بدون مفتاح استدلال.
{
"mcpServers": {
"tokenlab": {
"command": "npx",
"args": ["-y", "@tokenlabai/mcp-server@latest"],
"env": {
"TOKENLAB_MCP_TOOL_PROFILE": "full",
"TOKENLAB_MANAGEMENT_TOKEN": "mt-your-management-token",
"TOKENLAB_API_KEY": "sk-your-inference-key"
}
}
}
}الأدوات: list_webhooks, create_webhook, get_webhook, update_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries. لا تقم أبداً بلصق بيانات الاعتماد في وسيطة أداة. امنح صلاحية الإدارة فقط لعملاء MCP الموثوق بهم.
الاستقصاء الاحتياطي (Polling fallback)
لا تزيل الـ Webhooks الوصول إلى الاستعلام عن الحالة أو تفرض حداً جديداً للاستقصاء. إذا كنت تستخدم الاستقصاء، فاستخدم poll_url الخاص باستجابة الإنشاء، وقم بالتراجع (back off) أثناء الحالة المعلقة، وتوقف عند الحالات النهائية. توقف عند 401 أو 403 أو 404 أو error.retryable == false؛ وأعد محاولة 503 async_task_owner_unavailable العابرة مع التراجع. تُرجع المهمة المفقودة أو منتهية الصلاحية 404 async_task_not_found. لا يمكن للاستعلام المتكرر عن مهمة مفقودة إعادة إنشائها.
يعتبر callback_url الخاص بـ Seedance compatibility API عقداً منفصلاً للاستدعاء لكل طلب. يمكن تعيينه عند إنشاء تلك المهمة؛ وهو لا يستخدم حمولات أحداث مساحة العمل هذه أو رؤوس HMAC.