Skip to content

Start with Triggers

Start a flow automatically by configuring a trigger source and mapping values into the flow’s inputs. An enabled source records events before publication, independently of execution. Ordinary dispatch runs the published live release. Development tests perform real actions and spend usage.

For Daily invoice digest, use workflow data with these development rows:

Invoice IDAmountReview needed
INV-104120false
INV-1051500true
INV-106600false

Configure one digest at 09:00 America/Chicago. Create the docs-digest-test Slack channel and select its actual ID. Expect three invoices, one needing review, and exactly one message per run. An empty queue must produce one zero-item digest. Before live verification, separately import or copy live rows. Publishing copies no records.

SourceConfigureDeliver a sample
ScheduleTime and timezoneWait for a scheduled firing.
WebhookGenerated endpointSend a request to the returned URL.
EmailGenerated inbound addressSend email to that address.
App eventDiscovered event, connection and settingsProduce the event; allow its polling interval when applicable.

In the app: open Workflows → Daily invoice digest → flow → Triggers → Add new trigger. Choose the source/event, complete the settings, then choose Add Trigger. For schedules, choose Daily → Time → 09:00. There is no timezone picker. The timezone comes from the stored setting or your profile. To specify America/Chicago, use the assistant path.

With an assistant: list workflows to find the workflow’s ID.

Terminal window
cai workflow list --limit 100 --json

Note its data.items[].id as <workflowId>. Only when data.hasMore is false can you trust a workflow’s absence. Otherwise, get the ID from the app or owner. Workflow-scoped MCP calls still need workflowId. Set CLI context with cai use, then find the flow and schedule identifiers.

Terminal window
cai use <workflowId> --json
cai flow list --json
cai trigger search "schedule" --json

Note the flow’s data.items[].id as <flowId> and the schedule’s data.nodes[].slug and eventKeys[].key as <slug> and <eventKey>.

Inspect the schedule properties to find the values needed for creation.

Terminal window
cai trigger props --node <slug> --event <eventKey> --json

MCP uses trigger_component_props with node and event.

Start with data.propsForCreate and leave hidden props unset. Create only when data.readyForCreate is true and required values are filled. Timezone priority is the explicit setting, your profile, then UTC. Create this schedule with the nested cron object to get its creation fields.

Terminal window
cai trigger create --flow <flowId> --node <slug> --event <eventKey> --source-basis explicit-in-request --props '{"cron":{"cron":"0 9 * * *","timezone":"America/Chicago"}}' --json

Keep four creation fields under data as distinct placeholders. Use triggerId to control the canvas and backendTriggerId to list or replay events. Use triggerNodeId to select samples and runSubflowNodeId to map inputs.

MCP uses trigger_create with flow, node, event, sourceBasis and parsed props.

Creating a trigger provisions the source before saving the canvas. After STATE_CONFLICT or an uncertain result, inspect existing triggers and provider sources before retrying. Cleanup can fail. Another create can duplicate a source.

List triggers to see which already exist.

Terminal window
cai trigger list --json

Does another source need an account or options?

Section titled “Does another source need an account or options?”

Use that source’s discovered <slug> and <eventKey>. Below, <nodeSlug> is the same slug. List connections and, if none fits, request a link to connect an account.

Terminal window
cai connection list --integration <slug> --json
cai connection connect <nodeSlug> --no-open --json

Complete the connection at data.url, list again, and note data.items[].id as <connectionId>.

MCP uses connection_list with integration and connection_connect_url with nodeSlug.

Inspect properties with that connection to get the creation values.

Terminal window
cai trigger props --node <slug> --event <eventKey> --connection <connectionId> --json

Save data.propsForCreate as trigger-props.json and retain your chosen values. Keep the latest data.id as <dynamicPropsId>. Resolve each data.unresolvedOptionProps name as <name>. To find its options, replace <text> with the desired option label.

Terminal window
cai trigger options --node <slug> --event <eventKey> --connection <connectionId> --prop <name> --configured trigger-props.json --dynamic-props-id <dynamicPropsId> --query '<text>' --json

MCP uses trigger_prop_options with parsed configured and dynamicPropsId.

To browse options, replace --query '<text>' with --page 0. On subsequent zero-based pages, pass the returned data.context as --prev-context. MCP uses page and parsed prevContext. Merge the exact data.options[].value into the file. Reload the properties to check whether the trigger is ready for creation.

Terminal window
cai trigger props --node <slug> --event <eventKey> --connection <connectionId> --configured trigger-props.json --dynamic-props-id <dynamicPropsId> --json

When readyForCreate is true and required values are filled, create this alternative. According to the source choice, use <basis> as explicit-in-request, user-answer, or inferred-from-existing-workflow. Omit unnecessary connection/dynamic-ID flags. Create the alternative source to get its creation IDs.

