Triggers
Standing rules that run a playbook or prompt an Argus when something happens — an inbound webhook, an integration record change, a data-store query, or an event in a connected calendar. Every trigger is armed by a human before it can fire.
A trigger is a standing rule: when something happens, and only if your conditions hold, run an action. It's how Scape reacts to the outside world — an inbound webhook, a record changing in one of your integrations, a query going true against a table, or a meeting in one of your connected calendars — by launching a playbook or prompting an Argus manager.
The shape of a trigger
Every trigger has exactly one When, zero or more conditions, one Run, and a policy:
- When — the event that wakes the trigger.
- Only if — optional conditions that filter the event before it runs anything.
- Run — the action to take.
- Policy — rate limits and how to handle a backlog.
Creating a trigger
Right-click a project (or a Triggers folder) in the sidebar and choose New Trigger. Triggers are first-class items in the project tree — their icon reflects arm state at a glance. Opening one routes to an editor tab where you build the rule; a new trigger starts as a webhook → run-playbook skeleton with empty fields for you to fill in.
The native toolbar above the editor holds the arm control; the trigger's fire activity appears in the editor canvas itself (see Fire activity).
When — the event
A trigger watches exactly one of four sources:
| When | Fires on | Key settings |
|---|---|---|
| Webhook | An inbound HTTP request from an outside service (GitHub, Stripe, Zapier, a curl script). | A webhook name and a verification method (none, HMAC-SHA256, GitHub, or Stripe). Signed methods need a signing secret. |
| Integration record | A change to an item in one of your integrations — a new record, a removed record, or a field changed (name the field). | The integration item to watch and the event kind. |
| Data-store query | A change in a table — new matching rows, or a row count crossing a threshold (>, >=, <, <=, =). | The store, the event kind, and (for row count) the comparison and value. |
| A calendar event | An event in one of the project's connected calendars — it starts in N minutes, starts, ends, is added, changes, or is cancelled. | Which connected calendars to watch (none picked = all of them), the event kind, and (for starts in) the minutes before. See Calendar events. |
Calendar events
A calendar trigger watches the calendars you've connected to the project — for example, prep notes 10 minutes before every meeting with a customer, or tell my Argus when a review gets moved. If no calendars are connected yet, the editor points you to the Calendar's ⋯ › Calendars on this Mac….
| Event | Fires when |
|---|---|
| starts in… | N minutes before an event starts (1–1440). |
| starts / ends | At the event's start or end. |
| is added | A new event appears in a watched calendar. |
| changes | An event's details change. event.changedFields lists what changed (title, time, location, …), and event.attendeesOnly is true when only the attendees or organizer changed — replies (RSVPs), but also guests added or removed and a new organizer. A condition on it skips RSVP churn, but it skips those guest-list changes too. |
| is cancelled | An event is cancelled or deleted. |
How they behave:
- Once per occurrence. A repeating event fires once for each occurrence, and a fired occurrence doesn't fire again after a relaunch. Rescheduling can fire the trigger again at its new firing time: N minutes before the start, at the start, or at the end, depending on the trigger. A firing time already passed by the trigger's checks isn't caught up for an existing event (only a newly added event gets the late window below).
- Connecting doesn't fire. Events already in a calendar when you connect it don't count as added.
- Narrow with conditions. Filter by title, attendees, or location with conditions on
event.title,event.attendeeEmails, orevent.location. Other fields includeevent.description,event.organizer,event.calendar,event.meetingLink,event.start,event.end,event.allDay,event.recurring, andevent.minutesUntilStart. - Missed times are bounded. Calendar triggers are checked about every 30 seconds while Scape runs. A start or end that passed while Scape was closed can still fire on the next launch, but only if it's within the trigger's Backlog max age — and never too late to matter: starts in… doesn't fire once the meeting has started, and starts doesn't fire once it has ended. A newly added event whose time already passed (a last-minute invite) can still fire late for up to 10 minutes, under the same cutoffs.
- Calendar defaults. Choosing A calendar event sets a still-default policy to no cooldown and discard stale after 15 minutes, since several meetings can start at once. A policy you've already changed is left alone.
- No loops. A change made by a trigger's own playbook doesn't fire that same trigger again.
To act on the event, use {{event.eventId}}, {{event.originalStart}}, and {{event.fingerprint}} — a playbook's Calendar event step or an Argus can use them to change or delete that event, on a calendar marked Scape can edit.
Only if — conditions
Conditions filter the event before the trigger runs anything. Each condition tests a path into the event (e.g. event.body.action) with an operator:
| Operators | |
|---|---|
eq, neq | Equal / not equal |
contains, not_contains | Substring |
starts_with, ends_with | Prefix / suffix |
gt, gte, lt, lte | Numeric comparison |
exists, not_exists | Path present / absent |
Conditions combine with AND within a group and OR across groups — an or join starts a new group, and consecutive and rows extend the current one. You can add up to 32 conditions.
Run — the action
When a trigger fires, it does exactly one of:
- Run a playbook — launch a playbook headlessly, optionally passing inputs.
- Prompt an Argus — send a prompt to one of the project's Argus managers, which then acts on it.
Arming
A trigger cannot fire until a human arms it. Arming means you've reviewed the exact rule and approved it to run.
Clicking Review & Arm opens a sheet summarizing the trigger — its When, its conditions, its Run, and the signing status — and states the value-only guarantee above. Approving it arms the trigger.
Arming is deliberately human-only and per-device:
- No agent can arm a trigger. The MCP tools can author and edit every part of a trigger, but none of them can arm it. Arming lives only in the Scape UI.
- Arming doesn't sync. A trigger armed on one Mac is not armed on another — you arm it on each machine where you want it to fire.
Any edit disarms
Any change to a trigger — by you or by an agent through any of the set_trigger_* or condition tools — clears the arming. A human must re-arm. This is why every editing tool reports "re-arm in Scape" on success: the whole point of arming is that a human approved these exact bytes, so changing them revokes the approval.
The approval digest
When the Run is Run a playbook, arming also binds the exact executable graph — the target playbook plus every sub-playbook, custom tool, and integration it reaches. Scape records a digest of that graph at arm time. At fire time it re-computes the live graph and refuses the fire if anything drifted, so you have to re-arm and re-approve. The digest covers the executable substance — each playbook's steps and their arguments, its declared inputs and grants, and the pinned definitions of the tools and integrations it calls, transitively. It deliberately does not cover a playbook's prose or the output cache a normal run writes back — so editing an executable step forces a re-arm, but editing notes or simply running the playbook doesn't. What you reviewed is exactly what runs.
Needs re-arm
A trigger can be armed yet still be refused at every fire — because the approved graph no longer matches the live one. Scape surfaces this as a red Needs re-arm state (rather than a misleading green "Armed"). Click Re-arm to review the changed flow and approve it again.
Arm states
| State | Meaning |
|---|---|
| Armed (green) | Approved and eligible to fire. |
| Review & Arm (amber) | Not yet armed — the offer to review and arm. |
| Paused — license (amber) | Your subscription doesn't currently cover this trigger — whether it was previously armed or has never been armed. Shows an Upgrade/Reactivate action. |
| Needs re-arm (red) | Armed, but the approved graph drifted — fires are being refused until you re-arm. |
Policy
Each trigger has a policy governing how often it fires and what happens to events that pile up while Scape was closed:
| Setting | Default | What it does |
|---|---|---|
| Cooldown | 60s | Minimum seconds between fires. |
| Max fires per day | 100 | Daily cap. |
| Batch mode | Per event | Fire once per event, or once per drained batch. |
| Backlog policy | Fire latest only | For events buffered while Scape was closed: fire them all, fire only the newest, or discard stale ones. |
| Backlog max age | 60 min | Staleness window used by discard stale. |
Fire activity
The trigger editor shows a Fire activity feed in the canvas — recent fires and whether each ran or was refused, with the refusal reason (for example a digest drift or a rate-limit cooldown). It's hidden until the trigger has fired at least once, and it's the first place to look when a trigger isn't behaving as expected. An event whose conditions didn't match is simply skipped — it doesn't produce a refusal entry.
MCP tools
Agents can fully author and edit a trigger, but can never arm it — that's the human-only trust boundary.
| Tool | Description |
|---|---|
get_trigger_schema | The full grammar — When kinds and their args, condition operators, Run kinds, policy fields. Fetch this first. |
list_triggers | List triggers (with an armed flag), optionally filtered by project. |
get_trigger | A trigger's full rule document, its contentRev, and armed state. Read condition ids here. |
create_trigger | Create a trigger (subscription-gated). Starts as a webhook → run-playbook skeleton. |
delete_trigger | Delete a trigger (subscription-gated). |
set_trigger_when | Replace the When. Validates the reference; clears arming. |
set_trigger_run | Replace the Run. Validates the playbook/Argus reference; clears arming. |
set_trigger_policy | Patch policy fields; clears arming. |
add_trigger_condition / update_trigger_condition / delete_trigger_condition | Manage conditions (max 32); each clears arming. |
list_trigger_fires | The fire log (default 50 rows). |
The rule- and condition-editing tools (set_trigger_* and the condition tools) return the new contentRev and clear arming — a human must re-arm in Scape. create_trigger and delete_trigger return the created/deleted id instead.