Skip to content

Workflow YAML

Workflow files live in .workflows/ and contain actions, tasks, triggers, connections, and secrets. This page documents every available field.

secrets:
MY_SECRET: "{{ env.MY_SECRET }}"
connection_types:
<name>: { ... }
connections:
<name>: { ... }
actions:
<name>: { ... }
tasks:
<name>: { ... }
triggers:
<name>: { ... }
on_success:
- action: <name>
on_error:
- action: <name>

All top-level keys are optional. A file typically defines actions and tasks.

The top-level on_success and on_error hooks act as workspace-level fallbacks — they fire for top-level jobs when the task itself has no hooks defined for that event type.


Actions are the smallest execution unit. Each action defines what runs on a worker.

Field Type Default Description
type string required Action type: script, docker, pod, task, agent, or approval
name string — Human-readable display name
description string — What this action does
input map {} Input parameter schema (see Input fields)
output object — Output schema (see Output fields)
env map — Environment variables. Values support Tera templates
tags list [] Worker routing tags for step claiming
workdir string — Working directory override
resources object — CPU/memory requests (see Resources)
retry object — Default retry config. Step-level retry overrides action-level (see Retry)

Runs a script in a runner environment with workspace files mounted.

Field Type Default Description
script string — Inline script content. Mutually exclusive with source
source string — Path to script file (relative to workspace root). Mutually exclusive with script
runner string local Execution environment: local, docker, or pod
language string shell Script language: shell, python, javascript (or js), typescript (or ts), go
dependencies list [] Packages to install before running. Requires non-shell language
interpreter string — Override auto-detected interpreter binary (e.g., python3.11)
manifest object — K8s pod manifest overrides. Only valid with runner: pod

Either script or source is required. Cannot use image, cmd, or entrypoint.

Toolchain preferences (auto-detected when interpreter is not set):

  • Python: uv > python3 > python
  • JavaScript: bun > node
  • TypeScript: bun > deno
  • Shell: bash > sh
actions:
run-tests:
type: script
language: python
dependencies: [pytest, requests]
script: |
import pytest
pytest.main(["-v", "tests/"])

Runs a container image as-is, without workspace mounting.

Field Type Default Description
image string required Docker image URI
cmd string — Shell command to run in the container
entrypoint list — Container entrypoint override
command list — Container command args

Cannot use runner, script, source, language, dependencies, or interpreter.

actions:
run-migration:
type: docker
image: myapp/migrations:latest
command: ["migrate", "--target", "latest"]

Runs a Kubernetes pod. Same fields as type: docker, plus:

Field Type Default Description
manifest object — Raw JSON/YAML deep-merged into the generated pod spec

The manifest field supports service accounts, node selectors, tolerations, resource limits, annotations, sidecars, and other pod-level configuration.

actions:
gpu-inference:
type: pod
image: myapp/inference:latest
manifest:
spec:
containers:
- name: main
resources:
limits:
nvidia.com/gpu: "1"
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule

References another task, creating a child job. The step is dispatched server-side (workers never claim it).

Field Type Default Description
task string required Name of the task to execute. May be another workspace’s task (ws.task)
ref string — Branch, tag or full commit SHA of the task’s owner workspace to run the task from — see Git Refs. Only valid on type: task actions

Cannot use any other execution fields (cmd, script, source, image, runner, language, manifest, etc.).

actions:
run-deploy:
type: task
task: deploy-pipeline
tasks:
orchestrate:
flow:
deploy:
action: run-deploy
input:
env: "production"
deploy-pipeline:
input:
env: { type: string }
flow:
# ... steps

Child jobs have a max nesting depth of 10 levels.

With ref, the task is looked up at that ref of its owner workspace and the child runs pinned to the commit the ref resolved to when the parent job was created. A task may call itself at another ref (bounded by the nesting depth). A type: task action carrying ref cannot be used as a hook.

Calls an LLM as a workflow step. The step is dispatched server-side (workers never claim it).

Field Type Default Description
provider string required Provider ID from server config
prompt string required Tera template for the user message
system_prompt string — Tera template for system/instruction message
model string — Override provider’s default model
max_tokens integer — Override provider’s max tokens
temperature number — Override provider’s temperature (0–2)
output object — Output schema (converted to JSON Schema at dispatch)

Cannot use any other execution fields (cmd, script, source, image, runner, language, manifest, task, etc.).

