Messages: email, SMS and WhatsApp
Reach people where they are: a booking confirmation by email, a reminder by SMS, an update on WhatsApp, or a notification inside the app. Messages are sent from workflows, so they go out whether or not anyone has the app open.
When to use which
| Channel | Good for | Setup |
|---|---|---|
| In-app notification | Staff alerts, "your order is ready" | None |
| Confirmations, digests, receipts | None: the platform sends it. Connect Resend, SendGrid, Gmail or SMTP to send from your own domain | |
| SMS | Reminders, codes | Connect Twilio |
| Updates in markets that live on WhatsApp | Connect WhatsApp | |
| Telegram | Team and community alerts | Connect a Telegram bot |
Step by step
- Pick the trigger: a new row, a status change, a schedule.
- Add a
notify,emailorintegrationaction, with{{field}}placeholders. - For SMS, WhatsApp and Telegram, connect the provider under the project's integrations. Until then the step is skipped.
- Apply, then run the workflow now from Backend, Workflows, Run now to test.
Code
In-app notification to one person
{ "action": "notify", "to": "technician_id", "title": "New job", "body": "{{site}} at {{time}}" }{ "id": "booking-confirmed", "title": "Confirm a booking by email",
"on": { "entity": "booking", "event": "created" },
"do": [{ "action": "email", "to": "member_id.email",
"subject": "You're booked", "body": "See you on the mat. Your booking is confirmed." }] }to is an email field on the row (email), a hop through a ref (member_id.email), or a persona id or staff for everyone with that role. Write plain text; it is sent in a clean branded layout.
SMS and WhatsApp
{ "action": "integration", "integration": "twilio", "call": "send_sms",
"props": { "from": "+15550100", "to": "{{phone}}", "body": "Reminder: {{title}} tomorrow at {{time}}" } }
{ "action": "integration", "integration": "whatsapp", "call": "sendMessage",
"props": { "phone_number_id": "1234567890", "to": "{{phone}}", "text": "Your table is ready" } }In a custom step or server function
await ctx.email({ to: String(member.email), subject: "Your week", body: lines.join("\n") });
ctx.notify({ title: "New booking", body: "Sunrise Flow is nearly full", role: "instructor" });Workflows written as code also have ctx.messages.sms, ctx.messages.whatsapp and ctx.messages.telegram.
Gotchas
- A failed send fails the run. It shows in the logs and can be replayed; it is never silently dropped.
- A schedule has no row, so its email goes to a role (
"to": "instructor"). For one email per person, loop in a custom step, as the todo tutorial does. - Never put a literal address in an
emailaction; use a field or a role. - Phone numbers need a country code for SMS and WhatsApp.