The problem when you sell software to restaurants
If you run an online ordering or order management platform, you know the scene: the customer ordered at 7:40 PM, the order left at 8:15 PM and they called three times asking where the food was. The restaurant blames the driver, the driver blames the kitchen, and your platform's support team gets the ticket.
WhatsApp fixes this when the update goes out on its own, triggered by the status change that already exists in your system. But the restaurant doesn't want a generic platform number talking to its customers. It wants the message to come from the pizzeria's WhatsApp, the same one on its Instagram and on the packaging. So the model is one connection per restaurant, and your platform has to manage hundreds of them.
The order journey in messages
Every order status transition is a natural trigger. The table below shows how a delivery platform usually maps internal events to messages:
| Event in your system | Message to the customer | API feature |
|---|---|---|
| Order created | Item summary, total and payment method | Text |
| Restaurant accepted | Order confirmed, estimated prep time | Text |
| Being prepared | Short update, without repeating the summary | Text |
| Out for delivery | Driver name and tracking link | Link button (CTA) |
| Delivered | Thank-you note and an invitation to rate | List with ratings |
| Customer inactive for 30 days | This week's menu, only for people who opted in | Item list |
Notice that not every status deserves a message. Five updates on a 40-minute order is annoying. Many platforms let the restaurant choose which steps send a notification, and that becomes a setting in your dashboard, not in the API.
Menus as interactive lists
For repeat orders, a list works better than a link to the full menu. The customer taps "See menu", picks an item and your webhook receives the ID of the selected row. Each list takes up to 10 sections with up to 10 items each, which covers a daily menu or the best sellers nicely. For the full menu, keep sending the link.
import { DApi } from 'd-api-sdk'
const dapi = new DApi({ apiKey: process.env.DAPI_KEY! })
await dapi.interactive.sendList({
sessionId: 'rest-4821', // one connection per restaurant
to: '15551234567',
title: 'Ninth Street Kitchen',
description: "Today's dishes. Tap to choose.",
buttonText: 'See menu',
sections: [
{ title: 'Pasta', rows: [
{ rowId: 'sku-112', title: 'Lasagna bolognese', description: '$18.00' },
{ rowId: 'sku-118', title: 'Gnocchi marinara', description: '$15.00' },
] },
{ title: 'Drinks', rows: [
{ rowId: 'sku-301', title: 'Orange juice 16oz', description: '$5.00' },
] },
],
})When the customer picks something, you get a messages.received event with type: "list_response" and the selected_row_id field holding the SKU. The rest is your cart logic. More formats are covered in WhatsApp buttons and lists.
The lunch and dinner peaks
Food delivery has a usage curve few industries share: two short windows concentrate a large share of the day's orders. An integration that responds fine at 3 PM can stall at 8 PM, and the bottleneck is almost always on the platform side, which calls the API inside the same request that changes the order status.
Three decisions prevent that:
- Take sending out of the dashboard request. The restaurant clicks "out for delivery", your backend saves the status and publishes a job. A worker makes the API call. If something is slow, the kitchen dashboard doesn't freeze.
- Use async mode when it makes sense. Send calls accept
async: true, which returns acommandIdyou can check later at/api/v1/commands/{id}. - Isolate per restaurant. On D-API each connection runs in an isolated environment with its own IP, so the restaurant that had a problem at 8 PM doesn't drag the others down.
Implementation plan for your platform
- Restaurant onboarding: on the integrations screen of your dashboard, the owner clicks "Connect WhatsApp". Your backend calls
POST /api/v1/sessionswith asessionIdderived from the store ID and shows the QR code returned by/sessions/{id}/qr. - One webhook: set the same URL for every connection. The
sessionIdfield in the envelope tells you which restaurant each event came from. - Status mapping: tie each order transition to a text template the restaurant can edit, with variables like name, order number and ETA.
- Monitoring: handle
connection.statusand show an alert in the dashboard when a store disconnects. Better for the owner to find out at 5 PM than for the customer to find out at 8 PM. - Customer replies: messages that aren't list replies go to the restaurant's inbox, if your platform has one, or stay on the store phone.
Predictable cost for thin margins
Delivery platforms live on small tickets and lots of orders. If every status update has a cost, the bill grows with the restaurant's success, and someone has to decide which messages to cut. With the D-API WhatsApp API, billing is per connection, not per message, and the price per connection goes down as your restaurant base grows. The tiers are on the pricing page.
If your platform serves other industries besides restaurants, the product overview is in WhatsApp API for SaaS. For how delivery updates work in other operations, see order tracking on WhatsApp. And before you turn on a "this week's menu" campaign for your whole base, read how to avoid bans. Talk to sales for a 14-day free trial, with guided implementation in a WhatsApp group.
