Developers

CLI & monitors as code

Manage SutramX monitors from the terminal and keep monitors, status pages and alert channels in a sutramx.yml file with plan, diff and apply.

The sutramx command line tool lets you list and change monitors from your terminal, and keep your whole monitoring setup in a version-controlled sutramx.yml file. You describe monitors, status pages and alert channels in the file, review what would change with sutramx plan, then make it so with sutramx apply.

Install#

The CLI is the npm package @sutramx/cli. It needs Node.js 20 or newer.

bash
npm install -g @sutramx/cli      # or run it without installing: npx @sutramx/cli <command>
sutramx login                    # paste an API key
sutramx monitors list

The source is at github.com/SutramX/cli.

Authenticate#

The CLI uses a workspace API key (it starts with sk_). Create one in Account settings → API keys → Create API key. A key acts on the one workspace it was created in. Whether you can create API keys, and how many, depends on your plan: see Plans & limits.

Every key has one of three access levels, chosen when you create it. The dashboard selects Read-only by default, and the level can't be changed later, so pick the level that the commands you run need:

Access levelWhat it can do from the CLI
Read-onlywhoami, monitors list and get, incidents list and get, maintenance list, init --from-workspace, plan and diff. Every change is refused with 403 READ_ONLY_ACCESS.
StandardEverything above, plus monitors create, pause, resume, delete and adopt, incidents ack and resolve, and apply for monitors and status pages
AutomationEverything above, plus apply for a file that manages integrations (alert channels) or sets per-monitor alert recipients (config.notification_emails)

login works with any level. regions, validate and init without --from-workspace don't need a key at all. plan and diff of a file that sets config.notification_emails also need the Automation level: with any other key the API refuses them with 403 ALERT_ROUTING_NOT_ALLOWED. See REST API for more about keys.

Log in interactively#

bash
sutramx login

The key is read from a hidden prompt (or from stdin when you pipe it in), checked against the API, and saved to a credentials file with permissions 0600. You can also pass it directly with sutramx login --api-key sk_..., but that leaves the key in your shell history.

To remove the saved key:

bash
sutramx logout

Environment variables#

Environment variables take priority over the saved file, which makes them the right choice for CI.

