Every AutoBlock has exactly one trigger that defines when a run starts. Steps (notifications, outbound webhooks, storage) run after the trigger fires. Outbound webhooks are steps — not triggers.
Source: packages/workflow-domain/src/types.ts, apps/api/src/modules/routines/routes.ts, apps/api/src/modules/webhooks/routes.ts, apps/worker/src/index.ts.
Trigger types
| Kind | User label | Starts when | Configure in |
|---|---|---|---|
manual | Run on demand | You tap Run | Dashboard / routine detail |
schedule | Recurring schedule | Cron tick matches | Wizard (cron + timezone on desktop) |
inbound_webhook | Inbound webhook | External POST to your URL | Wizard shows personal endpoint path |
Trigger comparison
| Trigger | You control timing | External system needed | Plan limit field |
|---|---|---|---|
| Manual | Yes — immediate | No | — |
| Schedule | Yes — cron/timezone | No (worker must be running) | scheduleLimit |
| Inbound webhook | No — event-driven | Yes — caller POSTs | webhookLimit |
Trial: 2 schedules, 1 webhook endpoint. Starter: 3 schedules, 2 webhooks. Plus: 15 schedules, 10 webhooks.
Manual execution
sequenceDiagram
participant You
participant App as product-web
participant API
participant Worker
participant Activity
You->>App: Tap Run on /routines/[id]
App->>API: POST /routines/:id/execute
API->>API: Check execution limit
API->>API: Insert pending execution run
Worker->>API: Poll pending runs
Worker->>Worker: executeRun()
Worker->>Activity: Status + logs available
You->>App: View /activity
Manual runs count against your monthly execution limit.
Scheduled execution
The worker (apps/worker) polls Postgres every few seconds (WORKER_POLL_MS, default 3000ms):
- Loads enabled schedules from the database.
- Computes previous cron tick in the schedule's timezone.
- If due and under execution limits, inserts a
pendingrun withtriggerKind: schedule. - Processes pending runs in the same poll loop.
| Requirement | Why |
|---|---|
| Worker service running | Schedules do not execute from the browser |
| Valid cron expression | Invalid cron is skipped silently |
| AutoBlock enabled | Disabled routines do not schedule |
| Entitlement headroom | Over-limit tenants skip schedule ticks |
Desktop wizard exposes full cron strings. Mobile favors simpler schedule presets where available.
Inbound webhook execution
Each inbound-webhook AutoBlock gets a unique path token. External systems POST to:
POST https://api.autoblocks.run/hooks/{pathToken}
Content-Type: application/json
Optional header:
Idempotency-Key: unique-key-per-event
| Response | Meaning |
|---|---|
200 + executionRunId | Run started (or replay if idempotency key seen) |
| 404 | Unknown or disabled endpoint |
| 402 | Execution limit exceeded |
Handler: apps/api/src/modules/webhooks/routes.ts. Idempotency prevents duplicate runs from retries.
Step types (after trigger)
| Step kind | What it does | Typical use |
|---|---|---|
notification | Email and/or in-app alert | Reminders, failure alerts |
outbound_webhook | POST JSON to your URL | CRM relay, Slack-compatible hooks |
storage | Persist run output | Audit trail in Activity logs |
Steps run in order field sequence. Rules can gate steps using supported operators.
Execution lifecycle
stateDiagram-v2
[*] --> pending: Trigger fires
pending --> running: Worker picks up
running --> succeeded: All steps OK
running --> failed: Step or validation error
succeeded --> [*]
failed --> [*]
View status on /activity. Failed runs include plain-language explanations — check Activity before opening a support thread.
Execution limits
| Plan | Executions / month |
|---|---|
| Trial | 100 |
| Starter | 500 |
| Plus | 5,000 |
When exceeded, new runs return HTTP 402 until the next billing period or upgrade.
Verify triggers are working
| Trigger | Check |
|---|---|
| Manual | Run once → immediate row in Activity |
| Schedule | Wait for tick → Activity row with schedule metadata |
| Webhook | Send test POST with curl → Activity row |
Example test webhook:
curl -X POST "https://api.autoblocks.run/hooks/YOUR_PATH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"test": true}'
Replace YOUR_PATH_TOKEN with the token shown in your AutoBlock detail view.