TokenLab

Hướng dẫn cốt lõi

API quản lý Webhook

Cấu hình thông báo tác vụ thông qua Dashboard, API hoặc MCP, xác minh chữ ký và khắc phục sự cố gửi thông báo.

Webhook thông báo cho ứng dụng của bạn khi một tác vụ bất đồng bộ hoàn tất, thất bại hoặc hết thời gian chờ. Hãy cấu hình chúng trong Dashboard → API → Webhooks, thông qua Management API hoặc thông qua profile full của TokenLab MCP. Chúng chia sẻ chung các endpoint của workspace và lịch sử gửi thông báo.

Sử dụng thông tin xác thực nào

Thông tin xác thựcMục đíchNơi sử dụng
Management Token mt-…Tạo, liệt kê, cập nhật, xóa, kiểm tra và xoay vòng webhookAuthorization: Bearer mt-… trên /v1/management/webhooks*
API key sk-…Gửi yêu cầu mô hình và truy vấn trạng thái tác vụCác API mô hình và /v1/tasks/{id}
Signing secret whsec_…Xác minh thông báo nhận được là xác thựcReceiver của bạn; không bao giờ sử dụng làm API Bearer token

Tạo Management Token tại Dashboard → API → Management Tokens. Token được giới hạn trong phạm vi workspace: hãy chọn cùng một workspace với API key dùng để gửi tác vụ. Một token không thể đọc hoặc sửa đổi các endpoint của workspace khác. API key và signing secret sẽ bị Management API từ chối. Cấu hình trên Dashboard sử dụng phiên quản trị viên workspace đã đăng nhập của bạn.

Lưu trữ mt-… và whsec_… trên backend của bạn. Không nhúng chúng vào mã nguồn trình duyệt, các prompt, tệp trong repository hoặc URL. Management Token cũng cho phép thực hiện các thao tác quản lý workspace khác; chúng không phải là thông tin xác thực chỉ dành riêng cho webhook.

Cấu hình một 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"}'

Phản hồi 201 bao gồm id và một secret dùng một lần bắt đầu bằng whsec_. Hãy lưu trữ secret này trước khi rời khỏi bước này. Các phản hồi liệt kê/lấy thông tin/cập nhật sẽ không bao giờ hiển thị secret này. Có thể cấu hình tối đa 10 endpoint cho mỗi workspace. URL phải sử dụng HTTPS công khai và không được chứa thông tin xác thực, chuỗi truy vấn hoặc fragment. Các lệnh chuyển hướng (redirect) sẽ không được theo sau.

Thao tácEndpoint
Liệt kê / TạoGET / POST /v1/management/webhooks
Lấy thông tin / Cập nhật / XóaGET / PATCH / DELETE /v1/management/webhooks/{webhookId}
Xoay vòng signing secretPOST /v1/management/webhooks/{webhookId}/rotate-secret
Gửi kiểm traPOST /v1/management/webhooks/{webhookId}/test
Lịch sử gửi thông báoGET /v1/management/webhooks/{webhookId}/deliveries?page=1&limit=50

Tạm dừng với PATCH {"is_active":false}; tiếp tục với PATCH {"is_active":true}. Việc tiếp tục sẽ đặt lại số lần thất bại liên tiếp. Thao tác xoay vòng sẽ trả về một secret mới một lần duy nhất; hãy cấu hình nó trên receiver của bạn ngay lập tức. Các yêu cầu đang được xử lý có thể vẫn mang chữ ký cũ, vì vậy hãy chấp nhận cả hai secret trong thời gian ngắn trong quá trình xoay vòng. Việc xoay vòng không thể đảo ngược.

Sự kiện và payload

Các gói đăng ký bao gồm các sự kiện tác vụ bất đồng bộ kết thúc trong tương lai; các kết quả đồng bộ và tác vụ lịch sử sẽ không được phát lại. Nhận tất cả các tác vụ workspace cho các loại sự kiện đã chọn và khớp data.taskId với ID được trả về khi bạn tạo tác vụ. Các trường callback sử dụng camelCase; các trường phản hồi quản lý sử dụng 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
  }
}
Sự kiệnDữ liệu
task.completedtaskType, taskId, model (tùy chọn), durationMs, resultUrls, settledCost
task.failedtaskType, taskId, error, errorCode, retryable, refundOutcome
task.timeouttaskType, taskId, expectedTimeoutMs, actualWaitMs, refundIssued, resolutionSource, refundOutcome
webhook.testThông báo kiểm tra và các đăng ký đã cấu hình; chỉ được gửi bởi thao tác kiểm tra

Mỗi mục trong resultUrls là một URL kết quả phương tiện của TokenLab, có hiệu lực trong 30 ngày. Xem Lưu giữ dữ liệu.

