XSender exposes inbound HTTP webhooks so that any external system can push data into a workflow — your storefront, CRM, billing system, IoT device, Zapier, Make, or a custom backend. This is the primary way to "process incoming messages and events" inside XSender.
There is one canonical inbound endpoint and several specialised ones. Each is documented below with the request shape, what XSender does on receipt, and a copy-pasteable example.
| You want to… | Use |
|---|---|
| Send a single transactional message | Send API (/api/{channel}/send) |
| React to an event in your system (signup, order, support reply) by enrolling a contact into a workflow | Automation Trigger Webhook |
| Receive delivery events from your ESP (Mailgun open, SES bounce, …) | Email Delivery Webhooks |
| Capture leads submitted on Meta / Google ad forms | Lead Capture Webhooks |
| Sync session state between the WhatsApp Node service and the app | WhatsApp Session Webhook |
POST /api/automation/webhook/{id}This is the most powerful inbound endpoint. It lets any external system trigger an automation workflow in XSender by POSTing a JSON payload that identifies a contact (email, phone, or WhatsApp number) plus any custom fields you want available inside the workflow.
In Automation → Workflows → New Workflow, drag the Webhook trigger onto the canvas. XSender generates a unique webhook_id for that node — copy the full URL.
curl -X POST https://YOUR-XSENDER-DOMAIN/api/automation/webhook/4f2c1b8d-9e6a-4f0b-bcde-1234567890ab \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"phone": "+15555550123",
"first_name": "John",
"last_name": "Doe",
"order_id": "A1023",
"amount": "129.95"
}'
{{ order_id }}, {{ amount }}, etc.webhook_id.{
"success": true,
"message": "Webhook processed",
"workflows_triggered": 2,
"contacts_enrolled": 1
}
Authentication: the unguessable
webhook_idin the URL acts as the secret. Treat it like an API key. Rotate it (delete + recreate the trigger node) if you suspect leakage.
POST /api/webhook/meta-lead-adsConfigured automatically when you connect a Meta page in Lead → Lead Generation → Meta. XSender:
hub.challenge handshake on GET.leadgen events on POST, retrieves the lead details from the Graph API, maps fields, creates or updates a contact, and (optionally) enrols it into a workflow.POST /api/webhook/google-ads-leadSet this URL inside the Google Ads Lead Form Extension. XSender validates the Google-signed payload, maps fields, and creates contacts the same way.
Both endpoints are exempt from rate-limiting.
These are used internally by the bundled WhatsApp Node service (whatsapp-node-service) to keep the XSender database in sync with the live WhatsApp Web sessions. You normally don't call them directly, but they are documented here for self-hosted users who run their own node service.
| Method | Path | Purpose |
|---|---|---|
| POST | /api/whatsapp/session/status | Push session state changes (connected / disconnected / qr). |
| POST | /api/whatsapp/session/sync | On node startup, bulk-sync all sessions. |
| GET | /api/whatsapp/session/status/{sessionId} | Read the latest session status. |
| POST | /api/whatsapp/node/webhook | Inbound message + status events from the node service. |
curl, Postman, or webhook.site as a transparent proxy.throttle:api middleware but are still protected by Laravel's CSRF exemption + content-type checks.