Webhooks
Nhận thông báo theo thời gian thực khi có sự kiện xảy ra trong tài khoản AgentSend của bạn — email mới đến, xác nhận giao hàng, phát hiện bounce, và nhiều hơn nữa.
Tổng Quan
Thay vì polling API để kiểm tra tin nhắn mới, webhooks cho phép AgentSend đẩy dữ liệu sự kiện đến máy chủ của bạn ngay khi có việc xảy ra. Đăng ký một endpoint HTTPS và AgentSend sẽ gửi yêu cầu POST với payload JSON mỗi khi sự kiện đã đăng ký được kích hoạt.
Webhooks là cách được khuyến nghị để xây dựng các agent phản ứng. Khi một phản hồi đến hộp thư của agent, ứng dụng của bạn nhận toàn bộ payload tin nhắn trong vài giây và có thể xử lý ngay lập tức.
Endpoint webhook phải truy cập được công khai qua HTTPS. URL localhost không được chấp nhận. Sử dụng công cụ như ngrok hoặc dịch vụ tunnel khi phát triển cục bộ.
Tạo Webhook
Đăng ký webhook mới bằng cách gửi yêu cầu POST đến /webhooks. Bạn phải cung cấp trường url; tất cả trường khác là tùy chọn.
/webhooks
| Tham số | Kiểu | Mô tả |
|---|---|---|
url bắt buộc |
string | URL HTTPS mà AgentSend sẽ POST sự kiện đến. |
description |
string | Nhãn dễ đọc để nhận dạng webhook trong bảng điều khiển. |
events |
string[] | Danh sách các loại sự kiện để đăng ký. Bỏ qua để nhận mọi sự kiện. |
const res = await fetch("https://api.agentsend.io/webhooks", { method: "POST", headers: { "x-api-key": process.env.AGENTSEND_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://myapp.example.com/hooks/agentsend", description: "Production inbox events", events: ["message.received", "message.bounced"], }), }); const webhook = await res.json(); console.log(webhook.id); // wh_01j9... console.log(webhook.secret); // whsec_... lưu an toàn!
secret được trả về chỉ một lần trong phản hồi tạo. Lưu nó vào biến môi trường an toàn ngay lập tức — không thể lấy lại được, nhưng bạn có thể xoay nó qua PUT /webhooks/{id}.
Các Loại Sự Kiện
Đăng ký các sự kiện cụ thể bằng cách truyền định danh của chúng trong mảng events. Nếu bỏ qua mảng, AgentSend sẽ giao tất cả loại sự kiện đến endpoint của bạn.
| Sự kiện | Mô tả |
|---|---|
domain.verified |
Một tên miền tùy chỉnh đã vượt qua xác minh DNS và sẵn sàng sử dụng. |
message.received |
Một email đến đã đến một trong các hộp thư agent của bạn. |
message.sent |
Một tin nhắn gửi đi đã được chấp nhận và xếp hàng để giao. |
message.delivered |
Máy chủ email của người nhận xác nhận giao thành công. |
message.bounced |
Tin nhắn không thể được giao (hard hoặc soft bounce). |
message.complained |
Người nhận đã đánh dấu tin nhắn là spam qua email client của họ. |
Payload Webhook
Mỗi lần giao webhook là một yêu cầu POST với body Content-Type: application/json. Payload có cấu trúc nhất quán bất kể loại sự kiện.
{
"id": "evt_01j9xkq7z8abc",
"type": "message.received",
"createdAt": "2026-04-16T10:23:45.000Z",
"webhookId": "wh_01j9abc123",
"data": {
"id": "msg_01j9xkp4n5def",
"inboxId": "inbox_01j8mq3r2t",
"threadId": "thr_01j9xkp4m1ghi",
"fromAddress": "alice@example.com",
"fromName": "Alice Chen",
"toAddresses": ["a1b2c3@agentsend.io"],
"subject": "Re: Your proposal",
"bodyText": "Looks great, let's move forward.",
"bodyHtml": "<p>Looks great, let's move forward.</p>",
"hasAttachments": false,
"receivedAt": "2026-04-16T10:23:44.812Z"
}
}Xác Minh Chữ Ký
Mỗi yêu cầu webhook bao gồm header X-AgentSend-Signature. Đây là hash HMAC-SHA256 của body yêu cầu thô, được ký với secret của webhook. Luôn xác minh chữ ký này trước khi xử lý giao hàng để bảo vệ khỏi các yêu cầu giả mạo.
import crypto from "node:crypto"; app.post("/hooks/agentsend", express.raw({ type: "application/json" }), (req, res) => { const sig = req.headers["x-agentsend-signature"]; const secret = process.env.AGENTSEND_WEBHOOK_SECRET; const expected = crypto .createHmac("sha256", secret) .update(req.body) // Buffer thô — KHÔNG parse JSON trước .digest("hex"); if (!crypto.timingSafeEqual( Buffer.from(sig), Buffer.from(expected) )) { return res.status(401).send("Invalid signature"); } const event = JSON.parse(req.body); // xử lý event.type … res.sendStatus(200); });
import hmac, hashlib, os from flask import Flask, request, abort app = Flask(__name__) @app.route("/hooks/agentsend", methods=["POST"]) def webhook(): sig = request.headers.get("X-AgentSend-Signature", "") secret = os.environ["AGENTSEND_WEBHOOK_SECRET"].encode() expected = hmac.new(secret, request.data, hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): abort(401) event = request.get_json() # xử lý event["type"] … return "", 200
Luôn dùng phép so sánh thời gian hằng số (ví dụ crypto.timingSafeEqual hoặc hmac.compare_digest) khi kiểm tra chữ ký để ngăn chặn tấn công thời gian.
Chính Sách Thử Lại
AgentSend coi giao hàng thành công khi endpoint của bạn phản hồi với bất kỳ mã trạng thái HTTP 2xx nào trong vòng 10 giây. Nếu yêu cầu hết thời gian hoặc trả về phản hồi không phải 2xx, việc giao hàng sẽ được thử lại với exponential back-off:
| Lần thử | Thời gian chờ sau lần trước |
|---|---|
| Thử lại lần 1 | 5 giây |
| Thử lại lần 2 | 30 giây |
| Thử lại lần 3 | 5 phút |
| Thử lại lần 4 | 30 phút |
| Thử lại lần 5 | 2 giờ |
Sau 5 lần thử lại thất bại (tổng 6 lần) việc giao hàng được đánh dấu là thất bại và không có thêm lần thử nào. Bạn có thể kiểm tra các lần giao thất bại trong nhật ký giao hàng và phát lại thủ công từ bảng điều khiển.
Phản hồi với 200 OK càng nhanh càng tốt. Nếu logic xử lý của bạn mất thời gian, chấp nhận payload ngay lập tức và xử lý bất đồng bộ với queue hoặc job nền.
Quản Lý Webhooks
API webhooks cho phép bạn liệt kê, cập nhật, và xóa các endpoint đã đăng ký.
Liệt kê webhooks
Trả về tất cả webhooks đã đăng ký trong tài khoản của bạn.
# GET /webhooks curl https://api.agentsend.io/webhooks \ -H "x-api-key: $AGENTSEND_API_KEY"
Cập nhật webhook
Thay đổi URL, mô tả, hoặc các loại sự kiện đã đăng ký. Bạn cũng có thể xoay secret ký bằng cách truyền "rotateSecret": true — phản hồi sẽ bao gồm secret mới.
# PUT /webhooks/{id} curl -X PUT https://api.agentsend.io/webhooks/wh_01j9abc123 \ -H "x-api-key: $AGENTSEND_API_KEY" \ -H "Content-Type: application/json" \ -d '{"events": ["message.received", "message.delivered", "message.bounced"]}'
Xóa webhook
Xóa webhook vĩnh viễn. Các giao hàng đang diễn ra vẫn được thực hiện trước khi việc xóa có hiệu lực.
# DELETE /webhooks/{id} curl -X DELETE https://api.agentsend.io/webhooks/wh_01j9abc123 \ -H "x-api-key: $AGENTSEND_API_KEY"
Theo dõi hoạt động
Nhận tóm tắt về khối lượng sự kiện gần đây và tỷ lệ lỗi cho một webhook cụ thể.
# GET /webhooks/activity curl "https://api.agentsend.io/webhooks/activity?webhookId=wh_01j9abc123" \ -H "x-api-key: $AGENTSEND_API_KEY"
Nhật Ký Giao Hàng
Mỗi lần giao hàng đều được ghi lại. Truy vấn endpoint nhật ký để kiểm tra toàn bộ lịch sử của một webhook, bao gồm mã phản hồi HTTP, body phản hồi, và thời gian.
GET/webhooks/logs
| Tham số truy vấn | Kiểu | Mô tả |
|---|---|---|
webhookId |
string | Lọc nhật ký cho một webhook cụ thể. |
status |
string | success, failed, hoặc pending. |
limit |
number | Số lượng bản ghi trả về (mặc định 50, tối đa 200). |
before |
string | Con trỏ phân trang; truyền id của bản ghi cuối cùng đã xem. |
# Lấy các lần giao thất bại cho một webhook curl "https://api.agentsend.io/webhooks/logs?webhookId=wh_01j9abc123&status=failed" \ -H "x-api-key: $AGENTSEND_API_KEY"
Mỗi bản ghi nhật ký bao gồm:
- id — ID duy nhất của lần giao hàng.
- eventId — ID của sự kiện gốc.
- eventType — ví dụ
message.received. - status —
success,failed, hoặcpending. - httpStatus — Mã phản hồi HTTP do endpoint của bạn trả về.
- durationMs — Thời gian khứ hồi tính bằng mili giây.
- attempt — Đây là lần thử nào (1 = lần giao đầu tiên).
- createdAt — Dấu thời gian của lần thử.