VariableWhat it does
SUTRAMX_API_KEYAPI key to use. Overrides the saved credentials.
SUTRAMX_API_URLAPI base URL. Default https://api.sutramx.com. You only need this for a non-default API. It must use https:// (plain http:// only for localhost). Same as the global --api-url flag.
SUTRAMX_CONFIGFull path of the credentials file to read and write.
XDG_CONFIG_HOMEWhen set (and SUTRAMX_CONFIG isn't), credentials go to $XDG_CONFIG_HOME/sutramx/credentials.json.
SUTRAMX_ALLOWED_ENVComma-separated variable names, or prefixes ending in *, that ${VAR} references in sutramx.yml may read. See Environment variables in the file.
NO_COLORAny value turns off coloured output. Colour is also off when output isn't a terminal.

The default credentials file is ~/.config/sutramx/credentials.json. It holds JSON with api_key, and optionally api_url and workspace_id.

Commands#

Every command supports --help. The global flags are --api-url <url> (also SUTRAMX_API_URL), -V, --version and -h, --help.

CommandWhat it doesKey level
sutramx login [--api-key sk_...]Verify and save an API keyAny
sutramx logoutRemove the saved keyNone
sutramx whoami [--json]Show the workspace, plan, key access level and limitsAny
sutramx monitors listList monitors with live statusRead-only
sutramx monitors get <id-or-key>Print one monitor as JSONRead-only
sutramx monitors create ...Create a monitor, or create-or-update with --keyStandard
sutramx monitors update <id-or-key> ...Change a monitor; only the options you pass changeStandard
sutramx monitors checks <id-or-key>Show a monitor's check history, newest firstRead-only
sutramx monitors run-check <id-or-key>Run one real check now and record itStandard
sutramx monitors pause <id-or-key>Stop checking a monitorStandard
sutramx monitors resume <id-or-key>Restart checks on a paused monitorStandard
sutramx monitors delete <id-or-key>Delete a monitor and its historyStandard
sutramx monitors adopt <id> <key>Give an existing monitor a key so sutramx.yml manages itStandard
sutramx incidents listList incidents, newest firstRead-only
sutramx incidents get <id>Show one incidentRead-only
sutramx incidents ack <id>Acknowledge an ongoing incident (stops escalation)Standard
sutramx incidents resolve <id>Resolve an ongoing incident by handStandard
sutramx incidents note <id> <text>Add a note to an incident timeline (internal unless --public)Standard
sutramx why <monitor-or-incident>Why a monitor is down, or why an alert fired: region votes, quorum, failure class, fault verdict, vendor signals and flakinessRead-only
sutramx maintenance listList maintenance windowsRead-only
sutramx status-pages listList status pagesRead-only
sutramx status-pages get <id-or-slug>Show one status page with its monitorsRead-only
sutramx uptimeUptime report: uptime, incidents, MTTR and health per monitor, plus SLO error budgetsRead-only
sutramx regions [--json]List probe location codesNone
sutramx initWrite a starter sutramx.ymlNone (Read-only with --from-workspace)
sutramx validateCheck sutramx.yml locallyNone
sutramx planShow what apply would changeRead-only (see Authenticate)
sutramx diffLike plan, with every changed field shown old -> newRead-only (see Authenticate)
sutramx applyMake SutramX match the fileStandard, or Automation for integrations and alert recipients

"Key level" is the lowest access level the command works with; a higher level works too.

monitors also works as monitor, incidents as incident, status-pages as status-page, uptime as report, and list as ls (monitors ls, incidents ls, maintenance ls, status-pages ls). monitors delete also works as monitors rm, and incidents ack as incidents acknowledge. Wherever a command takes <id-or-key>, you can pass the monitor's UUID or its monitors-as-code key. Incident commands take the incident's UUID, which incidents list shows.

whoami#

Prints the workspace id, plan and billing market, the key's access level (read_only, standard or automation), the plan's limits (monitors, minimum interval, locations per monitor, status pages) and whether the key can manage integrations. Add --json for the raw response, which also has read_only: true for a read-only key.

monitors list#

FlagWhat it does
--tag <tag>Only monitors with this tag
--status <status>Only monitors in this status: up, down, degraded, paused, pending or maintenance
--jsonPrint the full JSON instead of a table

The table shows ID, KEY, NAME, TYPE, STATUS, 24H uptime, EVERY (interval in seconds) and TARGET.

monitors create#

FlagWhat it doesDefault / limits
--name <name>Display name (required)1–255 characters
--url <url>Target URL for http, api and mcp monitors (mcp needs https://)
--type <type>Monitor type: http, api, ping, port, udp, cron, dns, multistep or mcphttp
--interval <seconds>Seconds between checks, a whole numberPlan default; 15–900 and not below your plan's minimum
--region <code>Probe location; repeat for severalPlan default locations
--tag <tag>Tag; repeat for several
--config <json>Type-specific settings as JSON
--key <key>Stable key: creates the monitor once and updates it on later runs
--pausedCreate it paused
--jsonPrint { action, monitor } as JSON
bash
# A website check from two locations
sutramx monitors create --name "Homepage" --url https://example.com --region fra1 --region usa-az-probe --tag prod

# A TCP port check, idempotent thanks to --key
sutramx monitors create --key infra/postgres --name "Postgres" --type port \
  --config '{"host":"db.example.com","port":5432}'

Without --key, every run creates a new monitor. With --key, the first run creates it and later runs update it, so the command is safe to repeat in scripts. The settings available in --config depend on the monitor type; see Monitors overview and the page for each type.

monitors update#

Takes the same --name, --url, --interval, --tag, --region, --config and --json flags as create, and changes only what you pass. --tag and --region replace all tags or locations, and --config replaces the whole config, so start from sutramx monitors get <id-or-key>.

monitors checks and run-check#

sutramx monitors checks <id-or-key> lists checks, newest first. Flags: --limit <n> (1–500, default 50), --before <time> (ISO-8601, to page back), --region <code>, --status <status> and --json. sutramx monitors run-check <id-or-key> runs one real check now and records it.

monitors delete#

Asks you to type yes before deleting. In scripts, pass -y or --yes; without it, a non-interactive run refuses to delete. Deleting removes the monitor's check history.

monitors adopt#

bash
sutramx monitors adopt 6f1c8f7e-6f2a-4a71-9d0b-0b8c1d2e3f40 web/home

Sets the key of a monitor that was created in the dashboard, so the sutramx.yml entry with that key manages it from now on instead of creating a duplicate.

incidents list#

FlagWhat it doesDefault / limits
--status <status>all, ongoing, resolved, acknowledged or suppressedall
--monitor <id-or-key>Only incidents of this monitor
--search <text>Search the monitor name or URLUp to 200 characters
--from <time>Incidents that started at or after this timeISO-8601, for example 2026-01-31 or 2026-01-31T12:00:00Z
--to <time>Incidents that started at or before this timeISO-8601
--page <n>Page number1 (1–10000)
--page-size <n>Incidents per page25 (1–100)
--jsonPrint the full JSON instead of a table

The table shows ID, MONITOR, STATE (ongoing, acknowledged or resolved), STARTED, DURATION and the REGIONS that confirmed the outage. When there are more incidents, the last line tells you the --page to ask for next.

bash
sutramx incidents list --status ongoing
sutramx incidents list --monitor api/health --from 2026-09-01

incidents get, ack and resolve#

CommandFlags
sutramx incidents get <id>--json prints the full response, with the incident's timeline
sutramx incidents ack <id>--json
sutramx incidents resolve <id>--note <text>: what was done, shown on the incident timeline (up to 5000 characters). --json

sutramx incidents note <id> <text> adds an internal note to the timeline. With --public, it's published as a public update on your status pages; the CLI asks you to confirm unless you pass -y or --yes.

Acknowledging an ongoing incident marks that someone is on it and stops escalation to the next on-call step. Incidents resolve on their own when checks recover, so resolve by hand only when you know the issue is fixed. See Incidents.

bash
sutramx incidents ack 0d7c2a9e-4b1f-4e8a-9c3d-6f2e1a0b9c8d
sutramx incidents resolve 0d7c2a9e-4b1f-4e8a-9c3d-6f2e1a0b9c8d --note "Rolled back the release"

why#

sutramx why <target> prints the Why this alert explanation in the terminal. The target is an incident id, or a monitor id, key, exact name or part of its name or URL.

FlagWhat it does
--no-last-incidentFor a monitor without an open incident, don't also explain its most recent incident
--jsonPrint the structured result (the same shape as the MCP tool sutramx_explain_incident)

The output starts with a one-line summary, then the verdict, whose fault it is (yours, external, checker or unknown), the failure class, the quorum rule and whether it was met, and a table of region votes. Regions whose checks were blocked by bot protection or were inconclusive on our side are marked "abstains": they don't count toward the quorum. Vendor signals and the 7- and 30-day flakiness score follow. A monitor with an open incident explains that incident; otherwise you get its current state and its most recent incident. Paused monitors and active maintenance windows are called out. When several monitors match, the CLI lists them and exits with status 1 instead of guessing.

bash
sutramx why checkout-api
sutramx why 0d7c2a9e-4b1f-4e8a-9c3d-6f2e1a0b9c8d --json

maintenance list#

FlagWhat it does
--status <status>Only windows in this state: scheduled, ongoing, completed or cancelled
--jsonPrint the full JSON instead of a table

The table shows ID, TITLE, STATUS, STARTS, ENDS, REPEATS and SCOPE (all monitors, or the monitors or groups the window covers). The status is the window's live state, so a scheduled window whose start time has passed shows as ongoing. Alerts are silenced while a window is active. The CLI only lists windows: creating, changing and deleting them is done by the workspace owner in the dashboard, see Maintenance windows.

status-pages and uptime#

sutramx status-pages list and sutramx status-pages get <id-or-slug> show your status pages; manage them with sutramx.yml or the dashboard. sutramx uptime prints uptime, incidents, MTTR and health per monitor, plus SLO error budgets. Flags: --days 7|14|30|90 (default 30), --monitor <id-or-key> and --json.

init#

FlagWhat it does
-f, --file <path>File to write (default sutramx.yml)
--from-workspaceDescribe the monitors that exist in the workspace now
--forceOverwrite an existing file

Without --from-workspace, init writes a commented starter file. With it, init exports every monitor with a key, except browser checks, which it skips with a warning. Monitors that had no key get one made from their name (for example "Checkout API" becomes checkout-api), and the file sets adopt_by_name: true so the first apply links them instead of creating copies. If several monitors share a name and type, init lists them: give each one a key with sutramx monitors adopt before you apply.

The export leaves out per-monitor alert recipients (config.notification_emails). Stored credentials, such as secret header values, are written as [REDACTED] because the API never reveals them; apply keeps the stored value as long as the URL's origin is unchanged. Replace [REDACTED] with a value, for example ${ENV_VAR}, to manage it from the file.

validate#

Checks the file's structure, environment variable references and duplicate keys without calling the API. Field rules such as intervals, config and plan limits are checked by plan.

plan, diff and apply#

These three share the same flags:

FlagWhat it does
-f, --file <path>Configuration file (default sutramx.yml)
--pruneDelete keyed monitors that are not in the file. This flag is the only way to delete monitors
--no-pruneNever delete monitors
--adopt-by-nameLink existing unkeyed monitors with the same name and type
--prune-integrationsDelete integrations of the declared types that are not in the file
--workspace <id>The workspace you mean to change: refuse unless the API key acts on it
--jsonJSON output

plan and diff also take --detailed-exitcode. apply also takes:

FlagWhat it does
--auto-approveApply without asking. Required when there is no terminal (CI). -y and --yes do the same
--continue-on-errorKeep going after a failed change instead of stopping
--allow-replaceAllow monitors whose type changed to be deleted, with their history, and created again (--prune also allows it)
--allow-delete-allAllow a prune that deletes every managed monitor because the file declares no monitors
--force-prune-without-plan-checkWith --prune, delete even when the API can't verify that the plan is unchanged

--allow-delete-all is a safety catch: when pruning is on and the file has no monitors at all (for example an empty or truncated file), apply refuses to start unless you pass it.

The sutramx.yml file#

By default the CLI reads sutramx.yml from the current directory; use -f for another path. The file is YAML, and because YAML accepts JSON, a JSON file works too.

yaml
version: 1

defaults:                 # merged into every monitor
  interval_seconds: 60
  tags: [prod]

settings:
  adopt_by_name: false    # true: first apply links existing monitors with the same name and type

monitors:
  - key: web/home
    name: Website
    url: https://www.example.com
    regions: [fra1, usa-az-probe]
    config:
      keyword: Example Domain

  - key: api/health
    name: Public API
    type: api
    url: https://api.example.com/v1/health
    interval_seconds: 30
    config:
      method: GET
      expected_status_codes: [200]
      headers:
        Accept: application/json

  - key: infra/postgres
    name: Postgres
    type: port
    config:
      host: db.example.com
      port: 5432

  - key: jobs/nightly-report
    name: Nightly report job
    type: cron
    config:
      cron_expression: "30 1 * * *"

status_pages:
  - slug: example-status
    title: Example status
    description: Live status of Example's website and API.
    is_public: true
    show_response_times: true
    monitors:
      - web/home
      - key: api/health
        section: API

integrations:             # needs an API key with the Automation access level
  - name: Ops alerts
    type: slack
    config:
      webhook_url: ${SLACK_WEBHOOK_URL}
    routing:
      scope: monitors
      monitors: [web/home, api/health]

The same idea as JSON:

json
{
  "version": 1,
  "monitors": [
    { "key": "homepage", "name": "Homepage", "url": "https://example.com" },
    { "key": "nightly-backup", "name": "Nightly backup", "type": "cron", "config": { "cron_expression": "0 2 * * *" } }
  ]
}
bash
sutramx plan -f sutramx.json

Top-level fields#

FieldWhat it doesDefault / limits
versionFile format version1 (the only value)
defaultsValues merged into every monitorOptional
settingsReconcile behaviour (adoption, workspace check)Optional
monitorsMonitors to manageUp to 500
status_pagesStatus pages to manageUp to 100; optional
integrationsAlert channels to manageUp to 100; optional

Unknown fields anywhere in the file are an error, so typos don't go unnoticed.

defaults#

FieldWhat it does
typeType for monitors that don't set one
interval_secondsInterval for monitors that don't set one
regionsRegions for monitors that don't set them (a list, or null for the plan default)
tagsAdded to every monitor's own tags
configMerged under each monitor's config (the monitor's own keys win)

settings#

FieldWhat it doesDefault
pruneHas no effect except a warning: monitors are only deleted with --prune on the command linefalse
adopt_by_nameOn apply, link an existing unkeyed monitor that has exactly the same name and type, instead of creating a new onefalse
prune_integrationsHas no effect except a warning: integrations are only deleted with --prune-integrations on the command linefalse
workspace_idThe workspace this file describes. apply refuses destructive changes when the API key acts on another workspace

--adopt-by-name on the command line overrides adopt_by_name for a single run. Deleting is never turned on by the file.

monitors#

FieldWhat it doesDefault / limits
keyStable identifier, unique in the workspace. Required.1–128 characters: letters, digits and . _ : / -, starting with a letter or digit
nameDisplay name. Required.1–255 characters
typehttp, api, ping, port, udp, cron, dns, multistep or mcphttp for new monitors
urlTarget URL for http, api and mcp monitors (mcp needs https://)Up to 2048 characters
interval_secondsSeconds between checks15–900, not below your plan's minimum
configType-specific settings (timeout, expected status codes, keyword, headers, host, port, cron expression...)Managed as a whole when present
tagsTagsStored lower-case
regionsProbe location codes, or nullOmit to leave as is; null resets to the plan's default locations
pausedtrue stops checks, false resumes themOmit to leave as is

The config keys for each type are the same as in the dashboard and API. See HTTP & keyword, API & multi-step checks, Ping, TCP & UDP, DNS and Heartbeat & cron. Run sutramx regions for the location codes.

status_pages#

FieldWhat it doesDefault / limits
slugPage identifier and URL slug. Required. Pages are matched by slug.3–64 lower-case letters, digits and hyphens
titlePage title. Required.1–255 characters
descriptionText under the titleUp to 1000 characters; null clears it
is_publicWhether the page is published
logo_urlLogo image URLUp to 2048 characters; null clears it
favicon_urlFavicon URLUp to 2048 characters; null clears it
accent_colorAccent colourHex like #0d9488; null clears it
show_response_timesShow response times on the page
hide_powered_byRemove SutramX brandingOnly on plans with white-label status pages
monitorsMonitors on the page, in display orderUp to 500. Each entry is a monitor key, or { key, section } to group it under a heading

Fields you leave out are not changed. Custom domains, private access and subscribers are set up in the dashboard: see Status pages overview.

integrations#

FieldWhat it doesDefault / limits
nameDisplay name. Required. Integrations are matched by type + name.1–80 characters
typeIntegration type, for example slack, discord, msteams, webhook, pagerduty, opsgenie or telegramWhich types you can use depends on your plan
configThe channel's fields, such as webhook_url for SlackString, number or boolean values
routing.scopeall (every monitor) or monitors (only the listed ones)all
routing.monitorsMonitor keys from this file (or monitor UUIDs) that this channel alerts forUp to 500

The config fields for each channel are described in Slack, Teams & chat apps, Webhooks and PagerDuty & Opsgenie.

Environment variables in the file#

String values can read from the environment, so secrets stay out of your repository:

SyntaxResult
${VAR}The value of VAR. If it is unset or empty, the command fails and names the missing variable.
${VAR:-default}The value of VAR, or default when it is unset or empty
$${VAR}The literal text ${VAR}

A file can never read the CLI's own credentials or CI tokens, such as SUTRAMX_API_KEY, SUTRAMX_CONFIG, GITHUB_TOKEN, GH_TOKEN, ACTIONS_*, INPUT_*, NPM_TOKEN or CI_JOB_TOKEN. When SUTRAMX_ALLOWED_ENV is set, for example SUTRAMX_ALLOWED_ENV=SLACK_WEBHOOK_URL,MYAPP_*, only the listed names and prefixes can be read. Set it in CI, where a pull request may have changed the file. A reference that isn't allowed fails with sutramx.yml references environment variables it may not read.

How plan and apply reconcile#

plan reads the file, asks the SutramX API what would change and prints it. Nothing is changed. Each line has a symbol:

SymbolActionMeaning
+createThe item doesn't exist yet
~updateSome fields change; plan lists their names, diff shows old -> new
-/+replaceThe monitor's type changed, which can't be done in place
-deleteRemoved because of pruning
text
Monitors
  + create  api/health "Public API" [api]
  ~ update  web/home "Website" [http]
      interval_seconds, regions

Plan: 1 to create, 1 to update, 0 to replace, 0 to delete.

apply builds the same plan, shows it, asks you to type yes, then makes the changes and prints one line per change (✓ applied, ✗ failed, · skipped).

Monitors#

  • Monitors are matched by key. Monitors created in the dashboard have no key and are never changed or deleted by apply, unless you adopt them with sutramx monitors adopt or adopt_by_name.
  • A field you leave out is not managed: an existing monitor keeps its current value, and a new monitor gets the same default as in the dashboard.
  • config, when present, is managed as a whole: keys you remove from the file are removed from the monitor. The one exception is notification_emails (per-monitor alert recipients), which is kept unless the file sets it. Setting it needs a key with the Automation access level; with any other key, plan and apply fail with 403 ALERT_ROUTING_NOT_ALLOWED.
  • Changing type shows as a replace: the old monitor is deleted, with its check history and incidents, and a new one is created. apply refuses a replace unless you pass --allow-replace (or --prune).
  • Monitors are validated by the API with the same rules as the dashboard: plan limits, minimum interval, allowed locations and URL safety. plan warns when your plan's monitor allowance or minimum interval would make apply fail.

Status pages#

Status pages are matched by slug and are created or updated. apply never deletes a status page, because pages have public subscribers; delete a page in the dashboard. A page's monitor list can refer to monitors created in the same run.

Integrations#

Integrations are created or updated. Secrets are stored encrypted and only read back masked (for example …abcd), so the CLI compares the visible part: a secret counts as changed when its visible tail differs from your value. A secret changed in the dashboard to something with the same tail isn't detected.

Order and failures#

Apply runs in this order: monitors first, then integrations, then status pages. That way new monitors can be referenced by key in the same file.

By default, apply stops at the first failed change. Changes that already succeeded are kept, and later changes are skipped. Fix the problem and run apply again: only what is still different is changed. With --continue-on-error, apply keeps going and reports every failure at the end.

If the file changes integrations but the key doesn't have the Automation access level, plan shows an error line and apply refuses to start and changes nothing. A read-only key can still run plan and diff, but apply fails with 403 READ_ONLY_ACCESS and changes nothing.

Pruning#

Pruning deletes keyed monitors that exist in the workspace but are no longer in the file.

  • Turn it on for a run with --prune. settings.prune: true in the file only prints a warning.
  • It only touches monitors that have a key. That includes monitors created by the Terraform provider or by an AI tool through the MCP server with a key, so don't enable pruning if other tools manage keyed monitors in the same workspace.
  • Deleting a monitor removes its check history.
  • --prune-integrations deletes integrations that aren't in the file, but only of the types the file declares. A file that only lists Slack channels never removes a PagerDuty connection.
  • If the file declares no monitors at all, apply refuses a prune that would delete every managed monitor unless you pass --allow-delete-all.

Always run sutramx plan before an apply that prunes and check the - lines.

Move an existing workspace to code#

  1. Run sutramx init --from-workspace. It writes a key for every monitor and sets adopt_by_name: true.
  2. Run sutramx plan. It should show no changes except the links to existing monitors, marked "(adopting existing monitor)".
  3. Run sutramx apply.
  4. Commit sutramx.yml. You can remove adopt_by_name once the monitors are linked.

Exit codes#

CodeMeaning
0Success. For plan and diff, also "no changes" when you pass --detailed-exitcode.
1Error: invalid file, missing variable, not logged in, API error, cancelled apply or a failed change
2plan or diff with --detailed-exitcode found changes

Without --detailed-exitcode, plan and diff exit 0 whether or not there are changes.

Use in CI#

In CI, pass the key with SUTRAMX_API_KEY from your CI secrets and use --auto-approve, because apply refuses to run without confirmation when there is no terminal. A job that only runs validate, plan or diff (for example on pull requests or to detect drift) can use a read-only key, unless the file sets config.notification_emails, which needs an Automation key even to plan; the job that runs apply needs a Standard key, or an Automation key when the file manages integrations or alert recipients.

bash
export SUTRAMX_API_KEY="$SUTRAMX_API_KEY_SECRET"
sutramx validate
sutramx plan --detailed-exitcode   # exit 2 = there are changes to review
sutramx apply --auto-approve

For GitHub, the GitHub Action wraps these steps, posts the plan on pull requests and applies on merge.

For machine-readable output, add --json. plan --json returns the full plan (monitor changes, status page and integration changes, warnings, blockers and hasChanges); apply --json returns { ok, changed, steps }.

Troubleshooting#

MessageWhat to do
Not logged in. Run sutramx login or set SUTRAMX_API_KEY.Log in, or set the environment variable
SutramX API keys start with "sk_".You pasted something other than an API key
Environment variables referenced in sutramx.yml are not setExport the listed variables, or give them a default with ${VAR:-default}
sutramx.yml references environment variables it may not readAdd the variables to SUTRAMX_ALLOWED_ENV, or stop referencing a credential the file may never read
... changed type and would be deleted with its history and created againPass --allow-replace if you mean to replace the monitor
Refusing to apply without confirmationAdd --auto-approve in non-interactive runs
Managing integrations needs an API key with the "Automation" access level. (code AUTOMATION_KEY_REQUIRED) or integrations can only be changed with an API key whose access level is "Automation"Create a new key with the Automation access level; a key's level can't be changed
READ_ONLY_ACCESSThe key is read-only. Use a Standard key for changes (or Automation for integrations and alert recipients)
ALERT_ROUTING_NOT_ALLOWEDThe file sets config.notification_emails. Use an Automation key, or remove the field from the listed monitors
the file declares no monitors, so prune would delete all ... managed monitorsCheck the file. Pass --allow-delete-all only if you really want to delete every managed monitor
ENTITLEMENT_LIMIT_REACHED or FEATURE_NOT_AVAILABLEYour plan doesn't allow the change. Check sutramx whoami and Plans & limits.
HTTP 429You were rate limited; wait a few minutes and run again

Validation errors from the API name the monitor key and the field, for example monitor api/health: interval_seconds: ....

Common questions#

Will apply touch monitors I made in the dashboard? No. Only monitors with a key are managed. Adopt a dashboard monitor if you want the file to manage it.

Can I split the configuration over several files? Each run reads one file. If you use several files against one workspace, give them different keys and leave pruning off, or one file's apply will delete the other's monitors.

What happens if apply fails half-way? Completed changes stay. Run apply again after fixing the cause; it only changes what is still different.

Last updated . Something unclear or missing on this page? Tell us at support@sutramx.com.