Terminal window
cai trigger create --flow <flowId> --node <slug> --event <eventKey> --source-basis <basis> --connection <connectionId> --props trigger-props.json --dynamic-props-id <dynamicPropsId> --json

Keep these creation IDs separate.

List captured events to find a sample.

Terminal window
cai trigger events --trigger <backendTriggerId> --limit 50 --json

Note the original sample’s data.events[].id as <eventId>. The default is the five newest events. The maximum is 50. Capture needs neither publication nor development permission. If nothing arrives, inspect source settings, destination and capture.sourceEnabled from trigger get. A disabled source captures nothing.

MCP uses trigger_event_list with backend triggerId. In MCP inputs, that ID and every captured-event ID are numeric strings.

Inspect the trigger and event, then select the sample to access its fields.

Terminal window
cai trigger get <triggerId> --json
cai trigger event <eventId> --json
cai trigger select-event --node <triggerNodeId> --event <eventId> --json

If dataTypeName or its schema is unavailable, wait and select the same event again. Write field expressions only after expression context exposes them.

MCP uses trigger_get with canvas triggerId, trigger_event_get with eventId, and trigger_event_select with triggerNodeId and eventId.

In the app: open the trigger canvas for Webhook URL, Email address, and Sample event → View. For schedules, use the assistant path because the sample picker is hidden. Open the flow’s Inputs → Add new input and add Schedule as text. In the trigger’s Run flow node, set it to 09:00 America/Chicago. This example supplies a label explicitly. It assumes no schedule payload field.

With an assistant: use data.runSubflowNodeId as <nodeId> below. If absent, add the input. Inspect its mapping property and expression context.

Terminal window
cai flow input add <flowId> --display "Schedule" --type text --json
cai node props <nodeId> --json
cai expr context <nodeId> --json

Keep the Schedule property’s returned name as <name>. Each input creates a mapping property. Event values never enter the flow automatically.

MCP uses flow_input_add, node_prop_list and expr_context. The latter two take nodeId.

Set the Schedule label, then inspect its mapping.

Terminal window
cai expr set <nodeId> --prop <name> --js '"09:00 America/Chicago"' --json
cai node props <nodeId> --json

MCP uses node_prop_set with nodeId, prop and inline js.

For event-derived inputs, bind the exact compatible field expression from context instead. Keep existing source IDs when repairing mappings.

First, test the flow directly to check its logic in isolation.

Terminal window
cai run flow <flowId> --inputs '{"Schedule":"09:00 America/Chicago"}' --target dev --json

MCP uses run_flow with flowId, target: "dev" and parsed inputs.

In the app, select Dev, open the flow and choose Test (tooltip “Test current flow”). After success, replay the original sample once to test the trigger path.

Terminal window
cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json

Keep the new data.eventId separate from the original sample ID. Use data.workflowExecutionId as <workflowExecutionId>. Development replay requires an enabled development trigger. It bypasses incoming-event permission. Every replay creates another captured event and real execution. Pending is not a reason to replay again.

MCP uses trigger_replay with backend triggerId, eventId and target: "dev".

Inspect the execution to get its status.

Terminal window
cai exec get <workflowExecutionId> --json

Repeat until data.status is completed, completed_with_error, failed or cancelled. For paused, use execution inspection.

MCP uses execution_get with workflowExecutionId.

Then inspect the tree to find the node’s execution ID.

Terminal window
cai exec tree <workflowExecutionId> --json

Note the relevant data.items[].id as <nodeExecutionId>.

MCP uses execution_tree with workflowExecutionId.

Read its values to check the mapping and message.

Terminal window
cai exec node <nodeExecutionId> --full --json

MCP uses execution_node_get with nodeExecutionId and full: true.

Check mapping and send values, invoice and review counts, and exactly one Slack message per test. With the empty queue, repeat and expect one zero-item digest.

Disabling development stops its canvas execution and leaves incoming-event permission intact. It stops neither source capture nor the published trigger. Publish the disabled definition to change live execution. When retained permission would double-run alongside a live path, CLI/MCP refuses re-enabling. Disallow incoming-event permission first.

Before turning Allow test events in dev mode On, rule out a live path or explicitly accept both executions and charges. While enabled, permission immediately admits real traffic. After one event, inspect Run history, then turn it Off. Replay’s target is separate.

To test incoming events intentionally, allow them into development for a real execution.

Terminal window
cai trigger test-events <triggerId> --allow --json

MCP uses trigger_test_events_set with triggerId and allowed:true. Add --acknowledge-dual-run / acknowledgeDualRun:true only after the user accepts a reported double-run hazard.

Follow Publish a Workflow for the complete trigger audit and live verification. CLI/MCP publication rejects unacknowledged dual dispatch. The app/shared service can publish with a warning. Capture happens before asynchronous typing and dispatch, so if no run appears, reread events and executions before diagnosing publication, enablement, routing or ingestion failure. If a run starts with empty mapped inputs, inspect its mapping.