01 / Automation reference
How a condition reads its event
Every path starts with trigger. and uses dots to address nested data. For example, trigger.deal.value reads the value supplied by the deal event that started this run. It does not look up an arbitrary record elsewhere in the workspace. Use the field picker for declared paths; use Custom path only for form answers or sender-defined JSON.
A path the selected trigger does not send resolves to an empty value. The selected operator determines the branch: an empty-value check can pass, and a not-equals condition may also pass. If a rule never passes, check the event and its path before changing the threshold. Similar business labels do not imply identical paths: a proposal uses total_value while a deal uses value.
02 / Automation reference
Use the declared type
The tables identify strings, numbers, booleans and objects. Match the comparison to the intended value. An object such as submission.data contains answers; reading one nested answer differs from comparing the entire object. Test a representative event and inspect both matching and non-matching cases.
Fields belong to the selected trigger. A deal event does not supply task data simply because both records exist in the workspace. Keep the intended business decision separate from the transport structure that makes it possible.
03 / Automation reference
Deal won (deal_won)
Someone changes a CRM deal's stage to Won by editing the deal. It does not fire when a signed proposal, a Convert to Project or an automation action moves the deal to Won; a signature fires Proposal accepted instead. The payload supplies the deal, value, contact email, client identifier and workspace identifier. It does not promise the whole contact or company record.
| Path | What it holds | Type |
|---|---|---|
| trigger.deal.id | Deal ID | string |
| trigger.deal.title | Deal title | string |
| trigger.deal.value | Deal value | number |
| trigger.deal.contact_email | Contact email | string |
| trigger.deal.client_id | CRM company ID | string |
| trigger.workspace_id | Workspace ID | string |
04 / Automation reference
Proposal accepted (proposal_accepted)
A client accepts a proposal using its public link. The payload identifies that proposal and total value. It does not automatically supply a project or task payload for later actions.
| Path | What it holds | Type |
|---|---|---|
| trigger.proposal.id | Proposal ID | string |
| trigger.proposal.title | Proposal title | string |
| trigger.proposal.total_value | Proposal total value | number |
| trigger.proposal.client_id | Client ID | string |
| trigger.workspace_id | Workspace ID | string |
05 / Automation reference
Task status changed (task_status_changed)
A task changes status, including a change to Done. This is broader than completion. Use trigger.task.new_status equals done when the rule should only react to that destination status.
| Path | What it holds | Type |
|---|---|---|
| trigger.task.id | Task ID | string |
| trigger.task.title | Task title | string |
| trigger.task.old_status | Previous status | string |
| trigger.task.new_status | New status | string |
| trigger.task.project_id | Project ID | string |
| trigger.task.is_milestone | Is milestone | boolean |
| trigger.workspace_id | Workspace ID | string |
06 / Automation reference
Invoice paid (invoice_paid)
An invoice is paid through Stripe. Manually marking an invoice paid does not fire this trigger. Test the payment path expected by the workflow rather than assuming a status edit is equivalent.
| Path | What it holds | Type |
|---|---|---|
| trigger.invoice.id | Invoice ID | string |
| trigger.invoice.client_id | Client ID | string |
| trigger.invoice.amount | Invoice amount | number |
| trigger.workspace_id | Workspace ID | string |
07 / Automation reference
Form submitted (form_submitted)
Someone submits a form. Individual answers use trigger.submission.data.<field>, replacing <field> with the actual question key. A question keyed budget uses trigger.submission.data.budget. Retest rules after changing question keys or answer formats.
| Path | What it holds | Type |
|---|---|---|
| trigger.form.id | Form ID | string |
| trigger.form.title | Form title | string |
| trigger.submission.id | Submission ID | string |
| trigger.submission.data | Submission data (object) | object |
| trigger.submission.submitter_email | Submitter email | string |
| trigger.submission.submitter_name | Submitter name | string |
| trigger.workspace_id | Workspace ID | string |
08 / Automation reference
Booking created (booking_created)
This trigger exists in the platform but is not currently offered in the automation editor, so you cannot build a workflow on it yet. Its fields are listed for reference.
A visitor books a slot on a booking page. Starts-at is an ISO-formatted string. Booking ID and booking-page ID identify different records. Keep local-time interpretation separate from the timestamp format.
| Path | What it holds | Type |
|---|---|---|
| trigger.booking.id | Booking ID | string |
| trigger.booking.visitor_name | Visitor name | string |
| trigger.booking.visitor_email | Visitor email | string |
| trigger.booking.starts_at | Starts at (ISO) | string |
| trigger.booking_page.id | Booking page ID | string |
| trigger.booking_page.title | Booking page title | string |
| trigger.workspace_id | Workspace ID | string |
09 / Automation reference
Scheduled (scheduled)
The configured schedule comes due. This payload deliberately carries no workspace_id and no changed-record data. It says that a time arrived; it does not identify a current project, task or client.
| Path | What it holds | Type |
|---|---|---|
| trigger.scheduled | Scheduled run | boolean |
| trigger.cron | Cron expression | string |
| trigger.fired_at | Fired at (ISO) | string |
10 / Automation reference
Webhook (webhook)
An external sender posts JSON to the automation URL. There is no fixed field list. Read top-level keys as trigger.<key> and nested properties with dots, such as trigger.customer.email. Define the expected body with the sender and test absent or differently typed values.
11 / Automation reference
Project completed (project_completed)
This trigger is not active. It appears in the editor, but completing a project does not run the automation. Choose a supported trigger for your workflow.
12 / Automation reference
Worked conditions
These thresholds are illustrative routing examples, not recommended qualification policies. Test an event above the threshold, another below it and an event missing the field. Inspect the actual resulting action, not only its run status.
| Intent | Trigger | Condition |
|---|---|---|
| Escalate a sample large deal | Deal won | trigger.deal.value greater than 5000 |
| React to completion | Task status changed | trigger.task.new_status equals done |
| Route form intake | Form submitted | trigger.submission.data.budget greater than 2000 |
13 / Automation reference
Troubleshoot in a reliable order
First confirm the event happened through the implemented path. Compare the condition with the selected trigger table. Check custom form keys and sender-defined bodies independently because neither has a universal schema. Finally review the type, operator and comparison value. This avoids changing business logic to compensate for missing data.
The declared field list was checked against backend/app/services/automation_trigger_fields.py on September 23, 2026. The previous public reference was dated August 21, 2026. This verifies the reference against the current map, not execution of a particular configured automation. Inspect real outcomes before relying on a workflow.
THE PRACTICAL DETAILS
Questions, answered.
Why is there no fixed webhook table?
The sender defines the JSON body. Use paths that match the actual submitted keys and nested objects.
Does every trigger include workspace_id?
No. Scheduled events contain only the scheduled marker, cron expression and fired-at timestamp. Webhooks depend on the supplied body.
How do I read a form answer?
Use trigger.submission.data.<field>, replacing <field> with the actual question key. Check the submitted data for the field key; it may differ from the visible question label.
Does project_completed work today?
No. It is declared but not dispatched in the current backend. Do not use it for a live dependency.