Navigation
Getting Started
Guides
Integrations
Guides
Deploy with CLI
How to deploy monitors, alerts, and SLOs from yorker.config.yaml using the Yorker CLI.
Deploy with CLI
The Yorker CLI lets you define monitors, alerts, notification channels, and SLOs in a yorker.config.yaml file and deploy them with a single command. Changes are computed as a diff against the current remote state and applied in the correct order.
Install
npm install -g @yorker/cliAuthenticate
Generate an API key from Settings > API Keys in the dashboard. Export it as an environment variable:
export YORKER_API_KEY=sk_...The CLI also accepts YORKER_API_URL to point at a different control plane (defaults to https://app.yorkermonitoring.com).
Scaffold a config
To create a starter yorker.config.yaml, run:
yorker initThe interactive wizard walks you through project name, first monitor URL, type, and frequency.
Pass flags to skip prompts:
yorker init --name my-app --url https://example.com --type http --frequency 5mConfig file structure
The yorker.config.yaml file has these top-level sections:
project: my-app # Required. Project identifier.
alertChannels: # Notification channel definitions.
ops-slack:
type: slack
webhookUrl: "{{secrets.SLACK_WEBHOOK_URL}}"
defaults: # Default settings for all monitors.
frequency: 5m
locations:
- loc_us_east
- loc_eu_central
groups: # Groups of monitors with shared settings.
- name: API Endpoints
frequency: 1m
monitors:
- name: Users API
type: http
url: https://api.example.com/users
monitors: # Top-level monitor definitions.
- name: Homepage
type: http
url: https://example.com
slos: # Service Level Objectives.
- name: Homepage Availability
monitor: Homepage
target: "99.9%"
window: 30d
maintenanceWindows: # Scheduled silences / pauses.
- name: Weekly DB maintenance
checks: all
mode: pause # pause | continue
startsAt: "2026-04-12T02:00:00Z"
endsAt: "2026-04-12T03:00:00Z"
recurring: true
recurrenceRule: "FREQ=WEEKLY;BYDAY=SU"See the Configuration reference for the full maintenanceWindows schema.
Commands
yorker validate
Validates the config file without deploying. Checks YAML syntax, Zod schema validation, script file existence, secret interpolation, and cross-references (e.g., SLOs referencing valid monitors, alerts referencing valid channels).
yorker validateExit code 0 means the config is valid. Non-zero means errors were found — they are printed to stderr.
yorker diff
Shows what would change between your local config and the remote state without applying anything:
yorker diffOutput shows each resource as CREATE, UPDATE, DELETE, or UNCHANGED, with field-level diffs for updates:
Yorker deploy plan for "my-app"
Checks:
+ CREATE http "API Health" (60s, 2 locations)
~ UPDATE http "Homepage"
~ configJson.timeoutMs 30000 -> 15000
= UNCHANGED browser "Checkout Flow"
Summary: 1 to create, 1 to update, 1 unchanged
(dry run — no changes applied)
yorker deploy
Applies changes to the remote state:
yorker deployResources are applied in dependency order: channels first, then checks (with label sync), then alerts, SLOs, and maintenance windows. See the CLI reference for the full phase table.
Remote resources that exist but are not in your config are reported but not deleted unless you pass --prune.
yorker deploy --prune
Deletes remote resources that are not present in the config file:
yorker deploy --pruneThis is useful for keeping the remote state in exact sync with the config. Prune deletions happen in the correct dependency order as part of the normal deploy phases — SLOs and alerts are removed early (phases A and B, before their parent checks in phase C), maintenance windows at phase I, and channels at phase Z. See the CLI reference for yorker deploy for the full phase table.
yorker deploy --force / --accept-remote
If someone edits a YAML-managed resource via the web UI, the next yorker deploy detects the change and aborts with a drift report. Two flags control how to resolve:
yorker deploy --force # local config wins — overwrite remote
yorker deploy --accept-remote # skip drifted resources — keep remote as-isSee Drift detection below for details.
yorker status
Displays the current state of all monitors:
yorker statusyorker results tail
Live-stream check results as they arrive:
yorker results tail "Homepage" --interval 30syorker test
Runs HTTP monitors locally against their configured URLs. Useful for validating URLs and auth before deploying:
yorker testBrowser monitors are listed but not executed locally (use Playwright directly for local browser tests).
Drift detection
The CLI tracks the state of each deployed resource in .yorker/.deploy-state.json (gitignored, per-machine). After every successful deploy, it saves a config hash and the remote updatedAt timestamp for each resource. On the next deploy, it compares:
- Local changed? — current config hash differs from the stored hash.
- Remote changed? — remote
updatedAtis newer than the stored timestamp, and the resource hasmanagedBy: "yaml".
This produces four possible outcomes:
| Remote unchanged | Remote changed | |
|---|---|---|
| Local unchanged | Skip | Drift (remote-only edit) |
| Local changed | Normal update | Conflict (both sides changed) |
When drift or conflicts are detected, the deploy aborts with a report showing which resources were affected. You have three options:
- Review and choose — inspect the remote changes in the dashboard, then update your config to match or intentionally overwrite.
--force— local config wins, remote changes are overwritten.--accept-remote— drifted resources are skipped, keeping their remote state.
First deploy
On the first deploy (no state file exists), drift detection is skipped entirely — the CLI creates the state file after a successful apply.
After yorker pull
Every successful yorker pull rewrites .yorker/.deploy-state.json with a fresh snapshot of remote state, so the next deploy treats everything as a clean baseline with no drift.
.yorker/.deploy-state.json
This file is per-machine state and should not be committed. Add it to your .gitignore:
.yorker/.deploy-state.jsonSecret interpolation
To keep secrets out of your config file, use placeholder syntax. The CLI resolves these at deploy time from environment variables.
{{secrets.NAME}}
Looks up YORKER_SECRET_NAME first, then falls back to NAME:
auth:
type: bearer
token: "{{secrets.AUTH_TOKEN}}"Set with export YORKER_SECRET_AUTH_TOKEN=... or export AUTH_TOKEN=....
{{env.NAME}}
Looks up the environment variable directly:
monitors:
- name: Staging API
type: http
url: "{{env.STAGING_URL}}/health"${NAME}
Legacy shorthand, equivalent to {{env.NAME}}. Not applied inside browser script files to avoid conflicts with JavaScript template literals.
The CLI fails with a clear error if any placeholder is unresolved after interpolation.
CI/CD integration
Validate on push, preview changes on PRs with yorker diff, and deploy on merge. See the full CI/CD Integration guide for complete GitHub Actions and GitLab CI workflows.
# GitHub Actions — quick start
- run: npm install -g @yorker/cli
- run: yorker validate
- run: yorker diff
- run: yorker deploy --force # CI owns the config
if: github.ref == 'refs/heads/main'Use --force in CI pipelines where the config file is the source of truth. If you want CI to preserve manual edits made via the dashboard, use --accept-remote instead.
Set YORKER_API_KEY and any YORKER_SECRET_* variables at the job or workflow level so all steps — including validate — can resolve {{secrets.*}} placeholders.
Complete example
project: my-app
alertChannels:
ops-slack:
type: slack
webhookUrl: "{{secrets.SLACK_WEBHOOK_URL}}"
on-call-email:
type: email
addresses:
- [email protected]
pagerduty:
type: webhook
url: "{{secrets.PAGERDUTY_WEBHOOK_URL}}"
method: POST
headers:
Authorization: "Token token={{secrets.PD_TOKEN}}"
defaults:
frequency: 5m
locations:
- loc_us_east
- loc_eu_central
http:
timeoutMs: 15000
followRedirects: true
assertions:
- type: status_code
value: 200
browser:
viewport:
width: 1280
height: 720
screenshotMode: every_step
alerts:
- conditions:
- type: consecutive_failures
count: 2
channels:
- "@ops-slack"
groups:
- name: Critical APIs
frequency: 1m
locations:
- loc_us_east
- loc_us_west
- loc_eu_central
alerts:
- conditions:
- type: consecutive_failures
count: 1
- type: multi_location_failure
minLocations: 2
channels:
- "@ops-slack"
- "@pagerduty"
monitors:
- name: Payments API
type: http
url: https://api.example.com/payments
assertions:
- type: status_code
value: 200
- type: response_time
max: 1000
- name: Auth API
type: http
url: https://api.example.com/auth/health
monitors:
- name: Homepage
type: http
url: https://example.com
- name: Checkout Flow
type: browser
script: ./monitors/checkout.ts
frequency: 5m
alerts:
- name: checkout-warning
conditions:
- type: consecutive_failures
count: 2
channels:
- "@ops-slack"
- name: checkout-critical
conditions:
- type: consecutive_failures
count: 5
channels:
- "@pagerduty"
- "@on-call-email"
slos:
- name: Homepage Availability
monitor: Homepage
target: "99.95%"
window: 30d
channels:
- "@ops-slack"
- name: Checkout Availability
monitor: Checkout Flow
target: "99.9%"
window: 30d
channels:
- "@ops-slack"
- "@pagerduty"