ref is not supported with agents yet: a flow step that names an agent action with ref is rejected with 400, and a tools: [{task: …}] entry with ref is a validation error (a tool call naming it is rejected). Agent steps inside a job that runs on a git ref work and use that commit’s definitions.

actions:
classify-ticket:
type: agent
provider: anthropic-main
system_prompt: "You are a support ticket classifier."
prompt: "Classify this ticket: {{ input.ticket_body }}"
output:
category:
type: string
required: true
options: [bug, feature_request, question]
confidence:
type: number
tasks:
handle-support:
input:
ticket_body: { type: string }
flow:
classify:
action: classify-ticket
input:
ticket_body: "{{ input.ticket_body }}"
route-bug:
action: escalate
depends_on: [classify]
when: "{{ classify.output.category == 'bug' }}"

Pauses execution for human approval/rejection. The step is dispatched server-side (workers never claim it).

Field Type Default Description
message string — Tera template for the approval message shown to approver

Cannot use any other execution fields (cmd, script, source, image, runner, language, manifest, task, provider, prompt, etc.).

actions:
approve-deployment:
type: approval
message: |
Deploy to production?
Version: {{ input.version }}
Environment: {{ input.env }}
tasks:
deploy-workflow:
input:
version: { type: string }
env: { type: string }
flow:
manual-approval:
action: approve-deployment
input:
version: "{{ input.version }}"
env: "{{ input.env }}"
deploy:
action: run-deployment
depends_on: [manual-approval]
input:
version: "{{ input.version }}"

When approved, the step’s output is { "approved": true, "approved_by": "user@example.com", "approved_at": "2025-03-21T10:30:00Z", "input": {...} }. When rejected, the step fails and downstream steps are skipped.


Input parameters define the schema for action and task inputs.

Field Type Default Description
type string required string, text, integer, number, boolean, date, datetime, json, file, or a connection type name. Alias: bool is accepted as a shorthand for boolean and normalized on load
name string — Human-readable label for the UI
description string — Help text
required bool false Whether the field must be provided
secret bool false Mask value in UI and logs
default any — Default value when not provided
options list — Predefined dropdown choices
allow_custom bool false Allow values outside options list
multiple bool false Accept multiple values (requires options). Submitted value is a JSON array; see Multi-select
order integer — Display order in UI (lower = earlier). Fields without order appear last
input:
environment:
type: string
description: Target environment
required: true
options: [staging, production]
version:
type: string
default: "latest"
dry_run:
type: boolean
default: false
order: 99

A file field (task or action level) takes an uploaded file; {{ input.<field> }} renders to a read-only path. It cannot have default, options, allow_custom, multiple or secret. file is a reserved name: a connection type cannot be called file. See File Inputs.

When type is not a primitive, it references a connection type. The input value (a connection name) is resolved to the full connection object at execution time.


Output schemas describe the structured output of an action. Script actions emit output by printing OUTPUT: {json} to stdout. Agent actions use output to instruct the LLM to respond with structured JSON.

actions:
build:
type: script
script: |
echo "Building..."
echo 'OUTPUT: {"artifact": "dist/app.tar.gz", "size": 1024}'
output:
artifact: { type: string }
size: { type: integer }

Output fields are defined directly under the output: key as a flat map of field names to field definitions.

Output field properties:

Field Type Default Description
type String Required string, integer, number, boolean, array, object. Alias: bool is accepted for boolean
description String — Human-readable description
required Boolean false Whether the field must be present
default Any — Default value
options Array — Allowed values (maps to JSON Schema enum)

For agent actions, output is converted to JSON Schema at dispatch time and injected into the system prompt.


CPU and memory requests for runner containers.

Field Type Description
cpu string CPU request (e.g., "500m", "1")
memory string Memory request (e.g., "256Mi", "1Gi")
actions:
heavy-compute:
type: script
runner: pod
resources:
cpu: "2"
memory: "4Gi"
script: "..."

Tasks compose actions into a DAG of steps.

