WaConnect|API Documentation Dashboard Swagger UI

Webhooks

Receive incoming WhatsApp messages and delivery status updates in real-time. WaConnect forwards events to your server via HTTP POST requests.

Setup

Provide Your Callback URL

Contact your WaConnect administrator and provide the URL of your webhook endpoint (e.g., https://your-app.com/api/whatsapp/incoming). The URL must be publicly accessible over HTTPS.

Set a Callback Secret (Recommended)

Provide a secret string to your administrator. WaConnect will use it to sign every webhook request with an HMAC-SHA256 signature, allowing you to verify authenticity.

Webhook Payload

When an incoming message arrives, WaConnect sends an HTTP POST request to your Callback URL with the following structure:

Headers

HeaderValue
Content-Typeapplication/json
X-Webhook-Eventmessage.received
X-Webhook-Delivery-Attempt1 (increments on retry)
X-Webhook-Signaturesha256=HEX_SIGNATURE (if Callback Secret is set)

Body

{
  "event": "message.received",
  "timestamp": "2026-04-11T10:30:00.000Z",
  "accountId": "uuid-of-your-account",
  "accountName": "Your Company Name",
  "message": {
    "messageId": "wamid.HBgLMTU1NTEyMzQ1NjcVAgASGCA0",
    "from": "15551234567",
    "contactName": "John Doe",
    "contactWaId": "15551234567",
    "messageType": "text",
    "content": {
      "text": "I need help with my order."
    },
    "context": null,
    "phoneNumberId": "106540352242922",
    "timestamp": "2026-04-11T10:29:58.000Z"
  },
  "conversation": {
    "id": "123456789012345",
    "origin": {
      "type": "user_initiated"
    }
  },
  "pricing": {
    "billable": true,
    "pricingModel": "CBP",
    "category": "user_initiated"
  }
}JSON

Verifying the Signature

If you set a Callback Secret, every webhook request includes an X-Webhook-Signature header. To verify it:

  1. Read the raw request body as a UTF-8 string.
  2. Compute an HMAC-SHA256 hash of the body using your Callback Secret as the key.
  3. Compare the hex-encoded hash with the value after sha256= in the header.

C# Example (ASP.NET Core)

A complete webhook receiver controller with HMAC signature verification:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace WebhookReceiver.Controllers
{
    [ApiController]
    [Route("api/whatsapp/incoming")]
    public class WhatsAppWebhookController : ControllerBase
    {
        // The same secret you provided to the WaConnect admin
        private const string CallbackSecret = "your_secure_secret_phrase";

        [HttpPost]
        public async Task<IActionResult> ReceiveMessage()
        {
            // 1. Read the raw body
            using var reader = new StreamReader(Request.Body);
            var rawBody = await reader.ReadToEndAsync();

            // 2. Verify the HMAC-SHA256 signature
            if (Request.Headers.TryGetValue("X-Webhook-Signature", out var sigHeader))
            {
                var expected = ComputeHmacSha256(rawBody, CallbackSecret);
                var provided = sigHeader.ToString().Replace("sha256=", "");

                if (!string.Equals(expected, provided,
                    StringComparison.OrdinalIgnoreCase))
                {
                    return Unauthorized("Invalid signature.");
                }
            }

            // 3. Parse the payload
            try
            {
                var doc = JsonDocument.Parse(rawBody);
                var root = doc.RootElement;

                if (root.GetProperty("event").GetString() == "message.received")
                {
                    var msg = root.GetProperty("message");
                    var from = msg.GetProperty("from").GetString();
                    var type = msg.GetProperty("messageType").GetString();

                    Console.WriteLine($"Received {type} from {from}");

                    if (type == "text")
                    {
                        var text = msg.GetProperty("content")
                                       .GetProperty("text").GetString();
                        Console.WriteLine($"Content: {text}");
                    }

                    // Process the message in your business logic
                }

                // 4. Always return 200 OK quickly
                return Ok();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
                return BadRequest();
            }
        }

        private static string ComputeHmacSha256(string payload, string secret)
        {
            var keyBytes = Encoding.UTF8.GetBytes(secret);
            var msgBytes = Encoding.UTF8.GetBytes(payload);
            using var hmac = new HMACSHA256(keyBytes);
            var hash = hmac.ComputeHash(msgBytes);
            return Convert.ToHexString(hash).ToLower();
        }
    }
}C#

Retry Policy

If your server responds with an error or times out, WaConnect retries delivery automatically:

AttemptDelayRetries On
1stImmediate
2nd1 second5xx errors, timeouts, 429
3rd2 seconds5xx errors, timeouts, 429
4th4 seconds5xx errors, timeouts, 429

WaConnect will not retry on 4xx client errors (except 429 Too Many Requests). Always return 200 OK as quickly as possible and process the message asynchronously.

Important: Your webhook endpoint must respond within 5 seconds. If processing takes longer, acknowledge the request immediately and handle the message in a background queue.