Đối với task.timeout, expectedTimeoutMs là ngưỡng thời gian chờ đã cấu hình và actualWaitMs là thời gian chờ thực tế, cả hai đều tính bằng mili giây. refundIssued: true có nghĩa là việc hoàn tiền đã thành công hoặc đã được thực hiện trước đó; false không loại trừ khả năng hoàn tiền sau này. refundOutcome mô tả kết quả xử lý hoàn tiền. Các sự kiện timeout không chứa durationMs.

Các trường phụ thuộc vào tác vụ và có thể không có. Sử dụng GET /v1/tasks/{id} với key sk-… của workspace gốc để có kết quả xác thực và trạng thái thanh toán. Trường retryable của một sự kiện mô tả lỗi tạo tác vụ; đây không phải là hướng dẫn để thăm dò (poll) một tác vụ đã kết thúc vô thời hạn hoặc tự động gửi một tác vụ tính phí mới. Trong task.failed, error, errorCode và retryable là các giá trị error_details.message, code và retryable công khai của tác vụ, giống với các giá trị mà việc đọc trạng thái trả về.

Xác minh trước khi xử lý

Mỗi yêu cầu POST bao gồm X-Webhook-ID, X-Webhook-Timestamp (giây Unix) và X-Webhook-Signature (sha256=<hex>). Tính toán HMAC-SHA256 dựa trên chuỗi timestamp chính xác, một dấu chấm và byte nội dung yêu cầu thô (raw request body bytes), sử dụng secret whsec_… đầy đủ. Không phân tích cú pháp và chuyển đổi lại JSON trước khi xác minh.

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);
  });
}

Sau khi xác minh, hãy kiểm tra xem id trong body có khớp với X-Webhook-ID không, lưu ID sự kiện cùng với mục công việc của bạn một cách nguyên tử (atomically) và trả về 2xx nhanh chóng. Xử lý các công việc nặng từ hàng đợi của riêng bạn. Khử trùng lặp (deduplicate) theo ID sự kiện trong endpoint nhận: việc gửi thông báo có thể lặp lại và thứ tự không được đảm bảo. Dung sai timestamp năm phút giới hạn độ tuổi của yêu cầu phát lại; việc khử trùng lặp ID ngăn chặn việc xử lý lặp lại trong khoảng thời gian đó.

Thử lại và khôi phục

Mỗi chu kỳ gửi thực hiện tối đa ba lần thử, đợi 1 giây rồi 4 giây. Mỗi lần thử HTTP có thời gian chờ 10 giây và timestamp/chữ ký mới. Các lỗi mạng, 429 và 5xx có thể thử lại. Các lỗi 4xx khác, lệnh chuyển hướng và mục tiêu mạng không hợp lệ sẽ dừng chu kỳ đó mà không thử lại. Các lỗi tạm thời có thể kích hoạt việc thử lại sự kiện sau đó với cùng ID gửi. Mười chu kỳ thất bại liên tiếp sẽ tự động tạm dừng endpoint.

Sử dụng thao tác kiểm tra và lịch sử gửi để xem outcome, http_status, attempts và delivered_at. Phản hồi API kiểm tra thành công (200) chỉ có nghĩa là lần thử đã được ghi lại: hãy kiểm tra outcome == "delivered". Sửa receiver, tiếp tục endpoint, sau đó gửi một lần kiểm tra khác. Lịch sử chứa metadata gửi, không chứa payload; việc phát lại thủ công các sự kiện cũ không khả dụng. Hãy giữ lại các ID tác vụ và đối chiếu với trạng thái tác vụ nếu receiver của bạn bị tạm dừng hoặc không khả dụng.

Cấu hình MCP

Các công cụ quản lý webhook có sẵn trong profile full. Thông tin xác thực quản lý tách biệt với key suy luận (inference key); việc quản lý danh mục và webhook có thể hoạt động mà không cần key suy luận.

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

Các công cụ: list_webhooks, create_webhook, get_webhook, update_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries. Không bao giờ dán thông tin xác thực vào đối số của công cụ. Chỉ cấp quyền quản lý cho các client MCP đáng tin cậy.

Dự phòng thăm dò (Polling)

Webhook không loại bỏ quyền truy cập truy vấn trạng thái hoặc áp đặt giới hạn thăm dò mới. Nếu bạn thăm dò, hãy sử dụng poll_url trong phản hồi tạo tác vụ, thực hiện back-off khi ở trạng thái pending và dừng lại ở các trạng thái kết thúc. Dừng lại khi gặp 401, 403, 404 hoặc error.retryable == false; thử lại lỗi tạm thời 503 async_task_owner_unavailable với back-off. Tác vụ bị thiếu hoặc hết hạn sẽ trả về 404 async_task_not_found. Việc truy vấn liên tục một tác vụ bị thiếu không thể tạo lại nó.

Callback_url của API tương thích Seedance là một hợp đồng callback riêng biệt cho mỗi yêu cầu. Nó có thể được thiết lập khi tạo tác vụ đó; nó không sử dụng các payload sự kiện workspace hoặc header HMAC này.

Trên trang này