Field Type Default Description
name string — Human-readable display name
description string — What this task does
mode string distributed Execution mode: distributed
folder string — UI folder path (e.g., deploy/staging). Use / for nesting
input map {} Input parameter schema (see Input fields)
flow map required Steps — map of step name to flow step
timeout duration — Job-level timeout. Max 7d (604800s). Cancels entire job when exceeded
retry object — Retry entire task on failure, creating a new job (see Retry)
on_success list [] Hooks to run when the job succeeds
on_error list [] Hooks to run when the job fails
tasks:
deploy-pipeline:
name: Deploy Pipeline
description: Build, deploy, and verify
folder: deploy
timeout: 30m
input:
env: { type: string, default: "staging" }
flow:
build:
action: build-app
deploy:
action: deploy
depends_on: [build]
on_error:
- action: notify
input:
message: "Deploy failed: {{ hook.error_message }}"

Each entry in a task’s flow map defines a step. Steps can reference a named action or define one inline.

Field Type Default Description
action string required Action name to execute. Omit when using inline action
ref string — Run action from this branch, tag or full commit SHA of its owner workspace — see Git Refs. The action need not exist on the default branch. Not allowed when the action is type: agent
name string — Human-readable step display name
description string — What this step does
depends_on list [] Dependencies that must reach a terminal state before this one is decided (see Dependencies for the full {step, accept} / all / any shape)
input map {} Input values passed to the action. Values support Tera templates
continue_on_failure bool false Self-scoped only: if this step fails, its failure does not fail the job. Has no effect on whether anything downstream runs — that’s depends_on’s accept sets on each dependent (see Dependencies)
timeout duration — Step execution timeout. Max 24h (86400s)
when string — Tera condition. Falsy values: empty string, "false", "null", "none" (case-insensitive), "[]", "{}" and any number equal to zero ("0", "0.0")
for_each string or list — Tera expression or literal JSON array. Creates one instance per item
sequential bool false Run for_each instances one at a time instead of in parallel
retry object — Retry configuration for this step (see Retry)

Instead of referencing a named action, define one inline by adding action fields directly on the step:

flow:
greet:
type: script
script: "echo Hello {{ input.name }}"
input:
name: "{{ input.name }}"

All action fields are valid on inline steps (e.g., type, script, source, image, runner, language, env, tags).

flow:
a:
action: step-a
b:
action: step-b
c:
action: step-c
depends_on: [a, b] # waits for both a and b to complete

Steps without depends_on start immediately. Each entry in a depends_on list is one of four shapes; the list itself is an implicit all group:

Shape Meaning
plain-name Sugar for {step: plain-name, accept: [completed]} — today’s default: the dependency must complete
{step: name, accept: [...]} Satisfied iff name’s outcome is in the accept list
{step: name, accept: any} Sugar for all five outcomes below — “wait for it, don’t care how it ends”
{all: [...]} Satisfied iff every nested entry is satisfied (an explicit, nestable AND)
{any: [...]} Satisfied iff at least one nested entry is satisfied (OR)

accept is a non-empty list drawn from five outcomes, or the literal string any (any outcome — not to be confused with the any: group, which needs any one of its entries satisfied):

Outcome Meaning
completed The dependency’s status is completed
failed The dependency’s status is failed
cancelled The dependency’s status is cancelled
skipped The dependency was skipped by its own choice — its own when was false, or its own for_each was empty
omitted The dependency was itself blocked by its own depends_on tree — not its own choice

Readiness is uniform: the gate waits until every step named anywhere in the tree — including nested inside all/any — has reached a terminal state, then evaluates the whole tree exactly once. This holds even when the tree is already conclusively satisfied or unsatisfiable by one child — there’s no fail-fast, and no short-circuiting an any ahead of a still-running sibling. A step whose tree is not satisfied is skipped with skip_reason: unreachable.

all/any nest arbitrarily (an any may contain an all, a step entry, or a bare name). The same step name may appear more than once across different branches with different accept sets — that’s a legitimate way to express an OR over different outcomes of the same dependency, and is accepted. It’s rejected only when the same name is a direct sibling of the same all/any node (including the implicit top-level group): depends_on: [a, a]-style duplicates must be deduplicated.

continue_on_failure is unrelated to any of this — it only controls whether a step’s own failure fails the job (see the continue_on_failure row above), never whether anything downstream runs. See the Conditionals guide for worked examples, and the 0.18 upgrade guide if migrating from continue_on_failure/continue_when_skipped-based gating.

Every skipped step records a skip_reason (condition, empty, or unreachable; a legacy cascade reason can still appear on rows written before 0.18.0 and is read identically to unreachable); see the Conditionals guide.

