Send a customer an order update on WhatsApp from any system — a custom checkout, an ERP, a courier integration, Zapier. Three endpoints, one workspace key. Each update is an approved utility template on your own WhatsApp Business account; Meta bills your account per message and Tendabot adds nothing. Shopify and WooCommerce stores get all of this without writing code — see WhatsApp on Tendabot.
tbk_. Send it as Authorization: Bearer./bots/<botId>/….{name}, {order}, {total} and {tracking}; a change is submitted to Meta as a new version and only replaces the old one once approved.Records the order, then queues the update. It sends as soon as the template is approved, or after the wait you set for that event (confirmed waits two minutes so a payment seconds later folds into one message).
curl -X POST https://platform.tendabot.com/api/v1/orders/events \
-H "Authorization: Bearer tbk_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acme:5512:shipped:1" \
-d '{
"botId": "YOUR_BOT_ID",
"event": "order.shipped",
"order": {
"externalId": "5512",
"number": "4821",
"status": "shipped",
"total": "68.00",
"currency": "GBP",
"paymentMethod": "card",
"orderUrl": "https://shop.example/orders/4821",
"customer": { "name": "Sara Khan", "phone": "+447700900123", "city": "Leeds", "country": "GB" },
"items": [{ "name": "10 ml bottle", "qty": 2 }],
"tracking": { "carrier": "Royal Mail", "number": "RM482177301GB", "url": "https://www.royalmail.com/track-your-item#/tracking-results/RM482177301GB" },
"occurredAt": "2026-09-05T10:12:00Z"
}
}'201 { "status": "queued", "event": "shipped", "eventId": "…", "scheduledAt": "2026-09-05T10:12:01.000Z" }
200 { "status": "duplicate", "event": "shipped", "reason": "already recorded for this order" }
200 { "status": "skipped", "event": "shipped", "eventId": "…", "reason": "no usable phone number on the order" }
200 { "status": "off", "event": "shipped", "reason": "order updates are switched off for this bot — enable them under Automations" }
401 { "error": "Send your workspace API key as \"Authorization: Bearer tbk_…\"." }
402 { "error": "This workspace has sent its 1,000 order updates for the month — upgrade in Billing for more." }
422 { "error": "order.customer.phone … / order.orderUrl must be an http(s) URL", "field": "order.orderUrl" }order.shipped or shipped. The full list is below.Idempotency-Key header to make that per shipment, per attempt, or whatever your system counts.occurredAt is more than 24 hours ago is recorded and never sent. Pass "backfill": true to import history the same way.https://platform.tendabot.com/t/<eventId>, which redirects to tracking.url, because a template button needs one fixed address.| event | Send it when | The customer gets |
|---|---|---|
| placed | The order is in | Thanks for your order #… Total … · View order |
| paid | Payment landed on an unpaid order | Payment of … received for order #… · View order |
| cod_confirm | A cash-on-delivery order is in | Please confirm your cash-on-delivery order #… · Confirm order / Cancel order |
| payment_pending | Still unpaid after your wait | Order #… is waiting for payment · Pay now |
| shipped | A tracking number exists | Order #… is on its way with … Tracking … · Track parcel |
| completed | Complete, no tracking number | Order #… is complete and on its way |
| delivered | The courier delivered it | Order #… has been delivered |
| cancelled | Cancelled or refunded | Order #… has been cancelled |
| feedback | After delivery | How was your order #…? · Great / Okay / Not good |
All nine are utility templates: no promotional wording, so they stay on Meta's cheapest rate. Each can be switched off per bot under Automations.
Records or updates an order without messaging anyone, so the AI can answer “where is my order” for a store that sends no updates, or ahead of the events that will.
curl -X PUT https://platform.tendabot.com/api/v1/orders/5512 \
-H "Authorization: Bearer tbk_YOUR_KEY" -H "Content-Type: application/json" \
-d '{ "botId": "YOUR_BOT_ID", "order": { "number": "4821", "status": "processing", "total": "68.00", "currency": "GBP",
"customer": { "name": "Sara Khan", "phone": "+447700900123" } } }'
200 { "ok": true, "storeOrderId": "…", "reachableOnWhatsApp": true }Every update decided for the order: sent, delivered, read, replied, or skipped with the reason. Works with a read-only key. Add &source=wordpress for orders that arrived through the plugin.
curl "https://platform.tendabot.com/api/v1/orders/5512/events?botId=YOUR_BOT_ID" -H "Authorization: Bearer tbk_YOUR_KEY"
200 {
"order": { "externalId": "5512", "number": "4821", "status": "shipped", "codDecision": null, "updatedAt": "…" },
"events": [
{ "id": "…", "event": "shipped", "status": "read", "template": "tb_order_shipped", "sentAt": "…", "deliveredAt": "…", "readAt": "…" },
{ "id": "…", "event": "placed", "status": "skipped", "reason": "older than 24 hours when it arrived" }
]
}A tap on Confirm order, Cancel order, or a feedback button reaches you here. Add a webhook under Bot → Settings → Webhooks and tick order.replied; it is signed with your webhook secret like every Tendabot webhook. WooCommerce stores also get the decision written onto the order by the plugin.
{
"event": "order.replied",
"botId": "…", "eventId": "…", "externalId": "5512", "orderNumber": "4821", "source": "api",
"decision": "confirm", // confirm | cancel | feedback
"score": 3, // feedback only: 1 not good · 2 okay · 3 great
"customerWaId": "447700900123",
"at": "2026-09-05T10:20:31.000Z"
}send_order_update takes the same fields, so an assistant can send one without an HTTP call. See the tool reference.