Alerts, Deliveries & Webhooks

Test alerts, inspect delivery attempts, retry failures, and verify webhook signatures

When a monitor detects a change, it delivers an alert to the channels you configured (alertWebhookUrl and/or alertEmails). Every attempt is logged as a delivery.


Webhook payload

Anakin POSTs this JSON body to your alertWebhookUrl on each detected change:

{
  "type": "monitor.change",
  "monitorId": "b1e7c2a4-…",
  "url": "https://example.com/product/123",
  "watchMode": "specific_data",
  "changeId": "c_9a1…",
  "changedAt": "2026-01-01T12:00:00Z",
  "changedFields": ["price"],
  "summary": "The price dropped from $19.99 to $14.99.",
  "diff": { "before": { "price": 19.99 }, "after": { "price": 14.99 } }
}

Each request carries these headers:

HeaderDescription
X-Anakin-Signaturesha256= + hex HMAC-SHA256 of the raw request body, keyed with the monitor's alertWebhookSecret.
X-Anakin-TimestampUnix seconds when the request was signed.
X-Anakin-Delivery-IdThe delivery ID (for idempotency / retry correlation).

Verify the signature by recomputing the HMAC over the exact raw body and comparing (constant-time) to X-Anakin-Signature:

import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)

For the full webhook integration guide (retries, delivery semantics), see Website Monitoring Webhooks.


POSThttps://api.anakin.io/v1/monitors/{id}/test-alert

Send a sample alert to the monitor's configured channels so you can verify your endpoint and signature handling before a real change fires.

Response

200 OK
{ "success": true, "status": 200 }

status is the HTTP status your webhook returned (or the email send result). Errors: 400 invalid_request if no alert channel is configured; 502 if delivery failed (the body includes status and a message).


GEThttps://api.anakin.io/v1/monitors/{id}/deliveries

List recent alert-delivery attempts, newest first (up to 200).

Response

200 OK
{
  "deliveries": [
    {
      "id": "d_5f2…",
      "monitorId": "b1e7c2a4-…",
      "changeId": "c_9a1…",
      "event": "change",
      "channel": "webhook",
      "url": "https://your-app.com/hooks/anakin",
      "status": "success",
      "httpStatus": 200,
      "attempts": 1,
      "createdAt": "2026-01-01T12:00:01Z"
    }
  ]
}
FieldTypeDescription
eventstringchange or test.
channelstringwebhook or email.
urlstringDestination — the webhook URL or the comma-separated recipients.
statusstringpending, success, failed, or exhausted (retries used up).
httpStatusnumber | nullHTTP status returned by the webhook.
attemptsnumberDelivery attempts so far.
errorstring | nullFailure reason, when failed.
nextAttemptAtstring | nullWhen the next retry is scheduled (while pending).

POSThttps://api.anakin.io/v1/monitors/{id}/deliveries/{deliveryId}/retry

Re-queue a failed or exhausted delivery for another attempt.

Response

200 OK
{ "success": true }

Returns 404 not_found if the delivery doesn't belong to this monitor.


Code Examples

# Fire a test alert
curl -X POST https://api.anakin.io/v1/monitors/b1e7c2a4-.../test-alert -H "X-API-Key: your_api_key"

# Inspect deliveries
curl https://api.anakin.io/v1/monitors/b1e7c2a4-.../deliveries -H "X-API-Key: your_api_key"

# Retry one
curl -X POST https://api.anakin.io/v1/monitors/b1e7c2a4-.../deliveries/d_5f2.../retry -H "X-API-Key: your_api_key"