tutorial

How to Monitor Sendy Self-Hosted Email Newsletter Service 2026

Sendy is a self-hosted email marketing application powered by Amazon SES. This guide shows you how to monitor your Sendy web app, SES delivery pipeline, bounce/complaint handling, and cron jobs with Vigilmon.

Sendy is a self-hosted PHP email newsletter application that sends bulk email through Amazon SES at a fraction of the cost of managed ESPs. Its low cost comes with operational responsibility: Sendy runs on your web server, and unlike fully managed platforms, nobody pages you when your instance goes down mid-campaign. Vigilmon gives you uptime monitoring, delivery pipeline visibility, and cron job health checks — so you know the moment Sendy stops working.

What You'll Set Up

  • HTTP uptime monitoring for the Sendy web application
  • PHP-FPM and web server health via TCP and keyword checks
  • Cron job heartbeat to verify scheduled send workers are running
  • Amazon SES bounce/complaint webhook endpoint monitoring
  • SSL certificate expiry alerts

Prerequisites

  • Sendy installed on a LAMP or LEMP stack (PHP 7.4+, MySQL, Apache or nginx)
  • Amazon SES configured and verified in Sendy's settings
  • Cron jobs configured for scheduled sends
  • A free Vigilmon account

Step 1: Monitor the Sendy Web Application

Sendy's web UI is the control plane for all your campaigns. Add an HTTP monitor to detect when the application is unreachable.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Sendy URL: https://sendy.yourdomain.com.
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Add a keyword check for "Sendy" — Sendy's login page includes this text and its absence indicates a misconfigured PHP or nginx error page returning 200.
  7. Click Save.

Step 2: Add a Health Check Page to Sendy

Sendy doesn't include a health endpoint, but you can add a lightweight PHP file to your Sendy directory:

<?php
// /var/www/sendy/health.php

header('Content-Type: application/json');

$status = ['app' => 'ok'];

// Check MySQL connection
$host = 'localhost';  // update to match your Sendy config
$user = 'sendy';
$pass = getenv('SENDY_DB_PASS') ?: 'yourpassword';
$db   = 'sendy';

$conn = @new mysqli($host, $user, $pass, $db);
if ($conn->connect_error) {
    $status['database'] = $conn->connect_error;
} else {
    $status['database'] = 'ok';
    $conn->close();
}

$code = (in_array('ok', array_values($status), true) && count(array_unique(array_values($status))) === 1) ? 200 : 503;
http_response_code($code);
echo json_encode($status);

Set the file permissions so it's not world-readable (it contains a database check):

chmod 640 /var/www/sendy/health.php
chown www-data:www-data /var/www/sendy/health.php

Update your Vigilmon HTTP monitor to probe https://sendy.yourdomain.com/health.php. A 503 response tells you whether PHP is running but the database is down.


Step 3: Monitor the Cron Jobs with a Heartbeat

Sendy relies entirely on cron jobs to send scheduled campaigns, process autoresponders, and update subscriber counts. If your cron jobs stop running, scheduled campaigns never go out — and Sendy gives no visible indication that anything is wrong.

Sendy's cron entry typically looks like:

* * * * * php /var/www/sendy/scheduled.php > /dev/null 2>&1

Wrap it to ping Vigilmon after each successful run:

* * * * * php /var/www/sendy/scheduled.php && curl -s "https://vigilmon.online/heartbeat/YOUR_HEARTBEAT_ID"

To set up the heartbeat in Vigilmon:

  1. Click Add MonitorCron Heartbeat.
  2. Set the expected interval to 2 minutes (allows one missed minute before alerting).
  3. Copy the heartbeat URL.
  4. Replace YOUR_HEARTBEAT_ID in the cron command above.

If cron is misconfigured, the PHP interpreter crashes, or the scheduled.php script exits with an error, the && prevents the curl ping and Vigilmon fires an alert within 2 minutes.


Step 4: Monitor Amazon SES Feedback Handlers

Sendy registers webhook endpoints with Amazon SES (via SNS) to receive bounce and complaint notifications. These notifications are critical — if SES can't deliver them to your Sendy instance, you'll keep mailing invalid addresses, which damages your sender reputation and risks account suspension.

Sendy's bounce handler endpoint is typically:

https://sendy.yourdomain.com/bounce-handler.php

Add an HTTP monitor for it:

  1. Add an HTTP / HTTPS monitor for https://sendy.yourdomain.com/bounce-handler.php.
  2. Set Expected HTTP status to 200.
  3. Set Check interval to 5 minutes.

The handler returns 200 on a GET request even without a valid SNS payload — this is enough to confirm it's reachable. Sendy also has a complaint handler; add a monitor for it too:

https://sendy.yourdomain.com/complaint-handler.php

To verify SNS is successfully delivering to these endpoints, check your SNS subscription status in the AWS Console under SNS → Subscriptions. A subscription in PendingConfirmation state means the endpoint is unreachable — your Vigilmon monitor should catch this first.


Step 5: Add TCP Port Monitoring

Even without a health endpoint, TCP monitoring verifies your web server process is alive:

  1. Add a TCP Port monitor.
  2. Enter your server's hostname.
  3. Enter port 443 (HTTPS) or 80 (HTTP).
  4. Set Check interval to 1 minute.

If the HTTP monitor fails but TCP succeeds, Apache or nginx is running but PHP-FPM has crashed. If both fail, the web server itself is down.

For diagnosis, combine this with a separate TCP monitor on port 3306 (MySQL) to isolate database-level failures from web server failures.


Step 6: SSL Certificate Alerts

Sendy's HTTPS certificate is essential — Amazon SES SNS only delivers bounce and complaint notifications to HTTPS endpoints. An expired certificate breaks your SES feedback loop.

  1. Open the HTTP / HTTPS monitor for your Sendy URL.
  2. Enable Monitor SSL certificate.
  3. Set Alert when certificate expires in less than 21 days.

If you're using Let's Encrypt via Certbot, verify your auto-renewal cron job:

certbot renew --dry-run

A 21-day alert window gives you enough time to debug renewal failures before the certificate expires.


Step 7: Configure Alert Channels

  1. Go to Alert Channels in Vigilmon and add Slack, email, or PagerDuty.
  2. Route cron heartbeat alerts to your primary operations channel — a missed heartbeat means a scheduled campaign won't send.
  3. Route SSL and bounce handler alerts to your engineering team.
  4. Set Consecutive failures before alert to 2 on the web UI monitor to avoid false positives from PHP-FPM reloads.
  5. Add a maintenance window before Sendy upgrades:
curl -X POST https://vigilmon.online/api/maintenance \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"monitor_id": "your-monitor-id", "duration_minutes": 10}'

Summary

| Monitor | Target | What It Catches | |---|---|---| | Web UI | https://sendy.yourdomain.com | PHP or web server failure | | Health page | /health.php | Database connection failure | | Cron heartbeat | Heartbeat URL | Missed scheduled sends | | Bounce handler | /bounce-handler.php | SES feedback loop broken | | Complaint handler | /complaint-handler.php | SES feedback loop broken | | TCP port | :443 | Web server process crash | | SSL certificate | Sendy domain | Certificate expiry |

Sendy's self-hosted model gives you Amazon SES pricing with full ownership of the sending infrastructure. With Vigilmon monitoring the web layer, cron workers, SES feedback handlers, and SSL certificates, you have the same level of visibility as a managed ESP — without the per-subscriber fees.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →