Connect WhatsApp and marketing tools
Send every AlliDesk event — points earned, COD confirmation, a return approved, a warranty claim — to Spur, BIK, Interakt, WATI, AiSensy, Zapier or any tool with a webhook URL. Your tool sends the WhatsApp message from its own approved templates.
How it works
AlliDesk does not hold a WhatsApp account of its own. Your WhatsApp tool already has your number, your approved templates and your flows. You give AlliDesk the tool's webhook URL; when an event you picked happens, AlliDesk sends it there as JSON within seconds, and the tool's flow sends the message.
- In your tool, add a webhook trigger to a flow, journey or workflow, and copy the URL (and token, if it shows one).
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside your tool, paste it, tick the events and Save.
- Press Send test event with your own number. Your tool shows what arrived; map
phone,nameand the fields underdatainto your template. - Switch the flow on in your tool. Every delivery shows under Recent deliveries in AlliDesk, with the tool's answer.
You can connect up to ten tools, and one tool more than once — for example one Spur flow for loyalty and another for returns. Only a store owner can connect, change or remove a tool.
Spur
Start a Spur WhatsApp flow from any AlliDesk event.
- In Spur open Automations → Automation Flows → Create New Flow.
- Pick WhatsApp as the channel and Webhook as the trigger. Spur shows the flow's webhook URL — copy it.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside Spur, and paste it, tick the events you want, and Save.
- Press Send test event — the tool now has a sample to map.
- Back in Spur press Test Webhook → Check for Received Requests. Map phone and name, then use fields such as {{trigger.data.points}} in your template.
URL From the flow's Webhook trigger in Spur. Token Spur's webhook URL needs no token. Body AlliDesk's standard JSON (below). Phone Spur needs a phone number, so an event about someone with no phone is not sent to it (it shows as Skipped). BIK
Trigger a BIK journey on WhatsApp from any AlliDesk event.
- In BIK open the Journey Builder and start a journey on the WhatsApp channel with Webhook as the trigger.
- Copy the webhook URL BIK generates for that journey.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside BIK, and paste it, tick the events you want, and Save.
- Press Send test event — the tool now has a sample to map.
- In BIK map phone number and email as the unique IDs, then pick the other fields from the variable picker.
URL From the journey's Webhook trigger in BIK. Token Only if BIK shows you one. Body AlliDesk's standard JSON (below). Phone BIK needs a phone number, so an event about someone with no phone is not sent to it (it shows as Skipped). Interakt
Every event lands on the customer's Interakt profile, ready for campaigns.
- In Interakt open Settings → Developer Setting and copy the Secret Key.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside Interakt, and paste it as it is — Interakt already encodes it — tick the events, and Save.
- Press Send test event, then open that customer in Interakt: the event (for example “Points earned”) shows with its details as traits.
- Use those events when you build campaigns in Interakt.
URL https://api.interakt.ai/v1/public/track/events/Token Interakt → Settings → Developer Setting → Secret Key. Sent as Authorization: Basic <key>. Body Interakt's Track Events format (below). Phone Interakt needs a phone number, so an event about someone with no phone is not sent to it (it shows as Skipped). WATI through Pabbly Connect
Send a WATI template for any event, through a Pabbly Connect workflow.
- In Pabbly Connect create a workflow with Webhook by Pabbly as the trigger and copy its webhook URL.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside WATI, and paste it, tick the events you want, and Save.
- Press Send test event so Pabbly captures a sample.
- Add the WATI action that sends a template message, and map phone and the event's fields into the template.
URL From the Webhook by Pabbly trigger. Token Pabbly's webhook URL needs no token. Body AlliDesk's standard JSON (below). Phone WATI needs a phone number, so an event about someone with no phone is not sent to it (it shows as Skipped). AiSensy through Pabbly Connect
Send an AiSensy template for any event, through a Pabbly Connect workflow.
- In Pabbly Connect create a workflow with Webhook by Pabbly as the trigger and copy its webhook URL.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside AiSensy, and paste it, tick the events you want, and Save.
- Press Send test event so Pabbly captures a sample.
- Add the WhatsApp by AiSensy action that sends a template message, and map phone and the event's fields.
URL From the Webhook by Pabbly trigger. Token Pabbly's webhook URL needs no token. Body AlliDesk's standard JSON (below). Phone AiSensy needs a phone number, so an event about someone with no phone is not sent to it (it shows as Skipped). Pabbly Connect
Catch events in Pabbly and pass them to any app it connects.
- In Pabbly Connect create a workflow with Webhook by Pabbly as the trigger and copy its webhook URL.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside Pabbly Connect, and paste it, tick the events you want, and Save.
- Press Send test event so Pabbly captures a sample, then add the actions you want.
URL From the Webhook by Pabbly trigger. Token Pabbly's webhook URL needs no token. Body AlliDesk's standard JSON (below). Zapier
Start a Zap from any event and reach WATI, Zoko or thousands of apps.
- In Zapier create a Zap with Webhooks by Zapier → Catch Hook as the trigger and copy the webhook URL. Webhooks by Zapier needs a paid Zapier plan.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside Zapier, and paste it, tick the events you want, and Save.
- Press Send test event, then in Zapier test the trigger to pull in the sample and add your action.
URL From Webhooks by Zapier → Catch Hook. Token Zapier's catch hook needs no token. Body AlliDesk's standard JSON (below). Make
Run a Make scenario from any event.
- In Make start a scenario with Webhooks → Custom webhook, add a webhook and copy its address.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside Make, and paste it, tick the events you want, and Save.
- Press Send test event while Make is listening, so it learns the data structure.
URL From Webhooks → Custom webhook. Token Make's custom webhook address needs no token. Body AlliDesk's standard JSON (below). n8n
Start an n8n workflow from any event.
- In n8n add a Webhook node, set the method to POST, and copy the Production URL.
- If you set Header Auth on the node, put the same header name and value in Token below.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside n8n, and paste it, tick the events you want, and Save.
- Activate the workflow, then press Send test event.
URL The Webhook node's Production URL. Token Only with Header Auth on the node. Body AlliDesk's standard JSON (below). Custom webhook
Any other WhatsApp tool, CRM or server that gives you a webhook URL.
- In your tool, create an incoming webhook (it may be called a webhook trigger or API trigger) and copy its URL and token.
- In AlliDesk open Settings → Integrations → WhatsApp & marketing tools, press Connect beside Custom webhook, and paste the URL, and the token with the header your tool expects. Most use Authorization: Bearer.
- Tick the events, Save, and press Send test event to see exactly what arrives.
- Map phone, name and the fields under data into your message. Every request is signed, so your server can check it came from AlliDesk.
URL Must start with https://. Token Leave blank if your tool needs none. Body AlliDesk's standard JSON (below). What AlliDesk sends
One
POSTper event, per person, per connection, withContent-Type: application/json. Only HTTPS URLs on the public internet are accepted.X-AlliDesk-EventThe event key, e.g. loyalty.points_earned. X-AlliDesk-DeliveryA unique id for this delivery; the same on every retry, so you can ignore a repeat. X-AlliDesk-TimestampUnix seconds when it was sent. X-AlliDesk-Signaturesha256=HMAC of timestamp, a dot and the body, with the connection's signing secret. AuthorizationYour token, when you saved one: Bearer, Basic, or exactly as typed, under the header name you chose. Standard body{ "event": "loyalty.points_earned", "event_name": "Points earned", "event_id": "cmh3w2k0p0004", "occurred_at": "2026-09-17T10:42:07.000Z", "test": false, "audience": "customer", "phone": "919876543210", "phone_national": "9876543210", "country_code": "91", "name": "Asha Verma", "first_name": "Asha", "email": "asha@example.com", "store": { "name": "Your store", "domain": "yourstore.in", "currency": "INR" }, "data": { "first_name": "Asha", "points": "120", "points_name": "points", "reason": "a product review", "balance": "820", "account_url": "https://yourstore.in/apps/account" } }Interakt body{ "phoneNumber": "9876543210", "countryCode": "+91", "event": "Points earned", "traits": { "first_name": "Asha", "points": "120", "points_name": "points", "reason": "a product review", "balance": "820", "account_url": "https://yourstore.in/apps/account", "allidesk_event": "loyalty.points_earned", "allidesk_event_id": "cmh3w2k0p0004", "store_name": "Your store", "email": "asha@example.com" } }phoneCountry code and number, digits only (919876543210) — the shape Spur and most tools take. Also split into phone_national and country_code. Null when AlliDesk has no number. name,first_name,emailThe customer, or for a team alert your store's name and the alert's email. audiencecustomer, or store_team for alerts meant for you. dataThe event's own fields, as text or numbers — listed for every event below. testtrue for a test event sent from the settings page. Filter these out of a live flow if you need to. Every event (44)
Tick any of these on a connection. A new event AlliDesk adds appears here and on the settings page.
Sign-in
login.otpabout a customerSign-in code. The one-time code a customer asked for to sign in to their account. data:codestore_nameminutesOrders and accounts
orders.cod_confirm_requestedabout a customerConfirm your cash-on-delivery order. Asks the customer to confirm a COD order before it is processed. data:first_nameorder_nameorder_totalconfirm_urlaccounts.inviteabout a customerAccount invitation. Invites a customer to create (or sign in to) their account. Used by campaigns and the Invite button. data:first_namestore_nameaccount_urllogin_urlReturns and exchanges
requests.receivedabout a customerRequest received. Confirms to the customer that their return, exchange or replacement request is in. data:first_nameorder_namerequest_typerequest_statusstore_nameaccount_urlrequests.status_changedabout a customerRequest status update. Sent to the customer whenever their request moves: approved, pickup booked, received, settled, rejected. data:first_nameorder_namerequest_typerequest_statusnotestore_nameaccount_urlLoyalty
loyalty.points_earnedabout a customerPoints earned. Tells the customer when an action such as a review, birthday or sign-up added points. data:first_namepointspoints_namereasonbalanceaccount_urlloyalty.tier_upabout a customerMoved up a tier. Congratulates the customer when they reach a new tier. data:first_nametier_nametier_benefitspoints_namestore_nameaccount_urlReferrals
referrals.rewardedabout a customerReferral reward. Tells the referrer their friend's order went through and their reward is in. data:first_namefriend_namerewardstore_nameaccount_urlGST invoices
gst.invoiceabout a customerGST invoice. The tax invoice for an order, with the PDF attached. data:first_namestore_nameorder_nameinvoice_numberinvoice_dateamountinvoice_urlgst.estimateabout a customerGST estimate. A quotation for the customer, with the PDF attached and a link to accept it from their account. data:first_namestore_nameinvoice_numberinvoice_dateamountvalid_untilinvoice_urlaccount_urlgst.credit_noteabout a customerGST credit note. The credit note issued when an order is refunded, with the PDF attached. data:first_namestore_nameorder_nameinvoice_numberinvoice_dateamountinvoice_urlgst.statementabout a customerGST statement. A period's purchases as one statement, with the consolidated tax summary attached. Sent when someone asks for it, never on its own. data:first_namestore_nameperiodinvoice_countitem_countamounttax_amountbalance_duestatement_dateaccount_urlReviews
reviews.requestabout a customerReview request. Asks the customer to review what they bought, a few days after the order lands. data:first_namestore_nameproductorder_namereview_urlreviews.couponabout a customerThank-you coupon. Sends the discount code a customer earned for writing a review. data:first_namestore_namecoderewarddaysStore alerts
reviews.alertto your teamlow-rated review. Tells your team when a review comes in at or below the rating you set. data:store_nameratingproductbodystatusalerts.low_stockto your teamlow stock. A variant fell to or below the threshold. data:productvariantavailablestore_namealerts.new_requestto your teamnew request. A customer raised a return, exchange or replacement. data:customer_nameorder_namerequest_typeamountdashboard_urlstore_namealerts.cod_unconfirmedto your teamCOD order still unconfirmed. A cash-on-delivery order has waited longer than the threshold without confirmation. data:order_namehoursstore_namewarranty.merchant_new_claimto your teamNew claim filed. Alert to the merchant when a claim comes in. data:customer_nameclaim_numberproduct_titleissue_typedescriptiondashboard_urlwarranty.merchant_new_registrationto your teamNew marketplace registration. Alert when a customer registers a marketplace purchase for review. data:customer_nameproduct_titlemarketplacepurchase_datedashboard_urlWishlist
wishlist.price_dropabout a customerPrice drop on a saved item. A product on the customer's wishlist got cheaper. data:first_nameitemsstore_namewishlist_urlwishlist.back_in_stockabout a customerSaved item back in stock. A product on the customer's wishlist is available again. data:first_nameitemsstore_namewishlist_urlWarranty
warranty.activated_purchaseabout a customerWarranty activated on purchase. Sent when a store purchase is registered on its own. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlwarranty.activated_manualabout a customerWarranty activated — manual registration. Sent when a customer's own registration (marketplace or shop purchase) is approved or activates. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlwarranty.registration_rejectedabout a customerMarketplace registration rejected. Sent when a registration cannot be verified. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlreasonwarranty.extended_purchasedabout a customerExtended warranty purchased. Sent when a customer buys an extended plan. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlwarranty.expiring_7about a customerWarranty expiring in 7 days. Urgent reminder a week before expiry. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlextend_linewarranty.claim_receivedabout a customerClaim received. Immediate confirmation after a claim is filed. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionsla_hourswarranty.claim_approvedabout a customerClaim approved. Sent when the claim is approved, with the resolution. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionnext_stepwarranty.claim_deniedabout a customerClaim not approved. Sent when the claim is rejected, with the reason. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionreasonwarranty.claim_info_neededabout a customerMore information needed. Sent when the team asks the customer for photos, a video or details. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionrequestwarranty.claim_completedabout a customerClaim completed and closed. Final note when a claim is resolved and closed. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionwarranty.service_center_assignedabout a customerService centre assigned. Sent with the centre's address once a repair is routed there. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutioncenter_namecenter_addresscenter_phonecenter_hourswarranty.item_readyabout a customerItem ready for pickup. Sent when the repair is done and the item can be collected. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutioncenter_namecenter_hourswarranty.home_visit_scheduledabout a customerHome visit scheduled. Sent when a technician visit is booked. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionvisit_datevisit_windowtechnicianwarranty.replacement_with_returnabout a customerReplacement (return required). Sent when a replacement ships and the old unit must be returned. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionreplacement_orderreturn_instructionswarranty.refund_issuedabout a customerRefund or store credit issued. Sent when the claim is settled in money. data:first_namestore_nameproduct_titleplan_nameexpires_ondays_leftaccount_urlclaim_numberclaim_statusclaim_urlresolutionamountsettlement_noteMembership
membership.joinedabout a customerWelcome to the programme. Sent when a membership starts, whether it was bought or granted. data:first_namestore_nameprogram_nameplan_namebenefitsexpires_ondays_leftsaved_totalrenew_urlaccount_urlmembership.expiringabout a customerMembership running out. Sent on the reminder days set under Membership → Settings. data:first_namestore_nameprogram_nameplan_namebenefitsexpires_ondays_leftsaved_totalrenew_urlaccount_urlmembership.expiredabout a customerMembership ended. Sent the day a membership lapses. data:first_namestore_nameprogram_nameplan_namebenefitsexpires_ondays_leftsaved_totalrenew_urlaccount_urlSubscriptions
subscriptions.startedabout a customerSubscription started. Sent once the customer has authorised the mandate and the first order is on its way. data:first_namestore_nameprogram_nameplan_namescheduleamountnext_charge_onreasonmanage_urlsubscriptions.reminderabout a customerA charge is coming. Sent the set number of days before each charge. Off by default: most shoppers would rather not hear from you every cycle. data:first_namestore_nameprogram_nameplan_namescheduleamountnext_charge_onreasonmanage_urlsubscriptions.payment_failedabout a customerPayment did not go through. Sent when a cycle's charge fails. The app tries again over the next few days. data:first_namestore_nameprogram_nameplan_namescheduleamountnext_charge_onreasonmanage_urlsubscriptions.cancelledabout a customerSubscription ended. Sent when a subscription stops, whether the customer stopped it or the shop did. data:first_namestore_nameprogram_nameplan_namescheduleamountnext_charge_onreasonmanage_urlWho an event is about
- A customer event carries that customer's phone, name and email, from their account on your store.
- A store alert (low stock, a new return, a low-rated review, a COD order unconfirmed) goes once for each phone number in Alerts → Recipients, or else once for each of your Team WhatsApp numbers on the settings page.
- A customer who answered no to “Send order updates by SMS or WhatsApp” on their account gets nothing through your tools; the delivery shows as Skipped. A sign-in code they asked for is the exception.
- Spur, BIK, Interakt, WATI and AiSensy need a phone, so an event with no number is skipped for them.
- The Sign-in code event carries the code itself: tick it only on a tool that sends it straight to the customer.
Checking the signature
Tools like Spur and Zapier do not need this. If the URL is your own server, check each request came from AlliDesk: copy the signing secret from the connection's Advanced section, then compare signatures on the raw body.
import { createHmac, timingSafeEqual } from "node:crypto"; // Express: app.post("/allidesk", express.raw({ type: "application/json" }), handler) export function fromAllidesk(rawBody, headers, signingSecret) { const timestamp = headers["x-allidesk-timestamp"]; const received = String(headers["x-allidesk-signature"] ?? "").replace(/^sha256=/, ""); // Refuse anything older than five minutes, so a copied request cannot be replayed. if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false; const expected = createHmac("sha256", signingSecret).update(`${timestamp}.${rawBody}`).digest("hex"); return received.length === expected.length && timingSafeEqual(Buffer.from(received), Buffer.from(expected)); }Retries and the log
- Any 2xx answer is delivered. Answer quickly — AlliDesk waits 10 seconds by default (3 to 30 in Advanced).
- A 5xx, 408, 429, a timeout or a connection error is tried again up to 5 times in all, after about ½, 1, 2, 4 minutes.
- Other 4xx answers are not retried: they mean the URL or token is wrong. A redirect is not followed — paste the final URL.
- Recent deliveries on the settings page shows each one with the tool's answer, for 30 days. The body is not stored, since it can carry a sign-in code.
- Switching a connection off stops events at once, including retries still waiting.
When nothing arrives
Nothing in Recent deliveries The event is not ticked on the connection, the connection is off, or the event has not happened yet. Send a test event to check the connection. Skipped No phone number for that person and the tool needs one, or the customer said no to WhatsApp updates. HTTP 401 or 403 The token is wrong or missing. For Interakt, paste the Secret Key exactly as Interakt shows it. HTTP 404 The tool's webhook URL changed, for example after the flow was recreated. Paste the new one. Delivered, but no WhatsApp The request reached your tool; check the flow is switched on, the template is approved and phone is mapped to the recipient. Still stuck? Write to hello@allidesk.com with the connection's name and the time of the delivery.
Write to hello@allidesk.com. A person replies, usually within one business day.