Manifest reference
Complete field reference for the SteadyCron v2 YAML manifest — jobs, channels, rules, variables, tags, and namespaces.
The v2 manifest is the authoritative definition of your SteadyCron account. A single file (or a directory of files) declares every job, alert channel, tag, and variable the CLI manages.
Top-level structure
namespace: my-app # optional — scopes IaC ownership
variables: # server-side template variables (list of objects)
channels: # alert channel definitions
tags: # reusable tag definitions
shaping: # rate-limit hints
jobs: # HTTP jobs and heartbeat checks
# alert rules are declared per job under jobs[].rules
namespace
A string that scopes all resources in this manifest. The CLI only manages (and with
--prune, only deletes) resources that belong to this namespace — so IaC-managed jobs
and manually created jobs can coexist safely in the same account.
namespace: production
Omitting namespace uses the default namespace. See
Namespaces & ownership for multi-environment setups.
jobs[]
Each entry is either an HTTP job (kind: http) that calls your endpoint on a schedule,
or a heartbeat check (kind: heartbeat) that expects a ping from your own cron.
Common fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Stable reconciliation key. When set, renames are safe — the id never changes, so heartbeat ping URLs are preserved. Falls back to name when absent. |
name | string | Yes | Display name shown in the dashboard and alert messages. Must be unique within the manifest. |
kind | http | heartbeat | No | Job type. Defaults to http. |
schedule | string | Yes* | Five-field cron expression (minute hour dom month dow). |
interval | integer | Yes* | Fixed interval in seconds (10–86400). Alternative to schedule. |
timezone | string | No | IANA timezone name, e.g. Europe/Berlin. Defaults to UTC. |
paused | boolean | No | Create or keep the job in a paused state. |
tags | string[] | No | Tag references as "key:value" strings, e.g. ["env:prod", "team:backend"]. |
rules | object[] | No | Per-job alert rules. See Alert rules. |
*Exactly one of schedule or interval is required.
HTTP job fields
| Field | Type | Required | Description |
|---|---|---|---|
method | string | No | HTTP method. One of GET, POST, PUT, PATCH, DELETE. Defaults to GET. |
url | string | Yes | Endpoint to call. Supports ${ENV} (CLI substitution) and {{template_var}} (server-side) placeholders. |
headers | object | No | Additional request headers. Values support ${ENV} placeholders. |
body | string | No | Request body. Supports {{template_var}} placeholders. |
timeout | integer | No | Request timeout in seconds. Defaults to 60. |
retries | integer | No | Number of retries on non-2xx response or timeout. Defaults to 0. |
retry_backoff | integer | No | Seconds between retries. Defaults to 30. |
retry_on_timeout | boolean | No | Count timeouts as failures for retry purposes. Defaults to true. |
retry_on_status | integer[] | No | HTTP status codes that trigger a retry (100–599). |
skip_if_running | boolean | No | Skip execution if the previous run is still active. Defaults to false. |
misfire_policy | string | No | Behavior when a scheduled fire is missed: do_nothing (default) or fire_once_now. |
Heartbeat check fields
| Field | Type | Required | Description |
|---|---|---|---|
grace | integer | No | Seconds to wait after the expected ping time before alerting. Defaults to 60. |
stuck_run_detection | boolean | No | Alert when a run exceeds max_run_duration. Defaults to true. |
max_run_duration | integer | No | Maximum allowed run duration in seconds (60–86400). |
channels[]
Alert channels referenced by job rules via their id or name.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Stable reference key used in jobs[].rules[].channel. |
name | string | Yes | Human-readable name shown in the dashboard and alert messages. |
kind | string | Yes | One of slack, discord, email, telegram, webhook. |
config | object | No | Kind-specific key-value configuration. Use ${ENV} placeholders — never commit real secrets. |
channels:
- id: ops-slack
name: Slack #ops
kind: slack
config:
webhook_url: ${SLACK_WEBHOOK_URL}
Alert rules {#alert-rules}
Alert rules are defined per job under jobs[].rules. Each rule binds a trigger event
to a notification channel.
jobs:
- id: weekly-digest
name: Weekly digest email
kind: http
schedule: "0 9 * * 1"
url: https://api.myapp.com/jobs/digest
rules:
- channel: ops-slack
trigger: on_failure
severity: p1
- channel: ops-slack
trigger: on_recovery
| Field | Type | Required | Description |
|---|---|---|---|
channel | string | Yes | Channel id or name to notify. |
trigger | string | Yes | Event that fires the rule: on_failure, on_recovery, on_missed_heartbeat. |
severity | string | No | Severity label forwarded to the channel (e.g. p1, p2, p3). |
params | object | No | Trigger-specific parameters. |
dedup_window_seconds | integer | No | Alert deduplication window in seconds. |
tags[]
Tags group jobs in the dashboard. Each tag has a key and value; jobs reference them
as "key:value" strings.
tags:
- id: env-prod
key: env
value: prod
- id: team-backend
key: team
value: backend
Job reference: tags: ["env:prod", "team:backend"]
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Stable reference key. |
key | string | Yes | Tag category (e.g. env, team). |
value | string | Yes | Tag value (e.g. prod, backend). |
color | string | No | Hex color code for the dashboard. |
variables
Server-side template variables. Each variable is an object with id, name, and value.
The CLI resolves ${ENV_VAR} in value at apply time; the server substitutes {{name}}
in HTTP job fields at execution time. Secrets never end up in git.
variables:
- id: digest-token
name: digest_token
value: ${DIGEST_TOKEN}
Use {{digest_token}} in HTTP url, headers, or body fields.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Stable reference key. |
name | string | Yes | Variable name used in {{name}} server-side substitutions. |
value | string | No | Variable value. Supports ${ENV_VAR} CLI substitution. |
shaping
Request shaping controls concurrency and rate limits for HTTP jobs — useful when many jobs fire at the same minute and you need to spread load.
shaping:
max_concurrent_jobs: 5
max_jobs_per_minute: 30
| Field | Type | Description |
|---|---|---|
max_concurrent_jobs | integer | Maximum number of HTTP jobs running in parallel. |
max_jobs_per_minute | integer | Maximum HTTP job executions per minute. |
Complete example
namespace: production
variables:
- id: digest-token
name: digest_token
value: ${DIGEST_TOKEN}
channels:
- id: ops-slack
name: Slack #ops
kind: slack
config:
webhook_url: ${SLACK_WEBHOOK_URL}
tags:
- id: env-prod
key: env
value: prod
- id: team-backend
key: team
value: backend
jobs:
- id: weekly-digest
name: Weekly digest email
kind: http
method: POST
url: https://api.myapp.com/jobs/digest
schedule: "0 9 * * 1"
timezone: Europe/Berlin
timeout: 120
retries: 3
tags: ["env:prod", "team:backend"]
rules:
- channel: ops-slack
trigger: on_failure
severity: p1
- channel: ops-slack
trigger: on_recovery
- id: nightly-backup
name: Nightly DB backup
kind: heartbeat
schedule: "0 2 * * *"
grace: 1800
tags: ["env:prod"]
rules:
- channel: ops-slack
trigger: on_missed_heartbeat
severity: p1
Secrets: two mechanisms, side by side
${ENV_VAR_NAME} | {{template_var}} | |
|---|---|---|
| Resolved by | CLI at apply time | Server at execution time |
| Works in | Any field | HTTP job url, headers, body only |
| Use for | API keys, webhook URLs, environment-specific values | Dynamic per-execution values |
| Exported as | Placeholder ${VAR} | Placeholder {{var}} |
steadycron export emits both kinds of placeholder wherever it detects a secret or
a template variable, so the exported manifest is safe to commit as-is.