Skip to content

Webhook Best Practices

This guide covers production-ready patterns for receiving and processing SendAPI webhook events reliably.

Respond Quickly

Your webhook endpoint should return a 200 OK response within 10 seconds — SendAPI's HTTP client times out after 10s and treats the delivery as failed. If your processing takes longer, acknowledge the event immediately and offload heavy work to a background queue.

javascript
// ✅ Good — acknowledge immediately, process later
app.post('/webhook', (req, res) => {
  const event = req.body;
  queue.add('process-webhook', event); // Background job
  res.status(200).json({ received: true });
});

// ❌ Bad — blocks until processing completes
app.post('/webhook', async (req, res) => {
  await processEvent(req.body);  // Might take 10+ seconds
  res.json({ received: true });
});

Handle Duplicates (Idempotency)

SendAPI may deliver the same event more than once (e.g., during retries). Use the event id to deduplicate:

javascript
app.post('/webhook', async (req, res) => {
  const eventId = req.body.id;

  // Check if we've already processed this event
  const exists = await db.webhookEvents.findOne({ eventId });
  if (exists) {
    return res.status(200).json({ received: true }); // Already processed
  }

  // Store and process
  await db.webhookEvents.create({ eventId, data: req.body });
  await processEvent(req.body);

  res.status(200).json({ received: true });
});

Verify Event Authenticity

When SDK support is available, verify webhook signatures to ensure events are genuinely from SendAPI and haven't been tampered with. Until then, restrict your webhook endpoint by IP or use a secret URL path.

Event Types

EventDescription
sms.deliveredSMS was successfully delivered to the handset
sms.failedSMS delivery failed
whatsapp.message.sentWhatsApp message was sent
whatsapp.message.deliveredWhatsApp message was delivered
whatsapp.message.readWhatsApp message was read
whatsapp.message.receivedInbound WhatsApp message received
whatsapp.session.connectedWhatsApp session paired successfully
whatsapp.session.disconnectedWhatsApp session lost connection
email.deliveredEmail was delivered to the inbox
email.openedRecipient opened the email
email.clickedRecipient clicked a link
email.bouncedEmail bounced (hard or soft)

Retry Policy

If your endpoint returns a non-2xx status code or times out (10 seconds), SendAPI retries with exponential backoff. 4 attempts total:

AttemptDelay since previous attempt
1 (initial)Immediate
25 seconds
330 seconds
42 minutes

After 4 failed attempts, the delivery is marked failed. You can inspect or re-trigger it via GET /v1/webhooks/{id}/deliveries.

Released under the MIT License.