> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synti.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Automations

> Trigger shell commands or new agent sessions automatically when events happen inside Synti.

Automations let Synti react to things that happen on your machine without you lifting a finger. When an event fires — a label is added, a session changes status, a timer ticks — Synti can run a shell command or spin up a brand-new session with a prompt you define. Everything runs locally, and each automation is a small block of JSON you can read, edit, and version.

## How automations work

Every automation pairs a **trigger** (the event to listen for) with one or more **actions** (what to do when it fires). Optional **matchers** and **conditions** narrow things down so an automation only runs when it should.

The fastest way to create one is to describe it in plain language. Tell the agent something like "notify me whenever a session gets flagged" and it writes the configuration for you. You can also edit the underlying file directly, or manage automations from the sidebar.

Automations live per workspace at:

```text theme={null}
~/.synti/workspaces/{workspaceId}/automations.json
```

Changes take effect immediately — no restart required.

<Tip>
  Because automations are plain JSON, they travel well. Commit the file alongside a project or copy it between machines to reuse a setup.
</Tip>

## Managing automations

The automations panel in the sidebar lists everything you've defined. From there you can enable or disable an automation, duplicate it, delete it, run a test, and open its run history. To pause an automation without losing it, set `"enabled": false` on its matcher rather than deleting it.

## Triggers

Synti distinguishes two families of events. **App events** describe things happening in the app around a session and can run either kind of action. **Agent events** fire during the agent's own execution loop and can only run command actions.

### App events

| Event                      | Fires when                                    |
| -------------------------- | --------------------------------------------- |
| `LabelAdd` / `LabelRemove` | A label is added to or removed from a session |
| `LabelConfigChange`        | The label configuration changes               |
| `PermissionModeChange`     | A session's permission mode changes           |
| `FlagChange`               | A session is flagged or unflagged             |
| `SessionStatusChange`      | A session moves to a new workflow status      |
| `SchedulerTick`            | A scheduled (cron) moment is reached          |

### Agent events

`PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `UserPromptSubmit`, `SessionStart`, `SessionEnd`, `Stop`, `SubagentStart`, `SubagentStop`, `Notification`, `PreCompact`, `PermissionRequest`, and `Setup` cover the agent's tool-use and session lifecycle.

## Actions

**Command actions** run a shell command. Event details are exposed as environment variables, and each command supports an optional timeout (default 60 seconds) after which it is killed.

**Prompt actions** start a new session with a prompt you write. You can `@mention` sources to activate them, attach labels for organization, and override the LLM connection, model, and thinking level for that one session. Prompt actions are available on App events only.

```json automations.json theme={null}
{
  "automations": [
    {
      "trigger": "FlagChange",
      "matcher": "true",
      "enabled": true,
      "actions": [
        {
          "type": "command",
          "run": "osascript -e 'display notification \"Session $SYNTI_SESSION_NAME was flagged\"'",
          "timeout": 30
        }
      ]
    }
  ]
}
```

### Environment variables

Command actions receive the event context through variables:

| Variable                                                     | Available for           |
| ------------------------------------------------------------ | ----------------------- |
| `SYNTI_EVENT`, `SYNTI_EVENT_DATA`                            | All events              |
| `SYNTI_SESSION_ID`, `SYNTI_SESSION_NAME`                     | All session events      |
| `SYNTI_WORKSPACE_ID`                                         | All events              |
| `SYNTI_LABEL`                                                | Label events            |
| `SYNTI_OLD_MODE`, `SYNTI_NEW_MODE`                           | Permission mode changes |
| `SYNTI_OLD_STATE`, `SYNTI_NEW_STATE`                         | Status changes          |
| `SYNTI_TOOL_NAME`, `SYNTI_TOOL_INPUT`, `SYNTI_TOOL_RESPONSE` | Tool events             |
| `SYNTI_LOCAL_TIME`, `SYNTI_LOCAL_DATE`                       | Scheduler ticks         |

Labels on prompt-spawned sessions support variable expansion, so you can build dynamic tags like `"priority::${SYNTI_LABEL}"`.

## Scheduling

Use the `SchedulerTick` trigger with a standard cron expression — `minute hour day-of-month month day-of-week` — to run on a timer. Provide an IANA timezone name (for example `America/New_York`) so schedules behave correctly across regions.

```json theme={null}
{
  "trigger": "SchedulerTick",
  "cron": "0 9 * * 1-5",
  "timezone": "America/New_York",
  "actions": [
    { "type": "prompt", "prompt": "Summarize yesterday's flagged sessions." }
  ]
}
```

Common patterns: `0 9 * * 1-5` (weekdays at 9 AM), `*/15 * * * *` (every 15 minutes).

## Matchers and conditions

**Matchers** filter which event values an automation reacts to. Most events use a regex pattern; omitting the matcher triggers on every event of that type. Patterns are capped at 500 characters and screened for catastrophic-backtracking (ReDoS) risk. `SchedulerTick` uses a cron expression instead of a regex.

**Conditions** are optional filters evaluated after the matcher passes but before actions run. Every condition in the list must pass (implicit AND).

* **Time conditions** check `after`/`before` windows and weekday restrictions in a given timezone. Ranges that wrap past midnight (such as `22:00`–`06:00`) are supported.
* **State conditions** inspect event fields using exact match, `from`/`to` transition checks, `contains` membership, or `not_value` negation.
* **Logical composition** with `and`, `or`, and `not` can nest up to 8 levels deep.

<Note>
  Unknown condition types fail closed — they evaluate to false rather than passing silently. An invalid timezone falls back to the system's local time.
</Note>

## Permissions and safety

Automations run in one of two permission modes. **Safe mode** (the default) checks each command against an allowlist. **Allow-all** bypasses those checks and should be reserved for automations you fully trust.

Synti also guards against common footguns: values you don't control are escaped to prevent shell injection, regex length limits and ReDoS screening protect the matcher engine, rate limiting stops runaway loops, and command timeouts are enforced with a hard kill.

For more on how the agent's own tool permissions work, see [Permissions](/core-concepts/permissions).

## Rate limits

`SchedulerTick` may fire at most 60 times per minute (one per second). All other events are capped at 10 fires per minute. Events beyond the limit within a 60-second window are dropped.

## Validation and history

Ask the agent to validate `automations.json` and it will flag syntax errors, unknown event names, empty action lists, malformed cron or regex, missing label references, and condition problems.

Each automation keeps its last 20 runs (up to 1,000 entries overall) in `automations-history.jsonl`. Open an automation's detail view to see which runs succeeded and which failed.

## Routing to Telegram

If you've paired a Telegram supergroup in settings, a prompt action's `telegramTopic` field routes the new session into a dedicated forum topic. Topics are created on first use and reused afterward; the bot needs the "Manage Topics" admin permission. See [Connect to anything](/go-further/connect-to-anything) for messaging setup.

## Related

<CardGroup cols={2}>
  <Card title="Workspaces" icon="layer-group" href="/go-further/workspaces">
    Automations are scoped per workspace.
  </Card>

  <Card title="Deep links" icon="link" href="/go-further/deeplinks">
    Trigger Synti actions from outside the app.
  </Card>
</CardGroup>