flow:
deploy:
action: deploy-app
when: "{{ input.env == 'production' }}"
input:
env: "{{ input.env }}"

Evaluated before for_each. If the condition errors, the step fails (not silently skipped). See the Conditionals guide for details.

flow:
deploy:
action: deploy-to-region
for_each: ["us-east-1", "eu-west-1", "ap-south-1"]
input:
region: "{{ each.item }}"
index: "{{ each.index }}"

Creates deploy[0], deploy[1], deploy[2]. Inside instances, each.item is the current value and each.index is the zero-based position.

Downstream steps receive the aggregated output as an array via {{ step_name.output }}.

Limits: max 10,000 items. Step names must not contain [ or ]. See the Loops guide for sequential mode, error handling, and sub-job fan-out.

Accepts human-readable durations: 30s, 5m, 1h30m, or a plain integer (seconds).

flow:
build:
action: build-app
timeout: 10m

Enforced both server-side (recovery sweeper) and worker-side (process cancellation).


Strøm supports two layers of retry: step-level retry (retries the step in-place with backoff) and task-level retry (retries the entire task by creating a new job).

Field Type Default Description
max_attempts integer 3 Maximum number of attempts (including first attempt). Range: 1–10
delay duration "30s" Delay before first retry. Max 1h (3600s). Accepts 30s, 5m, 1h, or integer seconds
backoff string "fixed" Strategy: "fixed" (constant delay) or "exponential" (delay doubles each attempt, capped at 64x)
jitter bool false Add 0–25% random jitter to delay (reduces thundering herd on mass retries)

Retries a single step in-place. When a step fails, the server waits for the configured delay, then resets the step and allows a worker to claim and re-execute it.

actions:
fetch-data:
type: script
script: |
curl https://api.example.com/data || exit 1
echo 'OUTPUT: {"result": "ok"}'
tasks:
main:
flow:
get-data:
action: fetch-data
retry:
max_attempts: 3
delay: "10s"
backoff: exponential

How it works:

  • Attempt 1 fails
  • Wait 10s, then retry (Attempt 2)
  • If Attempt 2 fails, wait 20s, then retry (Attempt 3)
  • If Attempt 3 fails, the step fails; its dependents run only if their own depends_on edge to this step accepts failed — otherwise they’re skipped unreachable
  • All data from previous attempts is discarded; output is only captured from the final attempt

Step-level vs. action-level: If both action and step define retry, the step’s configuration takes precedence:

actions:
api-call:
type: script
script: "curl https://api.example.com"
retry:
max_attempts: 2 # Action default
delay: "5s"
tasks:
main:
flow:
call:
action: api-call
retry:
max_attempts: 4 # Step overrides action's max_attempts
delay: "10s"

Actions can define default retry behavior that applies to all steps using that action, unless the step overrides it:

actions:
unstable-task:
type: script
script: "some-flaky-operation"
retry:
max_attempts: 3
delay: "30s"
backoff: exponential
tasks:
main:
flow:
step1:
action: unstable-task
# Uses action's retry config: 3 max_attempts, 30s delay, exponential backoff
step2:
action: unstable-task
retry:
max_attempts: 5 # Overrides action default

Retries the entire task by creating a new job when the original job fails. This is useful when you want to retry all steps from the beginning on failure.

tasks:
deploy:
retry:
max_attempts: 2
delay: "60s"
flow:
build:
action: build-app
test:
action: run-tests
deploy:
action: deploy-app

How it works:

  • Original job fails at deploy step
  • Server waits 60s, then creates a new job with the same task and input
  • New job starts from build step
  • If the new job also fails, no further retries (max_attempts: 2 exhausted)
  • On final failure, on_error hooks fire only once (not after each retry attempt)

Retry chain: every retry job’s retry_of_job_id points at the first job of the chain; each failed attempt’s retry_job_id points at the attempt that replaced it:

Job 1 (failed) retry_job_id → 2
└─ Job 2 (failed) retry_of_job_id → 1, retry_job_id → 3
└─ Job 3 (success) retry_of_job_id → 1

If the first job has since been deleted by retention, the pointer is cleared (ON DELETE SET NULL), and the next retry points at the attempt that just failed instead — not at the earliest attempt that still exists.

Task retry vs. step retry:

  • Step retry: Faster, smaller scope, good for transient failures (network timeouts, temporary service degradation)
  • Task retry: Slower, full job restart, good for cascading failures (dependency issues, state cleanup needed)

