Actions and triggers
Actions and triggers are Boost.space's native automation — they run inside Boost.space with no external account. A trigger decides when an automation fires; an action decides what happens. Manage them under System settings → Automations, or skip the settings entirely and describe the automation to the Agent Chat — it builds the whole thing for you.
Triggers — when it fires
| Trigger | Fires |
|---|---|
| Record created | When a record is added to the module |
| Record updated | When a record changes |
| Record deleted | When a record is removed |
| At scheduled time | On a schedule you define — no record event needed |
Record triggers are always scoped to a module, and can be narrowed further — to specific spaces, or with a more detailed condition — so the automation fires exactly when you mean.
At scheduled time covers every rhythm:
| Interval | You set |
|---|---|
| Minutes / Hours | Every N minutes or hours, from a start time |
| Days | Every N days, at a time |
| Weeks | Every N weeks, on the weekdays you pick, at a time |
| Months | Every N months, on a day of the month, at a time |
| One time | A single date and time |
Times are shown in your local timezone; the trigger fires at the same absolute moment for everyone in the system.
Conditions — narrowing a record trigger
A record trigger can fire on every change in its module, or only on records that match conditions you set. Build them in the trigger card — When this happens — below Spaces. The builder is there for Record created, Record updated and Record deleted, on a module that has fields to condition on.
- The first row opens with Where. Each row after it is joined to the one before with and or or, chosen per row.
- Add condition adds a row to the group you are in; Add group starts a new group. A group is the bracket — its rows resolve first, then the group joins the ones before it. That is how you say this, and either of those.
-
Joins read left to right, and and does not bind tighter than or:
A or B and Cis (A or B) and C. - Compare with Equals, Unequal, More than, Greater than or equal to, Less than or Less than or equal to. A status condition takes no operator: pick the status and it matches.
- Record updated has one more: Changed fires whenever that field changed, whatever it changed to. It takes no value, and only that trigger has it.
- Rollup and Formula fields are not offered as condition fields. Condition on the fields they are computed from instead.
Actions — what happens
| Action | What it does |
|---|---|
| System notification | Notifies the users you choose, inside Boost.space |
| Sends an email | |
| Webhook | Calls a URL with the event's data — for developers wiring external systems |
| Code | Runs your own Python in a secure sandbox — see Code automations |
Actions are defined once (under Actions) and attached to triggers, so one action can serve several automations.
Dynamic values
An email or a webhook does not have to send fixed text. Wrap a value in single braces and it is resolved from the record that fired the trigger, so one action serves every record it ever runs on.
Product {$entity->name} (ID {$entity->id}) changed status to {$entity->status['name']}.
Fix it here: {$entityLink}
Three things are available inside the braces:
| Expression | Resolves to |
|---|---|
{$entity->field} |
Any field of the triggering record, named exactly as the REST API names it |
{$entityLink} |
A ready-made URL that opens that record in the app — the one thing you want in a "go fix this" email |
{$steps[<actionId>]['output']} |
What an earlier Code action in the same run returned |
Field names are the API's names, not the column headings. Look a field up in the API reference — or fetch one record and read the JSON — and use the key you see there. Casing is not uniform across fields, so copy it rather than guess it.
Nested values are indexed, not chained. A status arrives as a small object, so it is
{$entity->status['name']} — square brackets and quotes. {$entity->status->name} renders nothing.
Custom fields are addressed by their numeric ID, because a custom field has no fixed name to reference:
{(array_column($entity->customFieldsValues, null, 'customFieldInputId')[123]['value'])}
You do not have to type that. In the email body, insert custom fields from the field picker in the editor toolbar and it writes the expression for you.
Where it works, and where it does not
| Field | Dynamic values |
|---|---|
| Email subject and body | yes |
| Notification text | yes |
| Webhook URL and headers | yes |
| Webhook body, when you author the payload yourself | yes |
| Webhook body, when you pick fields or send the whole record | no — the payload is built for you |
Only the email body has the field picker. Everywhere else you type the expression by hand, so copy one that works.
The obvious use is telling somebody a record needs them, with {$entityLink} so they land on it
directly. That is one leg of the
human-in-the-loop pattern — the notification that turns a queue
of leftovers into work somebody can actually pick up.
Scheduled triggers have no record. A trigger that fires on a schedule rather than on a record change has nothing to resolve against, and every expression is emitted literally — the recipient reads
{$entity->name}. Keep dynamic values for record triggers, and have scheduled automations pull what they need in a Code action instead.
Create one
- Open System settings → Automations.
- Under Triggers, click New trigger — name it, pick the module, and choose the trigger.
- Attach the automated action (or create one under Actions first).
Or open the Agent Chat and say what you want:
"When a record in Leads gets the status Won, email the sales channel a summary."
Next
- Code automations — when the action is your own logic
- Make scenarios and views — for moving data between apps
- Automation overview