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:

  1. Provide your HTTPS endpoint URL
  2. Select which events to receive
  3. Choose whether to store delivery logs
  4. 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 MethodPOST
Endpoint Pathv1.0/settings/addWebhook
API VersionSingle API (v1.0)
Content-Typeapplication/json

Request Parameters

ParameterTypeRequiredDescriptionExample
owner_idStringYesYour unique SendClean account identifieruser_12345
tokenStringYesYour API authentication token for secure accesssk_live_abc123...
urlString (URL)YesHTTPS endpoint where webhook events will be sent via POST requesthttps://yourapp.com/webhooks/email-events
descriptionStringNoHuman-readable description for this webhook configurationProduction webhook for email tracking
store_logStringNoWhether 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 MethodPOST
Endpoint Pathv1.0/settings/keyResetWebhook
API VersionSingle API (v1.0)
Content-Typeapplication/json

Request Parameters

ParameterTypeRequiredDescriptionExample
owner_idStringYesYour unique SendClean account identifieruser_12345
tokenStringYesYour API authentication token for secure accesssk_live_abc123...
webhook_idStringYesUnique identifier of the webhook configuration to modify or querywh_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 MethodPOST
Endpoint Pathv1.0/settings/editWebhook
API VersionSingle API (v1.0)
Content-Typeapplication/json

Request Parameters

ParameterTypeRequiredDescriptionExample
owner_idStringYesYour unique SendClean account identifieruser_12345
tokenStringYesYour API authentication token for secure accesssk_live_abc123...
urlString (URL)YesHTTPS endpoint where webhook events will be sent via POST requesthttps://yourapp.com/webhooks/email-events
eventStringNoComma-separated list of events to track: send,open,click,soft_bounce,hard_bounce,spamsend,open,click
descriptionStringNoHuman-readable description for this webhook configurationProduction webhook for email tracking
store_logStringNoWhether to store webhook delivery logs. Values: "Enable" or "Disable"Enable
webhook_idStringYesUnique identifier of the webhook configuration to modify or querywh_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 MethodPOST
Endpoint Pathv1.0/settings/listWebhook
API VersionSingle API (v1.0)
Content-Typeapplication/json

Request Parameters

ParameterTypeRequiredDescriptionExample
owner_idStringYesYour unique SendClean account identifieruser_12345
tokenStringYesYour API authentication token for secure accesssk_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 MethodPOST
Endpoint Pathv1.0/settings/deleteWebhook
API VersionSingle API (v1.0)
Content-Typeapplication/json

Request Parameters

ParameterTypeRequiredDescriptionExample
owner_idStringYesYour unique SendClean account identifieruser_12345
tokenStringYesYour API authentication token for secure accesssk_live_abc123...
webhook_idStringYesUnique identifier of the webhook configuration to modify or querywh_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 MethodPOST
Endpoint Pathv1.0/settings/getWebhookInfo
API VersionSingle API (v1.0)
Content-Typeapplication/json

Request Parameters

ParameterTypeRequiredDescriptionExample
owner_idStringYesYour unique SendClean account identifieruser_12345
tokenStringYesYour API authentication token for secure accesssk_live_abc123...
webhook_idStringYesUnique identifier of the webhook configuration to modify or querywh_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";
}

?>

Did this page help you?