Constant delay between retries. Simple and predictable.

retry:
delay: "30s"
backoff: fixed # or omit (default)

Delays: 30s, 30s, 30s, …

Delay doubles with each attempt (up to a maximum of 64x the initial delay).

retry:
delay: "10s"
backoff: exponential
jitter: true # Recommended for high concurrency

Delays without jitter: 10s, 20s, 40s, 80s (capped at 640s), 640s, …

With jitter, each delay gets ±0–25% random variance:

  • 10s → 7.5s–12.5s
  • 20s → 15s–25s
  • 40s → 30s–50s

Jitter reduces synchronized retries across many workers (thundering herd problem).

Constraint Limit Example
max_attempts 1–10 max_attempts: 5 (5 total attempts)
delay 0–3600s (1h) delay: "30s" or delay: "1h"
Exponential cap 64x initial delay With delay: 10s, max is 640s
Step timeout vs. retry Step timeout applies per attempt Step with timeout: 5m and retry will try up to 5m per attempt

Step retry exhausts first; continue_on_failure then decides whether the job still counts as succeeded, independent of whether next runs (which is next’s own accept set):

flow:
unstable:
action: flaky-operation
retry:
max_attempts: 3
continue_on_failure: true # job still completes even if all retries fail
next:
action: next-step
depends_on:
- step: unstable
accept: [completed, failed]
# Runs even if all 3 retry attempts fail

Loop instances inherit the step’s retry config:

flow:
process:
action: process-item
for_each: [a, b, c]
retry:
max_attempts: 2
# Each instance (process[0], process[1], process[2]) gets max 2 attempts

Retry applies only if the step actually runs:

flow:
deploy:
action: deploy-app
when: "{{ input.env == 'prod' }}"
retry:
max_attempts: 3
# Retries only if condition is true; skipped if condition is false

Step timeout applies per attempt. Task timeout applies to the entire retry chain:

tasks:
main:
timeout: 10m # Total time across all retry attempts
flow:
fetch:
action: fetch-data
timeout: 2m # 2m per attempt
retry:
max_attempts: 3
delay: "30s"

If attempts are 2m, 2m, 2m (6m) plus delays (30s, 30s = 1m), total is 7m — well under the 10m task timeout.

Hooks fire after all retry attempts are exhausted:

tasks:
main:
flow:
unstable:
action: flaky-operation
retry:
max_attempts: 3
on_error:
- action: notify-ops
# Fires only after all 3 attempts fail, not after each attempt

Retried steps are visible in the job detail UI with:

  • Retry badge showing attempt number (e.g., “Attempt 2 of 3”)
  • Timestamp of each attempt
  • Previous attempt’s output (if available)
  • Backoff delay until next retry

Task-level retries create new jobs that appear in the job list, linked by retry_of_job_id.


Hooks fire when a job reaches a terminal state. Defined on tasks or at the top level of the workflow file.

Field Type Default Description
action string required Action to execute. Can be a type: task action for full child job
input map {} Input values. Supports Tera templates with hook context

ref is not supported on hooks yet: a hook with ref, or one whose action is a type: task action carrying ref, is a validation error and is never fired.

Variable Type Description
hook.workspace string Workspace name
hook.task_name string Task that completed/failed
hook.job_id string Job UUID
hook.status string "completed" or "failed"
hook.is_success bool true if completed
hook.error_message string/null All failed step errors combined
hook.source_type string Original job source ("api", "trigger", etc.)
hook.source_id string/null Original job source ID
hook.started_at string/null ISO 8601 timestamp
hook.completed_at string/null ISO 8601 timestamp
hook.duration_secs number/null Execution duration in seconds
hook.failed_steps list Failed step details (see below)
hook.revision string/null Workspace revision pinned on the job (git SHA or folder hash)
hook.ref string/null The git ref the job runs at; null unless it is a pinned job

Each entry in hook.failed_steps:

Field Type Description
step_name string Name of the failed step
action_name string Action that was executed
error_message string/null The step’s error message
continue_on_failure bool Whether this row’s own flow step has continue_on_failure set. A loop instance row reports its placeholder’s flag
tolerated bool Same value as continue_on_failure above — this failure does not by itself fail the job; other untolerated failures or a cancellation can still decide the outcome
tasks:
deploy:
flow:
# ...
on_success:
- action: notify
input:
message: "Deploy completed in {{ hook.duration_secs }}s"
on_error:
- action: notify
input:
message: "Deploy failed: {{ hook.error_message }}"

