Webhook phiên âm báo khi job hoàn tất hoặc thất bại

Webhook phiên âm giúp ứng dụng chờ thông báo thay vì liên tục gọi API hỏi trạng thái. Thêm webhook_url khi tạo job; transcript1 gửi POST có chữ ký khi xử lý hoàn tất hoặc thất bại. Khi nhận sự kiện hoàn tất, bạn lấy transcript bằng id.

  • transcription.completed và transcription.failed
  • Mỗi lần gửi đều có chữ ký HMAC-SHA256
  • Tối đa 6 lần gửi, tăng dần thời gian chờ

Nhận sự kiện trước, lấy nội dung sau

Hai sự kiện cần xử lý
transcription.completed báo đã có transcript; transcription.failed báo xử lý thất bại. Nếu bạn hủy job, không có webhook.
Kiểm tra ai gửi request
Header X-Transcript1-Signature có timestamp và chữ ký HMAC-SHA256 của raw body, dùng secret whsec_ của team.
Có gửi lại khi chưa nhận được
Phản hồi 2xx xác nhận đã nhận. Nếu không, hệ thống chờ lần lượt 2, 4, 8, 16, 32 phút rồi gửi lại, tối đa 6 lần tính cả lần đầu.
Endpoint phải công khai và dùng HTTPS
Địa chỉ được kiểm tra khi tạo job và trước mỗi lần gửi. Không dùng localhost hoặc URL chuyển hướng.
Payload không chứa toàn bộ transcript
Sự kiện gửi đối tượng transcription không kèm nội dung transcript. Dùng id để lấy văn bản ở định dạng ứng dụng cần.

Thêm webhook_url ngay trong request

Bạn dùng webhook_url khi gửi link, tạo upload từng phần hoặc làm form field khi tải file một lần. Không ghép với reuse_recent. Xem tham số webhook trước khi tích hợp.

Webhook phù hợp với các việc chạy nền như xử lý phỏng vấn, lập kho podcast hoặc lấy transcript từ danh sách video. Lưu id của transcription cùng job trong hệ thống của bạn để callback về đúng lần thao tác của người dùng.

Dùng URL HTTPS công khai cuối cùng, không qua chuyển hướng. localhost không nhận được webhook. Ví dụ bên dưới dùng file tải lên để bạn thử toàn bộ luồng bằng một bản ghi mình có quyền sử dụng.

Tải file và đăng ký nhận webhook
curl -X POST "https://api.transcript1.com/v1/transcriptions" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F [email protected] \
  -F webhook_url=https://example.com/hooks/transcript1

Nhận lại cùng sự kiện cũng chỉ xử lý một lần

data chứa đối tượng transcription nhưng không chứa transcript. Ghép data.id với type để nhận biết bản gửi trùng, rồi lấy transcript qua API bằng id.

Một sự kiện có thể tới nhiều lần. Handler đã làm xong nhưng trả lời sau giới hạn 10 giây thì hệ thống vẫn có thể gửi lại. Sau khi kiểm tra chữ ký, lưu sự kiện hoặc đưa vào hàng đợi bền vững rồi trả 2xx sớm. Lưu khóa chống trùng trước khi đăng nội dung hay thông báo cho người dùng.

Tác vụ chạy nền dùng data.id để lấy transcript. Với transcription.failed, đọc data.error và cập nhật trạng thái job của bạn. Nếu hủy job, code xử lý hủy phải tự cập nhật trạng thái vì sẽ không có callback.

POST gửi đến URL của bạn
X-Transcript1-Signature: t=<unix seconds>,v1=<hex digest>

{
  "type": "transcription.completed",
  "created_at": "2026-10-13T09:30:04.000Z",
  "data": {
    "id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
    "object": "transcription",
    "status": "completed",
    "transcript_source": "speech_to_text",
    "billed_minutes": 4,
    "error": null
  }
}

Xác minh chữ ký webhook HMAC trước khi đọc JSON

Tính HMAC-SHA256 cho chuỗi t + dấu chấm + raw body bằng secret whsec_ của team. So sánh trong thời gian cố định và từ chối timestamp quá xa hiện tại. Hướng dẫn xác minh có ví dụ đầy đủ.

Đọc body nguyên trạng trước khi JSON parser xử lý. Parse rồi ghép JSON lại có thể đổi khoảng trắng hoặc thứ tự key, làm chữ ký không còn khớp. Kiểm tra header, timestamp và độ dài digest; chỉ parse nội dung sau khi chữ ký hợp lệ.

Đoạn Node.js dưới đây giả định t và v1 đã được tách và kiểm tra. Tài liệu có ví dụ đầy đủ cho Node.js và Python với độ lệch timestamp tối đa 5 phút. Dùng toàn bộ secret, gồm cả tiền tố whsec_. Đổi secret của team sẽ áp dụng ngay cho những lần gửi tiếp theo.

Node.js
const expected = crypto
  .createHmac('sha256', secret)
  .update(`${t}.${rawBody}`)
  .digest('hex');
const valid = v1.length === expected.length
  && crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));

Thử cả sự kiện lỗi và sự kiện trùng

Kiểm tra handler với job hoàn tất, job thất bại và cùng sự kiện gửi lại. Một job hoàn tất không được làm nội dung xuất bản hai lần. Job thất bại không được đi vào luồng lấy và đăng transcript khi chưa có văn bản.

Tách lỗi chữ ký khỏi lỗi xử lý ứng dụng. Mỗi lần gửi chỉ chờ 10 giây, nên đừng đợi lập chỉ mục hay gọi mô hình AI xong mới phản hồi. Hàng đợi của bạn cần tự thử lại các bước phía sau; lịch gửi lại webhook không thay thế việc đó.

Phản hồi không phải 2xx, lỗi kết nối hoặc timeout đều dẫn đến gửi lại sau 2, 4, 8, 16, 32 phút, tổng cộng tối đa 6 lần. Hệ thống không đi theo chuyển hướng. Ghi log id, loại sự kiện và tình trạng nhận; không ghi signing secret.

Nếu đã hết lượt gửi, đọc lại job qua API để đối chiếu trạng thái. Vì vậy, phải lưu id ngay từ lúc tạo; đừng chỉ dựa vào callback để biết một job có tồn tại hay không.

Dùng thử với 60 phút miễn phí

Xác minh email để nhận 60 phút miễn phí một lần. Không cần thẻ.

Lấy khóa API

Câu hỏi thường gặp

Bạn cần hỏi thêm? Gửi câu hỏi cho chúng tôi

Tôi lấy signing secret ở đâu?

Mở trang “Webhooks” trong bảng điều khiển. Secret bắt đầu bằng whsec_, dùng chung cho team và có thể đổi tại đó bất cứ lúc nào.

Webhook gửi không thành công thì sao?

Hệ thống tăng dần thời gian chờ và thử tối đa 6 lần trong khoảng một giờ, tính cả lần đầu. Mỗi lần chờ tối đa 10 giây và không đi theo URL chuyển hướng.

Tôi dùng webhook qua MCP được không?

Không. Webhook chỉ có trong REST API. Công cụ MCP chờ xử lý trong thời gian giới hạn hoặc trả id để đọc lại sau.