# cron.watch — full docs for humans and agents > Cron / scheduled-task monitoring: deadman's-snitch check-ins + uptime + latency + custom > metrics. This single file is the complete, machine-readable reference. Base API: > `https://api.cron.watch/v1`. Check-ins: `https://cron.watch/s/`. > > STATUS: cron.watch is pre-launch. The check-in surfaces and this API are the committed > design; sign up at https://cron.watch to get early access and a real API key. Endpoints > marked (roadmap) are not live yet. --- ## 1. Sign up (get an account + API key) The fastest, most compliant path is self-serve — you (or your AI agent) create the account; nobody is cold-emailed. **Via the API (roadmap):** ``` POST https://api.cron.watch/v1/signup Content-Type: application/json { "email": "you@company.com", "name": "Your Name" } ``` Response: ``` { "status": "verify_sent", "verify_url": "https://cron.watch/verify/" } ``` Confirm the email link, then mint an API key: ``` POST https://api.cron.watch/v1/keys Authorization: Bearer { "label": "cli" } -> { "api_key": "cw_live_xxx", "org": "org_default" } ``` **Via MCP (recommended for agents):** call the `signup` tool (see §6). The agent walks the user through email verification and stores the returned key. **Today (pre-launch):** join the waitlist at https://cron.watch/#get — you'll get the API key + MCP access when early access opens. All authenticated requests send `Authorization: Bearer cw_live_...`. --- ## 2. Organizations & teams An **organization** owns monitors, members, alert policies, and billing. Every account gets a default org; create more to separate products or clients. ``` # list orgs GET https://api.cron.watch/v1/orgs # create an org POST https://api.cron.watch/v1/orgs { "name": "Acme Production", "slug": "acme-prod" } -> { "id": "org_a1b2", "slug": "acme-prod" } # invite a member (members are UNLIMITED and FREE — you pay per monitor, not per seat) POST https://api.cron.watch/v1/orgs/acme-prod/members { "email": "teammate@acme.com", "role": "admin" } # roles: owner | admin | member | viewer ``` Pick the org per request with a header `X-Cronwatch-Org: acme-prod`, or rely on your default org. --- ## 3. Create a monitor A **monitor** is one thing you watch. Types: `cron`, `timer`, `latency`, `uptime`, `fleet` (many reporters → one monitor with a quorum rule), `heartbeat` (WebSocket). ``` POST https://api.cron.watch/v1/monitors X-Cronwatch-Org: acme-prod { "name": "nightly-backup", "type": "cron", "schedule": "0 23 * * *", // cron expression, or "every 15m" "grace": "10m", // how late before we alert "max_runtime": "30m", // alert if a run overruns "tags": ["prod", "backup", "postgres"], "slug": "4f9a-nightly" // optional; used in the check-in URL } -> { "id": "mon_77", "slug": "4f9a-nightly", "checkin_url": "https://cron.watch/s/4f9a-nightly" } ``` For a **fleet/quorum** monitor (e.g. "≥5 servers must be up"): set `"type":"fleet", "dimension":"host", "quorum":5, "window":"60s"`. --- ## 4. Check in (tell us a job ran) Four interchangeable surfaces — pick whatever the job can do. The slug comes from the monitor's `checkin_url`. **HTTP (the one-liner everyone starts with):** ``` # bare ping = "I ran" curl -fsS https://cron.watch/s/4f9a-nightly # signal start + exit code → real duration + success/failure curl https://cron.watch/s/4f9a-nightly/start ./run.sh; curl https://cron.watch/s/4f9a-nightly/$? ``` **WebSocket (long jobs, live progress):** ``` wss://cron.watch/s/4f9a-reindex -> {"phase":"index","pct":64,"docs":8100000} ``` A dropped socket mid-run = instant "job died" alert. **Email (legacy boxes):** ``` MAILTO=4f9a-nightly@cron.watch 0 4 * * * /opt/legacy/backup.sh ``` **DNS (cheapest, escapes locked-down networks):** ``` dig +tcp +short 4f9a-nightly.dns.cron.watch # tcp = confirmed check-in ./run.sh; dig +tcp $?.4f9a-nightly.dns.cron.watch # encode exit code in the label ``` --- ## 5. Send data & custom metrics Attach values and metadata to any check-in — they're charted, baselined, and alertable (e.g. "row count dropped 90% vs the trailing week" even when the job exited 0). **On an HTTP check-in (form or JSON):** ``` curl https://cron.watch/s/4f9a-nightly \ -d 'rows=10423&latency_ms=812&queue=4&host=worker-2®ion=eu&version=2.4.1' # or JSON: curl https://cron.watch/s/4f9a-nightly -H 'Content-Type: application/json' \ -d '{"metrics":{"rows":10423,"latency_ms":812},"meta":{"host":"worker-2","exit_code":0}}' ``` **Via the API:** ``` POST https://api.cron.watch/v1/monitors/mon_77/metrics { "metrics": {"rows": 10423, "latency_ms": 812}, "meta": {"host": "worker-2", "region": "eu"} } ``` **Other ingestion paths:** webhook (point existing CI/Stripe/GitHub webhooks at `https://cron.watch/w/`), SFTP drop, or S3 object PUT — see https://cron.watch/metrics.html. Reserved metric names with built-in meaning: `latency_ms`, `duration_ms`, `exit_code`, `rows`. Metadata keys `host`, `region`, `version` become filterable dimensions (and the grouping key for fleet monitors). --- ## 6. MCP server (AI-native) cron.watch ships a Model Context Protocol server so any MCP client (Claude Desktop, Claude Code, Cursor, …) can drive it with natural language. Reference implementation: https://github.com/bitgeek/cronwatch-mcp (Python). Hosted, zero-install endpoint `https://mcp.cron.watch` is (roadmap). Add it to a client config: ```jsonc // claude_desktop_config.json (or any MCP client) { "mcpServers": { "cron.watch": { "command": "python", "args": ["-m", "cronwatch_mcp"], "env": { "CRONWATCH_API_KEY": "cw_live_xxx" } } } } ``` Tools exposed: - `signup(email, name)` — start self-serve signup, return verification status. - `list_organizations()` / `create_organization(name, slug?)` - `invite_member(org, email, role?)` - `create_monitor(name, type, schedule?, grace?, tags?, org?)` — returns the check-in URL. - `list_monitors(org?)` / `get_monitor(monitor)` - `check_in(monitor, status?, duration_ms?)` - `push_metric(monitor, metrics, meta?)` Typical agent flow: `signup` → `create_organization` → `create_monitor` → hand the returned `checkin_url` to the job → `push_metric` from runs. --- ## 7. Pricing - 10 monitors free for 3 months. - Then $0.50 / monitor / month. Prepay $10/yr as account balance, or $5/mo minimum. - Unlimited team members, always free. Billing is per monitor, never per seat. - Enterprise: volume pricing, custom domains, SSO, self-host. ## 8. Alerting Per-monitor policies route to Slack, PagerDuty, OpsGenie, or webhook with escalation (e.g. Slack after 5m → PagerDuty after 15m). Flapping is dampened; maintenance windows mute on schedule; SLO/error-budget burn-down turns raw checks into a contract. ## 9. Sister tools - crontab.in — crontab.guru-style cron-expression builder. - cronwat.ch — run history / observer. - mail.cron.watch — product email (newsletters, alerts).