Docs
Dashboard
HoneyNotify SDKs

Choose your platform

Select a platform to open its public SDK repository on GitHub.

AndroidKotlin and Firebase Cloud MessagingiOSSwift and Apple Push Notification serviceWebBrowser push and service worker support
Engagement

Webhooks

Webhooks send selected HoneyNotify events to your backend over HTTPS. Each delivery is signed so your receiver can verify that the body came from HoneyNotify and was not changed in transit.

Create an endpoint#

POST /v1/webhooks
{
  "url": "https://example.com/webhooks/honeynotify",
  "description": "Production engagement events",
  "event_types": ["notification.accepted", "notification.failed", "opened"]
}

URLs must be HTTPS and must pass HoneyNotify's destination safety checks. Supply between 1 and 50 unique event names. An event name may contain letters, numbers, dots, underscores, and dashes; * subscribes to all available events.

The signing secret is returned only when the endpoint is created or explicitly rotated.

{
  "webhook_id": "ab7a6711-48d1-42a7-afcc-00c0789788f5",
  "signing_secret": "whsec_…"
}

Store the secret immediately in your server-side secret manager.

Verify every delivery#

HoneyNotify sends:

  • X-HoneyNotify-Timestamp: the signing timestamp; and
  • X-HoneyNotify-Signature: v1= followed by a hexadecimal HMAC-SHA256 digest.

The signed value is the timestamp, a literal dot, then the raw request body:

HMAC_SHA256(signing_secret, timestamp + "." + raw_body)

PHP verification example:

<?php

$timestamp = $_SERVER['HTTP_X_HONEYNOTIFY_TIMESTAMP'] ?? '';
$provided = $_SERVER['HTTP_X_HONEYNOTIFY_SIGNATURE'] ?? '';
$body = file_get_contents('php://input');
$expected = 'v1=' . hash_hmac('sha256', $timestamp . '.' . $body, $_ENV['HONEYNOTIFY_WEBHOOK_SECRET']);

if (!hash_equals($expected, $provided)) {
    http_response_code(401);
    exit;
}

Verify against the raw bytes before JSON decoding. Also reject timestamps outside a short tolerance, such as five minutes, to reduce replay risk.

Receiver behaviour#

Return a 2xx response quickly, then process the event asynchronously. Your handler should:

  1. enforce a request-size limit;
  2. verify timestamp freshness and signature;
  3. parse the JSON only after verification;
  4. deduplicate using the event/delivery identifier where supplied;
  5. enqueue business work; and
  6. respond without waiting on slow downstream systems.

Deliveries can be retried, arrive later than expected, or arrive out of order. Design handlers to be idempotent.

HoneyNotify retries failed deliveries and marks them terminal after five attempts. A webhook success means your endpoint accepted the event, not that your later business processing succeeded.

Test an endpoint#

POST /v1/webhooks/{webhook_id}/test

This queues a webhook.test event and returns 202 with {"queued":true}. A successful API response confirms it was queued; check your receiver logs for delivery and signature verification.

Update, rotate, and disable#

GET /v1/webhooks
PATCH /v1/webhooks/{webhook_id}
DELETE /v1/webhooks/{webhook_id}

Update any combination of url, description, event_types, and boolean enabled. To rotate the secret:

{"rotate_secret":true}

The response contains the new signing_secret once. Deploy the new secret to your receiver as part of the same controlled change. If you need overlap during rotation, create a second endpoint and cut over before deleting the old one.

Delete permanently removes the endpoint. Set enabled to false when you want a reversible pause.