Workflows
When something happens, do something about it.
How a workflow runs
A workflow is a trigger, an optional set of conditions and an ordered list of steps. When the trigger fires, conditions are checked against the event; if they all hold, a run starts and the steps execute in order.
Every run is recorded with each step's input, output, error and attempt count. That run log is where you look first when something does not fire.
A workflow only ever sees events that happened after it was created, so switching one on never floods your log with history.
Triggers
Time-relative triggers move with the meeting and are cancelled with it.
| Trigger | Fires |
|---|---|
| booking.created | A booking is made |
| booking.rescheduled | A booking is rescheduled |
| booking.cancelled | A booking is cancelled |
| booking.no_show | An invitee does not show up |
| sync.error | A calendar fails to sync |
| sync.drift_detected | Sync drift is detected |
| account.connected | A calendar account is connected |
| account.needs_reauth | An account needs reconnecting |
| workflow.failed | A workflow run fails |
| booking.before | Before a meeting starts |
| booking.after | After a meeting ends |
| schedule | On a schedule |
Steps
Steps that cost money are metered against your monthly credits.
| Action | What it does | Needs |
|---|---|---|
| send_email | Email the invitee, the host, or anyone else. | — |
| send_sms | Text the invitee or the host. Uses your monthly SMS credits. | sms credits |
| wait | Pause before the next step. | — |
| http_request | Send an HTTP request to any service. The response is available to later steps. | — |
| cancel_booking | Calls off the meeting this run is about, and tells both sides. | — |
| slack_post | Send a message to a channel in your connected workspace. | slack |
| crm_upsert | Finds the HubSpot contact by email, or creates it. | hubspot |
| crm_log_meeting | Records this booking against the contact in HubSpot. | hubspot |
| ai_generate | Generates text for a later step to send. Uses your monthly AI credits. | ai credits |
| ai_brief | Summarises who you are meeting and what they said. Uses AI credits. | ai credits |
Placeholders
Any text field can carry `{{path}}` placeholders, filled from the run's context. An unknown path renders empty and is reported in the run log rather than failing silently.
Later steps can read earlier ones: `{{steps.0.output.text}}`.
{{booking.inviteeName}} Their full name
{{booking.inviteeFirstName}} Just the first name
{{booking.inviteeEmail}} Their email
{{booking.date}} Friday 3 October 2026
{{booking.time}} 14:30, in their zone
{{booking.hostTime}} The same moment, in yours
{{booking.rescheduleUrl}} Their reschedule link
{{booking.cancelUrl}} Their cancel link
{{booking.answers.<key>}} An answer to a booking question
{{eventType.title}} The event type's name
{{host.name}} Your nameIdempotency
Each step carries a key derived from its run and its position, and actions with external side effects pass it on. A retried step will not text someone twice.
A step that fails for a reason a retry cannot fix — a malformed address, a missing channel, a 4xx — stops immediately and says so, instead of burning the retry budget.