Webhooks
Register HTTP endpoints to receive real-time event notifications. Inspect delivery logs and monitor activity across your webhook subscriptions.
All requests require the x-api-key header. The base URL for every endpoint is https://api.agentsend.io.
The Webhook Object
Every endpoint that returns a webhook returns this shape. The secret field is only included in the response to POST /webhooks — store it securely, as it cannot be retrieved again.
{
"id": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"url": "https://your-app.com/webhooks/agentsend",
"description": "Production inbound handler",
"events": ["message.received", "message.bounced"],
"isActive": true,
"createdAt": "2026-04-16T10:00:00.000Z",
"updatedAt": "2026-04-16T10:00:00.000Z"
}| Field | Type | Description |
|---|---|---|
id | string (uuid) | Unique webhook identifier. |
url | string (uri) | The HTTPS endpoint AgentSend delivers events to. |
description | string | null | Optional human-readable label for the webhook. |
events | string[] | null | Array of subscribed event types. null or an empty array means all events are delivered. |
isActive | boolean | Whether the webhook is currently receiving events. |
createdAt | string (ISO 8601) | When the webhook was created. |
updatedAt | string (ISO 8601) | When the webhook was last updated. |
Create a Webhook
Register a new webhook endpoint. Returns 201 Created with the Webhook object plus a secret field. Use the secret to verify webhook signatures — it is only returned once and cannot be retrieved later.
Request Body
| Parameter | Type | Description |
|---|---|---|
url requis |
string (uri) | The HTTPS URL AgentSend will POST events to. Must be a valid URI starting with https://. |
description |
string | A human-readable label to identify this webhook in the dashboard and logs. |
events |
string[] | List of event types to subscribe to. Omit or pass an empty array to receive all events. Valid values: domain.verified, message.received, message.sent, message.delivered, message.bounced, message.complained. |
Request Example
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://your-app.com/webhooks/agentsend", description: "Production inbound handler", events: ["message.received", "message.bounced"], }), }); const webhook = await res.json(); console.log(webhook.secret); // Save this — it won't be shown again
Response — 201 Created
{
"id": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"url": "https://your-app.com/webhooks/agentsend",
"description": "Production inbound handler",
"events": ["message.received", "message.bounced"],
"isActive": true,
"secret": "whsec_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"createdAt": "2026-04-16T10:00:00.000Z",
"updatedAt": "2026-04-16T10:00:00.000Z"
}The secret is only returned on creation. Store it in a secure environment variable immediately — you cannot retrieve it again via the API.
List Webhooks
Returns all webhooks registered for your account. Secrets are never included in list or get responses.
Request Example
const res = await fetch("https://api.agentsend.io/webhooks", { headers: { "x-api-key": process.env.AGENTSEND_API_KEY }, }); const { data } = await res.json(); console.log(`${data.length} webhooks registered`);
Response — 200 OK
{
"data": [
{
"id": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"url": "https://your-app.com/webhooks/agentsend",
"description": "Production inbound handler",
"events": ["message.received", "message.bounced"],
"isActive": true,
"createdAt": "2026-04-16T10:00:00.000Z",
"updatedAt": "2026-04-16T10:00:00.000Z"
}
]
}Get Event Catalog
Returns the complete list of event types your webhooks can subscribe to, including their names and descriptions. Use this to populate event-picker UIs or validate event names at runtime.
Request Example
const res = await fetch("https://api.agentsend.io/webhooks/catalog", { headers: { "x-api-key": process.env.AGENTSEND_API_KEY }, }); const { data } = await res.json(); data.forEach(e => console.log(e.name, e.description));
Response — 200 OK
{
"data": [
{
"name": "domain.verified",
"description": "Fired when a custom domain passes DNS verification."
},
{
"name": "message.received",
"description": "Fired when an inbound email arrives in an inbox."
},
{
"name": "message.sent",
"description": "Fired when an outbound message is accepted by the recipient mail server."
},
{
"name": "message.delivered",
"description": "Fired when delivery to the recipient mailbox is confirmed."
},
{
"name": "message.bounced",
"description": "Fired when a message hard-bounces."
},
{
"name": "message.complained",
"description": "Fired when a recipient marks the message as spam."
}
]
}List Delivery Logs
Returns a list of individual webhook delivery attempts, ordered by most recent first. Use this to debug failed deliveries, inspect payloads, and review response codes from your endpoint.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
webhookId |
string (uuid) | Filter logs to a specific webhook. If omitted, logs for all webhooks are returned. |
status |
enum | Filter by delivery outcome. One of success or failed. |
event |
string | Filter by event type, e.g. message.received. |
limit |
integer | Maximum number of log entries to return. Default 20. |
hours |
integer | Look-back window in hours. Default 168 (7 days). |
Request Example
const params = new URLSearchParams({ webhookId: "wh_01hx9k2v3w4x5y6z7a8b9c0d", status: "failed", limit: "50", hours: "24", }); const res = await fetch( `https://api.agentsend.io/webhooks/logs?${params}`, { headers: { "x-api-key": process.env.AGENTSEND_API_KEY } } ); const { data } = await res.json(); data.forEach(log => console.log(log.event, log.responseStatus));
Response — 200 OK
{
"data": [
{
"id": "whl_01hx9k2v3w4x5y6z7a8b9c0d",
"webhookId": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"event": "message.received",
"status": "failed",
"responseStatus": 503,
"durationMs": 4821,
"attempts": 3,
"createdAt": "2026-04-16T11:05:00.000Z"
}
]
}Get Activity
Returns aggregated delivery activity (success and failure counts over time) for one or all webhooks. Useful for rendering charts on a monitoring dashboard.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
webhookId |
string (uuid) | Scope activity to a specific webhook. If omitted, activity across all webhooks is returned. |
hours |
integer | Look-back window in hours. Default 6. |
Request Example
const res = await fetch( "https://api.agentsend.io/webhooks/activity?webhookId=wh_01hx9k2v3w4x5y6z7a8b9c0d&hours=24", { headers: { "x-api-key": process.env.AGENTSEND_API_KEY } } ); const activity = await res.json(); console.log(activity.successCount, activity.failureCount);
Response — 200 OK
{
"webhookId": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"hours": 24,
"successCount": 142,
"failureCount": 3,
"buckets": [
{ "timestamp": "2026-04-15T11:00:00.000Z", "success": 18, "failure": 0 },
{ "timestamp": "2026-04-15T12:00:00.000Z", "success": 24, "failure": 1 }
]
}Get a Webhook
Retrieve a single webhook by its ID. The secret is never returned after creation.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id requis |
string (uuid) | The ID of the webhook to retrieve. |
Request Example
const res = await fetch( `https://api.agentsend.io/webhooks/${webhookId}`, { headers: { "x-api-key": process.env.AGENTSEND_API_KEY } } ); const webhook = await res.json(); console.log(webhook.isActive, webhook.events);
Response — 200 OK
Returns a single Webhook object (without secret).
{
"id": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"url": "https://your-app.com/webhooks/agentsend",
"description": "Production inbound handler",
"events": ["message.received", "message.bounced"],
"isActive": true,
"createdAt": "2026-04-16T10:00:00.000Z",
"updatedAt": "2026-04-16T10:00:00.000Z"
}Update a Webhook
Update one or more properties of an existing webhook. All body fields are optional — only the fields you provide will be changed. Use isActive: false to pause deliveries without deleting the webhook.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id requis |
string (uuid) | The ID of the webhook to update. |
Request Body
| Parameter | Type | Description |
|---|---|---|
url |
string (uri) | New destination URL. Must start with https://. |
description |
string | Updated human-readable label. |
events |
string[] | Replaces the full list of subscribed event types. Pass an empty array to subscribe to all events. |
isActive |
boolean | Set to false to pause deliveries, or true to resume. |
Request Example
const res = await fetch( `https://api.agentsend.io/webhooks/${webhookId}`, { method: "PUT", headers: { "x-api-key": process.env.AGENTSEND_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ events: ["message.received", "message.delivered", "message.bounced"], isActive: true, }), } ); const updated = await res.json(); console.log(updated.events); // updated event list
Response — 200 OK
Returns the updated Webhook object.
{
"id": "wh_01hx9k2v3w4x5y6z7a8b9c0d",
"url": "https://your-app.com/webhooks/agentsend",
"description": "Production inbound handler",
"events": ["message.received", "message.delivered", "message.bounced"],
"isActive": true,
"createdAt": "2026-04-16T10:00:00.000Z",
"updatedAt": "2026-04-16T12:34:00.000Z"
}Delete a Webhook
Permanently delete a webhook. All future event deliveries to that endpoint will cease immediately. Delivery logs associated with the webhook are retained for audit purposes.
This action is irreversible. If you want to temporarily stop deliveries, use PUT /webhooks/{id} with isActive: false instead.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id requis |
string (uuid) | The ID of the webhook to delete. |
Request Example
await fetch( `https://api.agentsend.io/webhooks/${webhookId}`, { method: "DELETE", headers: { "x-api-key": process.env.AGENTSEND_API_KEY }, } ); // 204 No Content
Response — 204 No Content
Returns an empty body on success.
Event Types
The following event types can be passed to events when creating or updating a webhook. Omit the events field entirely (or pass an empty array) to receive all events.
| Event | Description |
|---|---|
domain.verified | A custom domain has passed DNS verification and is ready to use. |
message.received | An inbound email has arrived in one of your inboxes. |
message.sent | An outbound message was accepted by the recipient mail server. |
message.delivered | Delivery to the recipient mailbox was confirmed (where supported). |
message.bounced | A hard bounce was received — the address does not exist or rejected delivery. |
message.complained | A recipient marked the message as spam. |
To see full payload shapes for each event type, visit the Webhooks conceptual guide.