Panduan inti
API manajemen Webhook
Konfigurasikan notifikasi tugas melalui Dashboard, API, atau MCP, verifikasi tanda tangan, dan selesaikan masalah pengiriman.
Webhook memberi tahu aplikasi Anda saat tugas asinkron selesai, gagal, atau habis waktu (timeout). Konfigurasikan webhook di Dashboard → API → Webhooks, melalui Management API, atau melalui profil full TokenLab MCP. Webhook berbagi endpoint ruang kerja (workspace) dan riwayat pengiriman yang sama.
Kredensial mana yang harus digunakan
| Kredensial | Tujuan | Di mana digunakan |
|---|---|---|
Management Token mt-… | Membuat, mencantumkan, memperbarui, menghapus, menguji, dan merotasi webhook | Authorization: Bearer mt-… pada /v1/management/webhooks* |
API key sk-… | Mengirim permintaan model dan menanyakan status tugas | API Model dan /v1/tasks/{id} |
Signing secret whsec_… | Memverifikasi bahwa notifikasi yang diterima adalah autentik | Penerima Anda; jangan pernah menggunakannya sebagai token Bearer API |
Buat Management Token di Dashboard → API → Management Tokens. Token memiliki cakupan ruang kerja: pilih ruang kerja yang sama dengan API key yang mengirimkan tugas. Token tidak dapat membaca atau memodifikasi endpoint ruang kerja lain. API key dan signing secret akan ditolak oleh Management API. Konfigurasi dashboard menggunakan sesi admin ruang kerja Anda yang sedang masuk.
Simpan mt-… dan whsec_… di backend Anda. Jangan sematkan di kode peramban, prompt, file repositori, atau URL. Management Token juga mengotorisasi operasi manajemen ruang kerja lainnya; token ini bukan kredensial khusus webhook.
Mengonfigurasi endpoint
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"}'Respons 201 menyertakan id dan secret sekali pakai yang dimulai dengan whsec_. Simpan secret tersebut sebelum meninggalkan langkah ini. Respons daftar/get/update tidak akan pernah mengungkapkannya. Hingga 10 endpoint dapat dikonfigurasi per ruang kerja. URL harus menggunakan HTTPS publik dan tidak boleh berisi kredensial, query string, atau fragmen. Pengalihan (redirect) tidak diikuti.
| Operasi | Endpoint |
|---|---|
| List / Create | GET / POST /v1/management/webhooks |
| Get / Update / Delete | GET / PATCH / DELETE /v1/management/webhooks/{webhookId} |
| Rotate signing secret | POST /v1/management/webhooks/{webhookId}/rotate-secret |
| Send test | POST /v1/management/webhooks/{webhookId}/test |
| Delivery history | GET /v1/management/webhooks/{webhookId}/deliveries?page=1&limit=50 |
Jeda dengan PATCH {"is_active":false}; lanjutkan dengan PATCH {"is_active":true}. Melanjutkan akan mereset jumlah kegagalan berturut-turut. Rotasi mengembalikan secret baru satu kali; konfigurasikan pada penerima Anda segera. Permintaan yang sudah dalam proses mungkin masih membawa tanda tangan sebelumnya, jadi terimalah kedua secret secara singkat selama rotasi. Rotasi tidak dapat dibatalkan.
Event dan payload
Langganan mencakup event tugas asinkron terminal di masa mendatang; hasil sinkron dan tugas historis tidak diputar ulang. Terima semua tugas ruang kerja untuk jenis event yang dipilih dan cocokkan data.taskId dengan ID yang dikembalikan saat Anda membuat tugas. Bidang callback menggunakan camelCase; bidang respons manajemen menggunakan 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
}
}| Event | Data |
|---|---|
task.completed | taskType, taskId, opsional model, durationMs, resultUrls, settledCost |
task.failed | taskType, taskId, error, errorCode, retryable, refundOutcome |
task.timeout | taskType, taskId, expectedTimeoutMs, actualWaitMs, refundIssued, resolutionSource, refundOutcome |
webhook.test | Pesan uji dan langganan yang dikonfigurasi; dikirim hanya oleh operasi uji |
Setiap entri resultUrls adalah URL hasil media TokenLab yang berlaku selama 30 hari. Lihat Retensi data.
Untuk task.timeout, expectedTimeoutMs adalah ambang batas timeout yang dikonfigurasi dan actualWaitMs adalah waktu tunggu yang telah berlalu, keduanya dalam milidetik. refundIssued: true berarti pengembalian dana berhasil atau sudah diterbitkan; false tidak menutup kemungkinan pengembalian dana di kemudian hari. refundOutcome menjelaskan hasil pemrosesan pengembalian dana. Event timeout tidak berisi durationMs.
Bidang bergantung pada tugas dan bisa saja tidak ada. Gunakan GET /v1/tasks/{id} dengan kunci sk-… ruang kerja asli untuk hasil otoritatif dan status penagihan. retryable pada event menjelaskan kegagalan pembuatan; ini bukan instruksi untuk melakukan polling pada tugas terminal tanpa batas atau mengirimkan tugas baru yang dapat ditagih secara otomatis. Dalam task.failed, error, errorCode, dan retryable adalah error_details.message, code, dan retryable publik dari tugas tersebut, nilai yang sama dengan yang dikembalikan oleh pembacaan status.
Verifikasi sebelum pemrosesan
Setiap POST menyertakan X-Webhook-ID, X-Webhook-Timestamp (detik Unix), dan X-Webhook-Signature (sha256=<hex>). Hitung HMAC-SHA256 atas string timestamp yang tepat, titik, dan byte badan permintaan mentah, menggunakan secret whsec_… yang lengkap. Jangan mengurai dan menyerialisasi ulang JSON sebelum verifikasi.
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);
});
}Setelah verifikasi, periksa apakah id badan cocok dengan X-Webhook-ID, simpan ID event dengan item kerja Anda secara atomik, dan kembalikan 2xx dengan cepat. Proses pekerjaan berat dari antrean Anda sendiri. Lakukan deduplikasi berdasarkan ID event dalam endpoint penerima: pengiriman dapat berulang dan urutan tidak dijamin. Toleransi timestamp lima menit membatasi usia pemutaran ulang; deduplikasi ID mencegah pemrosesan berulang dalam jendela tersebut.
Percobaan ulang dan pemulihan
Setiap siklus pengiriman melakukan hingga tiga kali percobaan, menunggu 1 detik lalu 4 detik. Setiap percobaan HTTP memiliki timeout 10 detik dan timestamp/signature baru. Kegagalan jaringan, 429, dan 5xx dapat dicoba ulang. 4xx lainnya, pengalihan, dan target jaringan yang tidak valid akan menghentikan siklus tersebut tanpa mencoba ulang. Kegagalan sementara dapat memicu percobaan ulang event di kemudian hari dengan ID pengiriman yang sama. Sepuluh siklus gagal berturut-turut akan menjeda endpoint secara otomatis.
Gunakan operasi uji dan riwayat pengiriman untuk melihat outcome, http_status, attempts, dan delivered_at. Respons API uji yang berhasil (200) hanya berarti percobaan telah dicatat: periksa outcome == "delivered". Perbaiki penerima, lanjutkan endpoint, lalu kirim uji coba lagi. Riwayat berisi metadata pengiriman, bukan payload; pemutaran ulang manual event lama tidak tersedia. Simpan ID tugas dan rekonsiliasi dengan status tugas jika penerima Anda dijeda atau tidak tersedia.
Konfigurasi MCP
Alat manajemen webhook tersedia di profil full. Kredensial manajemen terpisah dari kunci inferensi; manajemen katalog dan webhook dapat berfungsi tanpa kunci inferensi.
{
"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"
}
}
}
}Alat: list_webhooks, create_webhook, get_webhook, update_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries. Jangan pernah menempelkan kredensial ke dalam argumen alat. Berikan akses manajemen hanya kepada klien MCP tepercaya.
Cadangan Polling
Webhook tidak menghapus akses kueri status atau memaksakan batas polling baru. Jika Anda melakukan polling, gunakan poll_url dari respons pembuatan, lakukan back off saat tertunda, dan berhenti pada status terminal. Berhenti pada 401, 403, 404, atau error.retryable == false; coba ulang 503 async_task_owner_unavailable sementara dengan backoff. Tugas yang hilang atau kedaluwarsa mengembalikan 404 async_task_not_found. Menanyakan tugas yang hilang berulang kali tidak dapat membuatnya kembali.
Seedance compatibility API's callback_url adalah kontrak callback per permintaan yang terpisah. Ini dapat diatur saat membuat tugas tersebut; ini tidak menggunakan payload event ruang kerja atau header HMAC ini.