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 have your own AI agent build one over MCP.
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, a notification 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}
Inside the braces you can use:
| Expression | Resolves to |
|---|---|
{$entity->field} |
Any field of the triggering record, named exactly as the REST API names it |
{$statusName} |
The name of the record's status |
{$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 an email's subject and in a notification's text, click
Add variable; in the email body, click Add field in the editor toolbar, or type /. Pick a
field — or Link to record or Status name — and it goes in as a chip that is saved as the
expression.
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 |
The email and the notification have the picker. In a webhook 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. An action attached to a scheduled trigger does not offer the picker.
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 ask your own AI agent over MCP:
"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