Webhooks
Create, update, list, inspect, reset, and delete email event webhooks with Single API v1.0.
Overview
Configures a webhook endpoint to receive real-time notifications about email events. Webhooks enable
your application to:
- React immediately to email events (opens, clicks, bounces)
- Update customer records in real-time
- Trigger follow-up workflows
- Monitor delivery issues
- Build real-time analytics
When you configure a webhook:
- Provide your HTTPS endpoint URL
- Select which events to receive
- Choose whether to store delivery logs
- Receive a webhook key for validating events
SendClean will POST JSON payloads to your endpoint for each event, allowing you to process them in your application.
Endpoint Details
| HTTP Method | POST |
|---|---|
| Endpoint Path | v1.0/settings/addWebhook |
| API Version | Single API (v1.0) |
| Content-Type | application/json |
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| owner_id | String | Yes | Your unique SendClean account identifier | user_12345 |
| token | String | Yes | Your API authentication token for secure access | sk_live_abc123... |
| url | String (URL) | Yes | HTTPS endpoint where webhook events will be sent via POST request | https://yourapp.com/webhooks/email-events |
| description | String | No | Human-readable description for this webhook configuration | Production webhook for email tracking |
| store_log | String | No | Whether to store webhook delivery logs. Values: "Enable" or "Disable" | Enable |
Request Example
Below is a complete example of the request body. Replace placeholder values with your actual credentials and data.
{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"url": "https://app.us.sendclean.net/api/report/mtaReports",
"description": "God bless you, SendClean",
"store_log": "Enable"
}Response Format
Successful Response:
{
"status": "success",
"code": 200,
"message": "Resource created successfully",
"data": {
"id": "resource_abc123",
"created_at": "2026-04-17T10:30:00Z"
}
}Common Use Cases
- Update CRM when emails are opened or clicked
- Trigger follow-up workflows based on email engagement
- Build real-time email analytics dashboards
- Alert customer service of bounced emails
- Automatically process spam complaints and unsubscribes
Best Practices
- • Use HTTPS endpoints only for security
- • Implement idempotent webhook handlers to handle duplicate deliveries
- • Validate webhook signatures to ensure authenticity
- • Return 2xx status codes within 5 seconds to prevent retries
- • Store webhook payloads for audit trails and debugging
- • Implement retry logic for failed webhook processing in your application
Common Errors & Troubleshooting
401 - Unauthorized: Authentication credentials are missing or invalid
Solution: Verify owner_id and token are correct. Ensure they match your account credentials exactly with no extra whitespace.
500 - Internal server error: Unexpected server error occurred
Solution: Retry the request after a brief delay. If error persists, contact SendClean support with the request details and timestamp.
Implementation Examples
curl -X POST \
https://api.sendclean.com/v1.0/settings/addWebhook \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"url": "https://app.us.sendclean.net/api/report/mtaReports",
"description": "God bless you, SendClean",
"store_log": "Enable"
}'const axios = require('axios');
const url = 'https://api.sendclean.com/v1.0/settings/addWebhook';
const payload = {
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"url": "https://app.us.sendclean.net/api/report/mtaReports",
"description": "God bless you, SendClean",
"store_log": "Enable"
};
axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});<?php
$url = 'https://api.sendclean.com/v1.0/settings/addWebhook';
$payload = json_decode('{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"url": "https://app.us.sendclean.net/api/report/mtaReports",
"description": "God bless you, SendClean",
"store_log": "Enable"
}', true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Error: $httpCode - $response";
}
?>Overview
Regenerates the authentication key for a webhook. The webhook key is used to:
- Verify webhook requests are genuinely from SendClean
- Prevent spoofed webhook calls
- Secure your webhook endpoint
You should reset the key:
- If it's been compromised or exposed
- Periodically for security (every 90 days recommended)
- When changing webhook infrastructure
- After security incidents
After resetting, update your webhook handler to use the new key for validation. The old key becomes invalid immediately.
Endpoint Details
| HTTP Method | POST |
|---|---|
| Endpoint Path | v1.0/settings/keyResetWebhook |
| API Version | Single API (v1.0) |
| Content-Type | application/json |
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| owner_id | String | Yes | Your unique SendClean account identifier | user_12345 |
| token | String | Yes | Your API authentication token for secure access | sk_live_abc123... |
| webhook_id | String | Yes | Unique identifier of the webhook configuration to modify or query | wh_abc123 |
Request Example
Below is a complete example of the request body. Replace placeholder values with your actual credentials and data.
{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}Response Format
Successful Response:
{
"status": "success",
"code": 200,
"message": "Operation completed successfully"
}Common Errors & Troubleshooting
401 - Unauthorized: Authentication credentials are missing or invalid
Solution: Verify owner_id and token are correct. Ensure they match your account credentials exactly with no extra whitespace.
500 - Internal server error: Unexpected server error occurred
Solution: Retry the request after a brief delay. If error persists, contact SendClean support with the request details and timestamp.
Implementation Examples
curl -X POST \
https://api.sendclean.com/v1.0/settings/keyResetWebhook \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}'const axios = require('axios');
const url = 'https://api.sendclean.com/v1.0/settings/keyResetWebhook';
const payload = {
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
};
axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});<?php
$url = 'https://api.sendclean.com/v1.0/settings/keyResetWebhook';
$payload = json_decode('{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}', true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Error: $httpCode - $response";
}
?>Overview
Modifies an existing webhook configuration. You can update:
- Target URL (to change endpoint)
- Event subscriptions (add or remove event types)
- Description and metadata
- Log storage preferences
- Active/inactive status
Use cases:
- Updating URL after infrastructure changes
- Adjusting which events you want to track
- Temporarily disabling webhooks for maintenance
- Changing from test to production endpoints
Changes take effect immediately, so ensure your new endpoint is ready before updating.
Endpoint Details
| HTTP Method | POST |
|---|---|
| Endpoint Path | v1.0/settings/editWebhook |
| API Version | Single API (v1.0) |
| Content-Type | application/json |
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| owner_id | String | Yes | Your unique SendClean account identifier | user_12345 |
| token | String | Yes | Your API authentication token for secure access | sk_live_abc123... |
| url | String (URL) | Yes | HTTPS endpoint where webhook events will be sent via POST request | https://yourapp.com/webhooks/email-events |
| event | String | No | Comma-separated list of events to track: send,open,click,soft_bounce,hard_bounce,spam | send,open,click |
| description | String | No | Human-readable description for this webhook configuration | Production webhook for email tracking |
| store_log | String | No | Whether to store webhook delivery logs. Values: "Enable" or "Disable" | Enable |
| webhook_id | String | Yes | Unique identifier of the webhook configuration to modify or query | wh_abc123 |
Request Example
Below is a complete example of the request body. Replace placeholder values with your actual credentials and data.
{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"event": "send,open,click,soft_bounce,hard_bounce,spam",
"description": "Welcome to SendClean",
"store_log": "Enable",
"webhook_id": "{{webhook_id}}",
"url": "https://app.us.sendclean.net/api/report/mtaReports"
}Response Format
Successful Response:
{
"status": "success",
"code": 200,
"message": "Resource updated successfully",
"data": {
"updated_at": "2026-04-17T10:30:00Z"
}
}Common Errors & Troubleshooting
401 - Unauthorized: Authentication credentials are missing or invalid
Solution: Verify owner_id and token are correct. Ensure they match your account credentials exactly with no extra whitespace.
500 - Internal server error: Unexpected server error occurred
Solution: Retry the request after a brief delay. If error persists, contact SendClean support with the request details and timestamp.
Implementation Examples
curl -X POST \
https://api.sendclean.com/v1.0/settings/editWebhook \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"event": "send,open,click,soft_bounce,hard_bounce,spam",
"description": "Welcome to SendClean",
"store_log": "Enable",
"webhook_id": "{{webhook_id}}",
"url": "https://app.us.sendclean.net/api/report/mtaReports"
}'const axios = require('axios');
const url = 'https://api.sendclean.com/v1.0/settings/editWebhook';
const payload = {
"owner_id":"{{owner_id}}",
"token":"{{token}}",
"event":"send,open,click,soft_bounce,hard_bounce,spam",
"description":"Welcome to SendClean",
"store_log":"Enable",
"webhook_id":"{{webhook_id}}",
"url":"https://app.us.sendclean.net/api/report/mtaReports"
};
axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});<?php
$url = 'https://api.sendclean.com/v1.0/settings/editWebhook';
$payload = json_decode('{
"owner_id":"{{owner_id}}",
"token":"{{token}}",
"event":"send,open,click,soft_bounce,hard_bounce,spam",
"description":"Welcome to SendClean",
"store_log":"Enable",
"webhook_id":"{{webhook_id}}",
"url":"https://app.us.sendclean.net/api/report/mtaReports"
}', true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Error: $httpCode - $response";
}
?>Overview
Returns all webhook configurations in your account with their current status and statistics.
For each webhook:
- Endpoint URL and description
- Subscribed events
- Active/inactive status
- Recent delivery success rate
- Total events delivered
- Last delivery attempt
Use this to:
- Audit webhook configurations
- Monitor delivery health
- Identify failing webhooks
- Plan webhook infrastructure changes
Endpoint Details
| HTTP Method | POST |
|---|---|
| Endpoint Path | v1.0/settings/listWebhook |
| API Version | Single API (v1.0) |
| Content-Type | application/json |
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| owner_id | String | Yes | Your unique SendClean account identifier | user_12345 |
| token | String | Yes | Your API authentication token for secure access | sk_live_abc123... |
Request Example
Below is a complete example of the request body. Replace placeholder values with your actual credentials and data.
{
"owner_id": "{{owner_id}}",
"token": "{{token}}"
}Response Format
Successful Response:
{
"status": "success",
"code": 200,
"data": {
"items": [
{
"id": "item_001",
"created_at": "2026-04-01T09:00:00Z",
"status": "active"
}
],
"total": 1,
"page": 0
}
}Common Errors & Troubleshooting
401 - Unauthorized: Authentication credentials are missing or invalid
Solution: Verify owner_id and token are correct. Ensure they match your account credentials exactly with no extra whitespace.
500 - Internal server error: Unexpected server error occurred
Solution: Retry the request after a brief delay. If error persists, contact SendClean support with the request details and timestamp.
Implementation Examples
curl -X POST \
https://api.sendclean.com/v1.0/settings/listWebhook \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "{{owner_id}}",
"token": "{{token}}"
}'const axios = require('axios');
const url = 'https://api.sendclean.com/v1.0/settings/listWebhook';
const payload = {
"owner_id": "{{owner_id}}",
"token": "{{token}}"
};
axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});<?php
$url = 'https://api.sendclean.com/v1.0/settings/listWebhook';
$payload = json_decode('{
"owner_id": "{{owner_id}}",
"token": "{{token}}"
}', true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Error: $httpCode - $response";
}
?>Overview
Permanently removes a webhook configuration. After deletion:
- No further events will be sent to this endpoint
- Historical delivery data is retained for reporting
- The webhook ID becomes invalid
- Configuration cannot be recovered
Only delete webhooks that are:
- No longer needed
- Pointing to decommissioned endpoints
- Replaced by new webhook configurations
Before deleting, consider disabling the webhook instead if you might need it again.
Endpoint Details
| HTTP Method | POST |
|---|---|
| Endpoint Path | v1.0/settings/deleteWebhook |
| API Version | Single API (v1.0) |
| Content-Type | application/json |
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| owner_id | String | Yes | Your unique SendClean account identifier | user_12345 |
| token | String | Yes | Your API authentication token for secure access | sk_live_abc123... |
| webhook_id | String | Yes | Unique identifier of the webhook configuration to modify or query | wh_abc123 |
Request Example
Below is a complete example of the request body. Replace placeholder values with your actual credentials and data.
{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}Response Format
Successful Response:
{
"status": "success",
"code": 200,
"message": "Resource deleted successfully"
}Common Errors & Troubleshooting
401 - Unauthorized: Authentication credentials are missing or invalid
Solution: Verify owner_id and token are correct. Ensure they match your account credentials exactly with no extra whitespace.
500 - Internal server error: Unexpected server error occurred
Solution: Retry the request after a brief delay. If error persists, contact SendClean support with the request details and timestamp.
Implementation Examples
curl -X POST \
https://api.sendclean.com/v1.0/settings/deleteWebhook \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}'const axios = require('axios');
const url = 'https://api.sendclean.com/v1.0/settings/deleteWebhook';
const payload = {
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
};
axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});<?php
$url = 'https://api.sendclean.com/v1.0/settings/deleteWebhook';
$payload = json_decode('{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}', true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Error: $httpCode - $response";
}
?>Overview
Retrieves detailed information about a specific webhook including recent delivery attempts, success
rates, and configuration details.
The detailed view includes:
- All configuration settings
- Recent delivery history (last 100 attempts)
- Success and failure rates
- Error messages for failed deliveries
- Retry information
- Latency statistics
Use this for:
- Troubleshooting webhook delivery problems
- Monitoring endpoint performance
- Understanding event volume
- Debugging integration issues
Endpoint Details
| HTTP Method | POST |
|---|---|
| Endpoint Path | v1.0/settings/getWebhookInfo |
| API Version | Single API (v1.0) |
| Content-Type | application/json |
Request Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| owner_id | String | Yes | Your unique SendClean account identifier | user_12345 |
| token | String | Yes | Your API authentication token for secure access | sk_live_abc123... |
| webhook_id | String | Yes | Unique identifier of the webhook configuration to modify or query | wh_abc123 |
Request Example
Below is a complete example of the request body. Replace placeholder values with your actual credentials and data.
{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}Response Format
Successful Response:
{
"status": "success",
"code": 200,
"message": "Operation completed successfully"
}Common Errors & Troubleshooting
401 - Unauthorized: Authentication credentials are missing or invalid
Solution: Verify owner_id and token are correct. Ensure they match your account credentials exactly with no extra whitespace.
500 - Internal server error: Unexpected server error occurred
Solution: Retry the request after a brief delay. If error persists, contact SendClean support with the request details and timestamp.
Implementation Examples
curl -X POST \
https://api.sendclean.com/v1.0/settings/getWebhookInfo \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}'const axios = require('axios');
const url = 'https://api.sendclean.com/v1.0/settings/getWebhookInfo';
const payload = {
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
};
axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log('Success:', response.data);
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});<?php
$url = 'https://api.sendclean.com/v1.0/settings/getWebhookInfo';
$payload = json_decode('{
"owner_id": "{{owner_id}}",
"token": "{{token}}",
"webhook_id": "{{webhook_id}}"
}', true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Error: $httpCode - $response";
}
?>Updated 4 days ago