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.
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/transcript1Nhậ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.
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.
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.