Triggers and unattended runs
Declare events a Block runs on by itself: new media, schedules, webhooks, project completion and provider events, turned on by the project owner, with hosted runs inside an approved budget.
A Block can declare events it runs on by itself. Declaring a trigger runs nothing: when the Block is placed in a project, the project owner reviews each trigger and turns it on for that Step, with the same reviews as the automation panels. Results wait for the owner to review before they are used.
{"triggers": [
{"event": "media.saved", "input": "video", "kinds": ["video"], "label": "When a new video is saved"},
{"event": "schedule", "everySeconds": 86400},
{"event": "webhook", "eventKind": "order.created"}
]}| Event | Fields | Runs when |
|---|---|---|
media.saved | input (the primary image, video, audio or asset input), optional kinds | New media is saved to the project (checked about every minute). Existing media is not processed. |
schedule | everySeconds (60 to 31,536,000) | On the interval, starting a minute after the owner turns it on. Missed runs are skipped. |
webhook | optional eventKind | Another service sends POST /api/workflow-trigger-events/<id> with the key the owner receives once (Authorization: Bearer <key>) and a JSON event {id, kind, occurredAt, data} up to 64 KB. Repeated event IDs run once. |
project.completed | none | Another project the owner chooses is marked complete. |
provider | appId, eventKind | A connected app reports the event; the owner connects the account. |
Up to 4 triggers per Block. A webhook, schedule or provider Block receives the event through an input with "semantic": "workflow_event" and "sources": ["project"].
Triggers work for recipe, JavaScript and hosted (runtime: "capability") Blocks. Module Blocks run only in the person's browser, so they cannot declare triggers or run unattended. Sandboxed code has 25 seconds per run.
Hosted Blocks run inside an approved budget
A hosted Block (generation, analysis, speech, transcription, web reading) runs unattended only after the owner approves it for that Step: the model and payment, credits per run, total credits, number of runs and how many days the approval lasts. The approval reuses the owner's earlier review of the Block with that model, so run the Step once yourself first. Each automatic run:
- claims its credits on the approval before anything is sent, so the total is
never exceeded, and stops and waits for the owner if the price rises above the per-run ceiling or the approval is used up, revoked or expired;
- runs as one job with one workflow budget, and is never paid twice: a resumed
or retried job polls the same hosted request;
- can take longer than the sandbox's 25 seconds. A long call (for example video
generation) puts the job in a timed wait and StillMade polls it until it finishes. Cancelling the job cancels the hosted call.
Timeline and workspace proposals never run unattended; they always wait for a person.
autoCaptions and orderNote in @stillmade/block-sdk are complete examples: transcription of each new video into timed captions (media.saved), and a JavaScript Block that turns a shop's webhook into a production note. The SDK helpers BLOCK_TRIGGER_EVENTS, BLOCK_TRIGGER_LIMITS, UNATTENDED_RUNTIMES, triggerProblems, blockTriggers, describeTrigger and triggerReview (what the owner reviews for each trigger) check and describe declarations.