Skip to main content

Documentation Index

Fetch the complete documentation index at: https://help.withallo.com/llms.txt

Use this file to discover all available pages before exploring further.

Respond quickly

Return a 200 status code as soon as you receive the webhook. Do your processing asynchronously — write the event to a queue or database, then process it in the background. If your endpoint takes too long to respond (over 20 seconds), the delivery is marked as failed and retried.

Implement idempotency

Allo guarantees at-least-once delivery, which means your endpoint may receive the same event more than once. To prevent duplicate processing:
  1. Extract the webhook-id header from the request — it uniquely identifies each delivery.
  2. Check if you have already processed this ID (e.g., lookup in your database).
  3. If it is new, process the event and store the ID.
  4. If it is a duplicate, return 200 and skip processing.
app.post("/webhooks/allo", async (req, res) => {
  const webhookId = req.headers["webhook-id"];

  // Check if already processed
  if (await db.webhookProcessed(webhookId)) {
    return res.sendStatus(200);
  }

  // Mark as processed before doing work
  await db.markWebhookProcessed(webhookId);

  // Process the event asynchronously
  queue.add("process-webhook", req.body);

  res.sendStatus(200);
});

Use HTTPS

Your webhook URL must use HTTPS. Self-signed certificates are not accepted.

Verify signatures

Always verify webhook signatures in production to ensure requests come from Allo.

Handle out-of-order delivery

Events may arrive in a different order than they occurred. For example, tag.added could arrive before call.completed for the same call. Do not assume events arrive in chronological order. Use the timestamp field in the payload to determine when the event actually occurred.

Monitor your endpoints

Check your webhook health from Settings > Webhooks. You can see delivery statistics and inspect failed deliveries.

Keep your secrets safe

  • Store the signing secret (whsec_...) in environment variables, not in source code.
  • Never commit secrets to version control.
  • Rotate secrets if they are compromised.

Disable CSRF protection

If your web framework enables CSRF protection by default (e.g., Django, Rails), disable it for your webhook endpoint. Webhook requests do not include CSRF tokens and will be rejected.