Hook jobs use source_type = "hook" and never trigger further hooks (recursion guard).


Field Type Default Description
type string required scheduler
cron string required Cron expression (5-field, or 6-field with optional seconds)
task string required Task to execute. May be another workspace’s task (ws.task)
ref string — Branch, tag or full commit SHA of the task’s owner workspace — see Git Refs
input map {} Input values
enabled bool true Whether the trigger is active
timezone string UTC IANA timezone name (e.g., Europe/Copenhagen)
concurrency string allow allow, skip, or cancel_previous
triggers:
nightly-backup:
type: scheduler
cron: "0 2 * * *"
task: run-backup
timezone: "Europe/Copenhagen"
concurrency: skip
Field Type Default Description
type string required webhook
name string required URL-safe name (alphanumeric, -, _). Endpoint: /hooks/{name}
task string required Task to execute. May be another workspace’s task (ws.task)
ref string — Branch, tag or full commit SHA of the task’s owner workspace — see Git Refs
secret string — Auth via ?secret=xxx or Authorization: Bearer xxx
input map {} Default input values. Request body/headers/query merged in
enabled bool true Whether the webhook is active
mode string async async (fire-and-forget) or sync (wait for job completion)
timeout_secs integer 30 Max wait in sync mode (1–300). Returns 202 on timeout
triggers:
github-push:
type: webhook
name: github-ci
task: ci-pipeline
secret: "whsec_your_secret"
mode: sync
timeout_secs: 120

Long-running queue consumer processes that create jobs via OUTPUT: prefix protocol.

Field Type Default Description
type string required event_source
task string required Consumer task that runs continuously
target_task string required Task to create jobs for from emitted events
env map {} Tera-templated environment variables for consumer execution
input map {} Default input merged into each emitted job
restart_policy string always always, on_failure, or never
backoff_secs integer 5 Initial restart delay with exponential backoff
max_in_flight integer — Max concurrent pending/running target jobs (optional, unlimited if omitted)
enabled bool true Whether the consumer is active
triggers:
sqs-events:
type: event_source
task: sqs-consumer
target_task: process-order
env:
QUEUE_URL: "{{ secret.sqs_url }}"
input:
priority: high
restart_policy: always
backoff_secs: 5
max_in_flight: 10

The consumer task runs as a normal job. Any step’s OUTPUT: lines (followed by valid JSON) create jobs for target_task. The input defaults are merged with the emitted JSON (emitted data wins on conflict).

ref is not supported on event-source triggers yet: it is a validation error, and the server does not start such a consumer.


Define schemas for reusable connection configurations.

Field Type Description
properties map Map of property names to property definitions
Field Type Default Description
type string required string, text, integer, number, boolean, date, or datetime. Alias: bool is accepted for boolean
required bool false Whether the property must be provided
default any — Default value
secret bool false Mask in UI and logs
connection_types:
postgres:
host: { type: string, required: true }
port: { type: integer, default: 5432 }
database: { type: string, required: true }
username: { type: string, required: true }
password: { type: string, required: true, secret: true }

Named instances of connection types.

Field Type Default Description
type string — Connection type reference (for validation). Optional for untyped connections
(other keys) any — Property values (flattened alongside type)
connections:
prod-db:
type: postgres
host: "db.example.com"
port: 5432
database: myapp
username: "{{ secrets.DB_USER }}"
password: "{{ secrets.DB_PASS }}"

Use connection names as input values when the input field’s type references a connection type. The name is resolved to the full connection object at execution time.


Key-value map rendered through Tera at workspace load time. Typically sources values from environment variables:

secrets:
DB_PASSWORD: "{{ env.DB_PASSWORD }}"
API_KEY: "{{ env.MY_API_KEY }}"
STATIC_VALUE: "hardcoded-is-fine-too"

Secrets are available in connection values and action templates via {{ secrets.DB_PASSWORD }}.


Timeout fields accept human-readable durations or plain integers (seconds):

Format Example Seconds
Seconds 30s 30
Minutes 5m 300
Hours 1h 3600
Combined 1h30m 5400
Plain integer 300 300