Alert webhooks
Aepto POSTs signed JSON to your HTTPS URL when subscribed events fire. Manage webhooks in the app or via the Platform API. End-user UI steps: Docs - Alert webhooks.
Auth and scopes
- API calls use
Authorization: Bearer ...(API key or Connect token). - Read:
webhooks:read. Write:webhooks:write. - Alert webhooks require a plan that includes them.
POSTcreates require anIdempotency-Keyheader.
Manage via API
Base path: https://app.aepto.com/api/v1. Full table: Endpoints — Alert webhooks.
| Method | Path | Notes |
|---|---|---|
POST | /alert-webhooks | Body: name, url (HTTPS). Response includes signing_secret once. |
GET / PATCH / DELETE | /alert-webhooks/{id} | PATCH may set name, url, is_enabled. |
POST | /alert-webhooks/{id}/rotate-secret | Returns a new signing_secret once. Store it; it is not shown again. |
POST | /alert-webhooks/{id}/subscriptions | Subscribe to event families (see below). |
GET | /alert-webhooks/{id}/subscriptions | List subscriptions. |
PATCH / DELETE | /alert-webhooks/subscriptions/{id} | Update or remove a subscription. |
curl -sS -X POST "https://app.aepto.com/api/v1/alert-webhooks" \
-H "Authorization: Bearer aep_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"name":"My receiver","url":"https://example.com/hooks/aepto"}'
Subscriptions
POST /alert-webhooks/{id}/subscriptions JSON fields:
feature_type- category to receive (defaultwebsite_monitoring)scope-global,domain, ormonitoringdomain_id/monitoring_id- required when scope needs themevent_types- optional filter; omit for all events in that featureis_enabled- optional (default true)bulk_account_wide-truecreates one global subscription per allowed feature type
feature_type values include: website_monitoring, content_monitoring, renewal_reminders, domain_notifications, theft_guard, dns_monitoring, email_deliverability_alerts, incident_reminders, pagespeed_alerts, domain_watch, domain_expense_reports, api_rate_limits.
Some features are account-wide only (global): Domain Watch, expense reports, incident reminders, and API Rate Limits. Per-monitor scope applies to website and content monitoring.
Outbound delivery
Aepto sends POST to your URL with JSON body and these headers:
Content-Type: application/jsonX-Aepto-Event-Id- unique event idX-Aepto-Event-Type- e.g.monitoring.downtimeX-Aepto-Signature-t=<unix>,v1=<hex>Idempotency-Key- same as event id (safe to dedupe)User-Agent: Aepto-Webhooks/1.0
Envelope (schema_version: 1):
{
"schema_version": 1,
"event_id": "...",
"event_type": "monitoring.downtime",
"occurred_at": "2026-01-15T12:00:00Z",
"user": { "id": 123, "public_ref": "user:123" },
"resource": { "type": "monitoring" },
"data": { }
}
Monitoring events use resource.type monitoring and types such as monitoring.downtime, monitoring.recovery, monitoring.ssl_expiry, monitoring.slow_response (plus sample monitoring.test). Other families use resource.type notification and event_type shaped like {feature_type}.{template_key} (for example dns_monitoring.dns_change_alert, theft_guard.general_security_alert).
Respond with 2xx quickly. Failed deliveries are retried with backoff; repeated failures can pause the endpoint until you fix and re-enable it.
Verify signatures
- Read the raw request body (bytes), not a re-serialized JSON object.
- Parse
X-Aepto-Signaturefort(timestamp) andv1(hex HMAC). - Reject if
tis too far from your clock (recommended: a few minutes). - Compute
HMAC-SHA256(signing_secret, t + "." + raw_body)as hex. - Compare to
v1with a constant-time equals.
// Node.js sketch
const crypto = require('crypto');
function verify(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(',').map((p) => p.trim().split('='))
);
const t = parts.t;
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
Secrets
- Store
signing_secretfrom create or rotate in your secrets manager. It is shown once. - Never log the full secret or put it in client-side code.
- Rotate with
POST /alert-webhooks/{id}/rotate-secretif a secret may be exposed.
App UI
In the dashboard: Domains → Alert webhooks. Use Send sample and the delivery log while wiring your receiver. Product walkthrough: Alert webhooks (Docs).
FAQ
How do I verify Aepto signed the webhook?
HMAC-SHA256 over t + "." + raw_body using the signing secret; compare to v1 in X-Aepto-Signature. Always use the raw body bytes — see Verify signatures above.
When is the signing secret shown?
Once, on create or rotate (POST …/rotate-secret). Store it in a secrets manager; it is not shown again.
Does slow response have a webhook event?
Yes — monitoring.slow_response, alongside downtime, recovery, and SSL expiry events.
Can I manage webhooks in the UI instead of the API?
Yes. Domains → Alert webhooks in the app, with Send sample and a delivery log. Product guide: Alert webhooks.
More answers: FAQ hub.