Automations

Triggers

How an automation starts running — webhooks, schedules, platform events, and manual runs. The four supported runtimes plus the delegate entry point.

A trigger is what kicks off an automation. Triggers are nodes at the top of the graph; the executor starts at the trigger and follows edges forward.

Every trigger stamps the automation row with a queryable trigger_type + trigger_config on save (via extractTriggerMeta), so the server can find matching automations without parsing pipeline JSON. The webhook router, schedule dispatcher, and event matcher all select on those columns.

The four supported triggers

Four trigger nodes have real runtimes today:

TriggerWhat fires it
WebhookAn external HTTP request to the automation's unique URL, gated by a revocable token.
ScheduleAn interval (Every N minutes / hours / days) or a cron expression (0 9 * * MON) reaching its next run cursor.
P88 EventA record / tag / calendar change in your workspace.
ManualA user clicking Run in the editor.

Two legacy trigger nodes remain in the palette for backwards compatibility (Heartbeat, WebSocket) but have no server runtime. Publish validation rejects them with a message pointing at the supported set. A fifth node, Campaign, is wired up in the flow model for the Campaigns mode but is not dispatched yet.

All trigger nodes share TriggerNodeShell.jsx. The data that started the run lands in the trigger node's output and is available downstream via the ƒ binding modal under Actions → [trigger] → output.

Webhook trigger

Drop a Webhook trigger node into an automation to expose a per-automation URL that fires the workflow on request.

Inspector fields:

  • Path — a URL fragment displayed on the node for the operator's benefit; the live endpoint is per-automation, not per-path.
  • MethodPOST, GET, or PUT.

Live URL: once the automation row is saved, the node displays the real endpoint with a copy button:

https://<project>.supabase.co/functions/v1/automation-webhook/<automationId>?token=<webhookToken>

The automation-webhook edge function (v1) receives the request, checks the token against automations.webhook_token, enqueues a run, and returns immediately. The request body / query / headers are handed to the executor as the trigger output.

Rotating a token: clearing / regenerating webhook_token in the DB revokes the old URL. The trigger node picks up the new token on the next editor reload.

Use webhooks for:

  • External services calling Project88 (Stripe, GitHub, custom apps).
  • External cron jobs that need a workflow run.
  • Custom UI events in your product wired to a Project88 flow.

Body verification (HMAC, header checks) still happens inside the graph — an early Condition or Code node can reject before the rest of the workflow continues.

Schedule trigger

The Schedule trigger runs an automation on a schedule. The inspector has two modes:

  • Interval (default) — Every N where N is a number and the unit is one of minutes / hours / days. The most common shape.
  • Cron expression — a five-field cron string (0 9 * * MON) for precise wall-clock schedules. Toggle with the "use cron expression →" link on the node.

Under the hood. A per-minute schedule dispatcher walks every active automation with trigger_type = 'schedule', evaluates the interval / cron against the automation's next_run_at cursor, and enqueues a run when due. Once the run enqueues, next_run_at advances to the next matching instant.

Publishing a schedule automation with neither an interval nor a cron expression is blocked by publish validation.

P88 Event trigger

The P88 Event trigger fires when a matching change lands in your workspace. The inspector picks one of three sources, each with its own event shapes:

SourceEventsExtra config
Recordscreated · updated · deletedTable (required), optional tag filter
Calendarcreated · updated · deleted
Tagsassigned · removedTag (required for the event), optional row-tag filter

Runtime. DB triggers on user_table_rows, tag_assignments, and calendar_events fan into an automation_events outbox (migration 155). The outbox is:

  • Org-gated — a row change only enqueues events for automations in the same org.
  • Change-gated — updates only emit when a watched field actually changed.
  • Service-role only — the outbox is invisible to the client.

A per-minute event matcher reads the outbox, joins against active automations of matching trigger_type = 'event' and matching trigger_config, and enqueues runs. Two safety valves keep a hot event source from spiraling:

  • 10-second dedup on (automation_id, event_id) — two DB triggers for the same logical change can't double-fire an automation.
  • 30 runs / minute circuit breaker per automation — a runaway event source pauses further dispatches for the rest of the minute and logs the throttle.

Publishing a P88 Event trigger without a source (or a Records event without a table) is blocked by publish validation.

Manual trigger

The simplest one: fires when a user clicks Run in the editor. Useful for one-off jobs and for testing a graph end-to-end before wiring it to a real trigger. See the Run button.

Delegate entry

Any automation can be delegated to from an agent's pipeline (or from another automation) via the Delegate node. The delegating workflow chooses the target, passes inputs, and waits for the response.

This isn't a trigger node per se — the entry point is still whatever trigger node sits at the top of the graph — but a delegate call is the canonical way to invoke an automation from another agent or workflow. Runs invoked this way carry a run_once action so the executor picks them up like any other queued run.

Legacy triggers (no runtime)

Two trigger nodes remain in the palette so old flows still open, but publish validation rejects them:

  • Heartbeat — a periodic platform tick. Replaced by Schedule.
  • WebSocket — an incoming WebSocket message. There's no receiver deployed today; use Webhook for external services.

If you have an old flow using one of these, swap the node for a supported trigger before publishing.

Where to next

On this page