> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kylon.io/llms.txt
> Use this file to discover all available pages before exploring further.

# workflow

> Create, trigger, pause, and inspect workflows and runs.

```text theme={null}
kylon workspace workflow — kylon workspace help detail

workflow — automated workflows in this room
  Workflow runs are non-blocking: public-output workflows can use kylon workspace ui send for read-only cards or bounded human input, but a run does not pause in-place to wait for a reply. If a user interacts with a workflow card, a continuation turn resumes the workflow session with the submitted result.
  kylon workspace workflow list [--room <name_or_id|all|current>] [--query <keyword>]
    IMPORTANT: omit --room to search the current room only. Use --room all
            for workspace-wide workflow search across all visible rooms, or a
            specific room name/ID to search one room.
    --query: case-insensitive substring match on workflow name (SQL-side via trigram).
  kylon workspace workflow show <workflow_id>         show full workflow configuration and prompt
  kylon workspace workflow create --name <name> [--room <room_ref>] [--task <text> --context <text> | --message <text> | --message-file <path>] [--schedule <json> | --trigger webhook (--webhook-profile <profile> --verification-secret-key <runtime-secret-key> [--verification-tolerance-seconds <seconds>] [--events <types>] | --provider <generic|github>) [--allow-headers <names>]] [--expect <text>] [--publish [--activate-output [agent_id]] [--mention-mode <forced|routed>]] [--timezone <tz>] [--current-thread] [--enable]
    Agent-created workflows default to the authenticated current Agent.
    Lifecycle: a workflow created with a recurring or data-change schedule (cron, every, row_change, app_record_change) starts PAUSED and fires nothing until resumed. After checking authorization for its real effects, verify it first (kylon workspace workflow trigger <workflow_id> --verify -> kylon workspace workflow runs show -> kylon workspace workflow resume; see the creation checklist). --enable skips the paused start — pass it only when the user explicitly asked for immediate enablement. Webhook, connection_event, and one-shot "at" workflows start enabled: pausing ingest drops deliveries the sender already committed, and a one-shot's verification is its execution.
    schedule format: {"kind":"cron","expr":"0 9 * * *"} | {"kind":"every","everyMs":3600000} | {"kind":"at","at":"2026-04-01T09:00:00Z"} | {"kind":"app_record_change","appId":"<app_id>","entityId":"<entity_id>","events":["insert","update","delete"]} | {"kind":"connection_event","connectionId":"<connection_id>","directions":["inbound"],"messageTypes":["email"]}
    --room creates the Automation in another visible Room; omit it for the current Room.
    omit --schedule for manual-only workflows
    Change-trigger predicate: add "when" to app_record_change to fire only on the changes you care about, instead of running and deciding there is nothing to do.
      {"kind":"app_record_change","appId":"<app_id>","entityId":"tickets","events":["update"],"when":{"where":{"status":"blocked","priority":["P0","P1"]}}}
      where is a flat field -> value map, ANDed. A scalar means equals; an array means one-of. Comparison is strict, so 1 does not match "1".
      A field missing from the changed payload never matches, so deletes (which carry no field data) never satisfy a where. Omit when if a delete must fire.
      A change the predicate rejects starts no run at all: it produces no run history and spends no credits.
    --timezone: IANA name like "Asia/Shanghai". Cron expr is interpreted in this timezone — do NOT pre-convert to UTC. Defaults to UTC.
    Creation checklist:
      1. Put the complete behavior in the saved workflow definition. For deterministic reusable logic, use a self-contained TypeScript body that imports @kylon/workflow-sdk; the saved immutable revision persists that source.
      2. Local files under /home/user are disposable authoring or per-run scratch. You may prepare code under /home/user/automations. Never make a workflow depend on that path surviving into a later run.
      3. Before testing, inspect the complete definition and its callees for real sends, writes, or deployments. Tests outside the scheduler have real effects too; --verify suppresses automatic Room output, not external effects. Reuse existing authorization: permission to create or schedule alone does not authorize an immediate test email. Then save the complete source with --message-file for multi-line code or --message for inline code. Do not save only an instruction to run an unpersisted local script.
      4. Prefer read-only inspection or unit checks of the logic. When real effects are authorized and safe, run the saved workflow once with kylon workspace workflow trigger <workflow_id> --verify and read the run with kylon workspace workflow runs show <run_id>. Honor the authorized targets and execution count. If an outside test already performed an effect, check its receipt and provider idempotency; never repeat a send merely to obtain a successful verification mark. Confirm the goal was achieved AND that every dependency actually responded: each connection it uses is authorized, upstream data exists and paginates completely, and writes land where expected. A dependency that is not connected yet is a reason to leave the workflow paused, not a detail to note.
      5. If real verification is unsafe or unauthorized, use read-only inspection or authorized drafts/provider test recipients only as partial checks. Do not silently change production recipients or the saved definition. Skipped sends, drafts, and test recipients do not prove production delivery. Keep new recurring/data-change workflows paused; leave other authorized triggers unchanged and state what remains unverified. Resume after full verification; use the existing --enable/--force override only on the user's explicit request and disclose the unverified behavior.
      6. Every Workflow should include: goal, trigger assumptions, execution steps, expected output, validation method, and what to report when blocked or validation fails.
      7. Persist cross-run state with the workflow state tools or the shared CLI. Read with workflow state read [--include-current-run true]. Write the complete business state with workflow state write --state <JSON-object> or --state-file <path> [--schema-version <version>] [--business-date <date>]. The server resolves the current workflow/run; never pass a run id or keep the only copy on the local VM. Native read_workflow_state/write_workflow_state tools use the same storage. Publish durable outputs with publish_workflow_file.
      8. Use --expect to describe the expected run result format.
    Every Workflow is supervised by an Agent. Save its complete task and any reusable
      script in the Workflow definition; local authoring files do not persist across runs.
    Scripts: a body that imports '@kylon/workflow-sdk' is saved as TypeScript in the
      immutable Workflow revision. It runs as a TOP-LEVEL module (top-level await works; a default
      export is never invoked and is rejected at save time). Available imports are:
      - ctx: workspaceId, roomId, agentId, now(), timezone, and trigger. Narrow on ctx.trigger.kind before reading its payload. Webhook triggers expose provider, method, headers, bodyJson/bodyText, and receivedAt; valid JSON up to 64 KiB supplies both its exact received bodyText and parsed bodyJson. Larger verified requests expose a bounded bodyText prefix plus bodyTruncated/bodyBytes and omit bodyJson. Use await ctx.trigger.body.json(), .text(), or .bytes() for the complete stored payload; unavailable historical bodies fail rather than returning a preview. Run workflow webhook profiles, then use --webhook-profile with a runtime-secret Connection key. P2 owns the provider protocol, verifies the exact raw body before enqueue, and deduplicates on the verified provider-native event id. Add --events only for exact event-type filtering. --verification-secret-key names a granted Connection and never carries its value. Use --allow-headers only for additional business headers the workflow itself needs. Legacy --provider github and --provider generic --verification-profile airwallex remain accepted for existing GitHub and Airwallex endpoints.
      - agent(prompt, { schema?, mode?, tier? }): calls a child Agent and returns its result to the script. Read-only by default (mode 'bounded'); pass mode: 'delegate' to give it your full toolset so it can run commands and write files, which composes with schema. Use mode: 'delegate' for research that needs commands or produces files. tier selects 'high' (Max), 'medium' (Standard), or 'low' (Lite) and never changes the toolset. Internal agents may only use their own tier or lower for children; model overrides obey the same limit.
      - parallel(thunks) and pipeline(items, ...stages): bounded-concurrency control flow.
      - sendMessage(text, { mention? }): stage message drafts for the supervising Agent; it does not post to the Room.
      - deliverConnectionEvent(): for a connection_event run only, ask the server to revalidate and deliver its canonical Event to this Automation's Room. It accepts no event data or destination.
      Scripts support every trigger kind. Row triggers expose ctx.trigger.rows (event, rowId, title, cells) and App-record triggers expose ctx.trigger.records (event, appId, entityId, recordId, data). Both also carry totalCount and truncated. Connection-event triggers expose a bounded normalized ctx.trigger.event.
      A large batch truncates in one of two ways, and truncated is true for both. Compare the array length with totalCount to tell them apart: equal lengths mean every entry arrived but some lost their cells/data (re-read those by id); a shorter array means the remaining entries were not delivered at all, so page them from the source rather than assuming you hold every id.
      Reading and writing App or workspace data: call the workspace REST API directly with fetch. Your environment provides $P2_API_BASE and the agent credential; read the bundled `kylon-api` skill for endpoints and auth. That is the supported deterministic path for App records, files, and table data.
      The SDK's connection and state helpers are not wired yet and throw if called. Use the supervising Agent's tools for managed connections and workflow state, or a delegate agent() call when the work needs a full toolset; use the REST path above for data.
      Execution: the platform prepares the saved script. Use run_workflow_code action="inspect", file="source" before action="run"; then inspect file="result", "messages", "stdout", "stderr", or "effects". Runs return bounded excerpts; inspect pages with offset=nextOffset when needed. This run-bound tool needs no general shell or file reader. Exit 0 alone does not prove the goal was achieved. sendMessage drafts stay in messages.json; stdout and stderr are logs, never automatic Room output. Check the result against the goal and validation before producing a concise report; do not paste raw JSON, error codes or logs into the Room. deliverConnectionEvent remains a platform-validated delivery of its canonical Event.
      Recovery: only after a failed execution, at most one materially changed, side-effect-safe attempt within the shared run budget. A completed execution cannot be rerun, even with changed source; verify read-only receipts and use existing tools only for clearly unfinished steps, or report failure. Never replay an external write whose outcome is unknown. Run the repaired source with source_text, or source_path when file tools are available; inspect the new results, then use action="save". Omit source to save the successful candidate, or provide that exact source again. Save accepts only the exact source successfully executed in this run and persists a new Workflow revision; editing a temporary file alone does not persist a repair. Log phases, counts, verification and error stacks without credentials. Generic reports require --publish; internal runs and verification runs stay in run history. Use --message-file for
      multi-line code to avoid shell quoting.
    Delivery policy: for normal public workflow results, use --publish and omit --current-thread so runs post to the room's flat chat. Omit --publish only for internal/run-history-only workflows. Do not add --current-thread just because the current turn is in a thread.
    Use private or targeted delivery only when the user explicitly asks, or when output is sensitive, noisy, or user-specific.
    Output handoff: add --activate-output when that published final result should itself be the single room root of a newly activated agent thread. Bare --activate-output follows the room's current main agent; pass an agent ID to pin a target. --mention-mode forced (default) requires a response; routed allows the target to stay silent. It cannot be combined with --current-thread. Do not also call thread create for the same result.
    Scheduled workflows must respect the platform minimum interval: production 10 minutes, development 5 minutes, unless WORKFLOW_MIN_INTERVAL_MS overrides it. Cron schedules are rejected when sampled adjacent fire times are closer than the minimum.
    app_record_change: fires when matching Database App records are inserted, updated, or deleted. Use 'app docs' or Data Viewer schema to find the appId and entityId. Events array must contain at least one of: insert, update, delete. Add "when" to narrow which records fire; scripts can read the changed records from ctx.trigger.records.
    webhook: creates a capability-token endpoint and returns a copyable webhook URL. Use --message-file/--message for code that branches on ctx.trigger, or --task/--context for structured task instructions.
    --expect: describe expected output format
    --publish: publish run results to room flat chat.
    --current-thread: deliver each run's result as a reply in the current thread. Use only when the user explicitly wants thread delivery.
  kylon workspace workflow update <workflow_id> [--name <name>] [--message <text> | --message-file <path> | --task <text> --context <text>] [--schedule <json>] [--expect <text>] [--publish] [--timezone <tz>] [--current-thread | --current-thread none] [--force]
    Use --message to replace the raw workflow prompt and clear structured task/context fields.
    An update that puts the workflow live on a recurring/data-change schedule runs the
    same verification gate as resume: prefer applying the change paused. When its real effects
    are authorized and safe, verify with kylon workspace workflow trigger <workflow_id> --verify, then resume;
    --force overrides only with the user's explicit confirmation.
    --publish: publish future run results to room flat chat.
    --current-thread: bind output to the current thread only for explicit thread delivery. --current-thread none: clear the thread binding.
  kylon workspace workflow webhook profiles
    List the closed, server-owned provider profiles and their identity, event-type,
    required-header, tolerance, body-size, and endpoint-rate policies. Use a listed id with --webhook-profile;
    do not manually reproduce provider signature headers or algorithms.
    Decision rule: use --provider generic for the simplest capability-URL webhook or an
    unlisted/unsigned sender. Use --webhook-profile only when the sender implements that
    exact listed signing protocol; never substitute a similar profile.
    Simple example:
      kylon workspace workflow create --name "Generic intake" --trigger webhook --provider generic --message "Process the received event"
    Verified example (when the signing secret is already available):
      kylon workspace workflow create --name "Stripe intake" --trigger webhook --webhook-profile stripe --verification-secret-key STRIPE_WEBHOOK_SECRET --events invoice.paid,invoice.payment_failed --message "Process the verified invoice event"
    Three distinct values are involved: the generated webhook URL contains P2's capability
    token; the sender/provider-side signing secret is the shared cryptographic secret; and
    --verification-secret-key is only the uppercase key of the runtime-secret Connection
    that stores that signing secret. Never put the secret value or URL token in that flag.
  kylon workspace workflow webhook show <workflow_id>
  kylon workspace workflow webhook configure <workflow_id> [--webhook-profile <profile> [--verification-secret-key <runtime-secret-key>] [--verification-tolerance-seconds <seconds>]] [--events <comma-separated-exact-types|none>] [--allow-headers <comma-separated-names>]
    Updates verification and filtering in place. The endpoint id, capability token,
    and URL do not change. Changing profiles requires a fresh secret key; omit it to
    reuse the existing secret for same-profile updates. Prefer each profile's default
    tolerance; override it only when the provider contract requires it.
    The tolerance option is rejected when webhook profiles reports tolerance=none.
    --events is an exact-match allowlist; "none" clears it. --allow-headers adds business
    headers to the trigger context, not signature headers required by the selected profile.
    A pre-kernel Airwallex endpoint must be explicitly upgraded with --webhook-profile
    airwallex and a signing-secret Connection key before changing events or allowed headers;
    the URL stays stable, while managed profile v1 body/rate/timeout policies become active.
  kylon workspace workflow webhook rotate <workflow_id>
  kylon workspace workflow webhook revoke <workflow_id>
  kylon workspace workflow runs <workflow_id>        show execution history
    When a workflow behaves incorrectly, inspect workflow show and recent workflow runs before changing it.
  kylon workspace workflow runs show <run_id> [--step <n>]   show detailed run output and execution steps
  kylon workspace workflow runs stop <workflow_id> <run_id>   stop a run that is still running (Workspace Admin)
    --step: expand the full result of step N (1-based index from the step list)
  kylon workspace workflow revisions <workflow_id>  list immutable saved definitions, newest first
  kylon workspace workflow deployments <workflow_id>  show initial deploys, updates, and rollbacks
  kylon workspace workflow rollback <workflow_id> <revision_id> [--force]
    Make an existing immutable revision active for future runs. In-flight runs stay pinned to
    the revision they admitted. A rollback that would put an enabled workflow onto a
    recurring/data-change schedule runs the same verification gate as resume; --force
    overrides it only with the user's explicit confirmation.
  kylon workspace credit budget show --scope workflow --id <workflow_id>
    Show the budget policy for one workflow.
  kylon workspace credit budget set --scope workflow --id <workflow_id> [--daily <credits|default>] [--weekly <credits|default>] [--monthly <credits|default>] [--action warn|pause] [--status active|disabled]
    Update the budget policy for one workflow.
  kylon workspace credit script
    Show the workspace code-run API credit limits used by code this workflow may run.
  kylon workspace workflow trigger <workflow_id> [--verify]  manually run a workflow now; returns a run
    handle — read that run with kylon workspace workflow runs show <run_id>. Without --verify this is a live execution of the
    saved revision: a published Workflow posts the supervising Agent's verified
    report. Script messages are drafts; stdout and stderr stay in run logs.
    --verify marks a REAL run with real billing: connections, SDK agent() calls,
    and direct external writes, sends, or deployments execute normally. It suppresses
    the Workflow's automatic Room report and failure notice; it does not undo or
    suppress external side effects. Before firing, inspect the saved definition and its
    callees and check that existing authorization covers those actions. Follow the
    creation checklist when only partial checks are safe. Read the result in the run record.
    Failures do not count as failure strikes or start another Agent. A successful verification
    run is what lets kylon workspace workflow resume proceed.
  kylon workspace workflow pause <workflow_id>       stop scheduled triggers (manual trigger still works)
  kylon workspace workflow resume <workflow_id> [--force]  re-enable scheduled triggers
    For recurring/data-change workflows, refused when the workflow has no
    successful run yet, or was auto-paused after repeated failures — fix the cause and
    verify only when its real effects are authorized and safe; otherwise leave it paused. --force
    overrides the gate; use it only with the user's explicit confirmation, and
    say so in your reply. The gate is a guardrail with an explicit override,
    not an authorization boundary. Webhook, connection_event, and "at"
    workflows resume freely.
  kylon workspace workflow archive <workflow_id>
Resource link handoff:
- Emit identified Kylon resources as clickable, path-only markdown links with human-readable labels.
- Copy command-returned links verbatim. Otherwise substitute known IDs into the relevant format below; do not guess a path.
- Workflow: `[name](/workspaces/{workspaceId}/rooms/{roomId}/workflows/{workflowId})`

Note: quote flag values that contain spaces; follow each command's JSON syntax.
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.