Webhooks

DropOnAir can push runtime events to your backend using signed HTTPS webhooks. Open the Webhooks page in the dashboard (left sidebar, Webhooks) to register endpoints and review delivery history. Delivery is asynchronous and queued, so message, call, and broadcast flows stay off the request path.

Important: Webhooks never include message ciphertext, encryption keys, or customer credentials. They carry event metadata only.

How delivery works

  1. You register one or more HTTPS endpoints per app in the DropOnAir dashboard.
  2. Runtime services publish webhook events internally when delivery, calling, broadcast, or quota transitions happen.
  3. The platform resolves matching registrations, signs the raw JSON payload, and sends a POST request to your endpoint.
  4. Failures are retried with exponential backoff for up to 5 total attempts.
  5. Delivery history is visible in the dashboard and retained according to the app's effective package retention window.

Supported events

EventMeaning
message.deliveredA message reached the recipient delivery flow.
message.failedMessage delivery failed permanently.
call.startedA call session entered the active state.
call.endedA call session ended and billing or duration metadata is final.
broadcast.publishedA broadcast publish action completed.
group_message.deliveredA group message reached the delivery flow.
app.quota_warningUsage is approaching a tracked plan limit.
app.quota_exceededUsage exceeded a tracked quota threshold.

Webhook request

POSThttps://your-backend.example/webhooks/droponair
Content-Type: application/json
X-DropOnAir-Signature: sha256=LOWERCASE_HEX_HMAC

Payload format

{
  "event": "message.delivered",
  "appId": "71b41926-f2bf-4e8a-b2bb-e9a55245a1ee",
  "timestamp": "2026-04-22T12:34:56Z",
  "data": {
    "messageId": "2f6d9c7b-...",
    "recipientUserId": "bob"
  }
}

Signature verification example (Node.js)

import crypto from 'crypto';

app.post('/webhooks/droponair', express.raw({ type: 'application/json' }), (req, res) => {
  const secret = process.env.DROPONAIR_WEBHOOK_SECRET;
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(req.body)
    .digest('hex');

  const received = req.get('X-DropOnAir-Signature') ?? '';
  const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));

  if (!valid) {
    res.status(401).send('invalid signature');
    return;
  }

  const event = JSON.parse(req.body.toString('utf8'));
  console.log(event.event, event.data);
  res.status(204).end();
});

Retention and operations

  • ✓  Free: webhook history follows 7-day package retention
  • ✓  Pro: webhook history follows 90-day package retention
  • ✓  Growth and PAYG: webhook history follows 365-day package retention
  • ✓  Enterprise: webhook history follows the app's configured retention policy
  • ✓  The dashboard shows the latest delivery attempts per app without exposing stored secrets