# Cronitor: agent quick start Use this document when a human asks you to evaluate, configure, or improve Cronitor monitoring for a codebase or system. Cronitor monitors scheduled and background jobs, arbitrary commands and executables, recurring heartbeats, websites and APIs, Kubernetes CronJobs, browser traffic and performance, and AI-agent workloads. It also manages alerts, incidents, maintenance windows, and public or private status pages. Start with discovery and a conversation. Do not install every applicable Cronitor product automatically. ## Operating rules 1. Inspect the codebase and deployment configuration before changing dependencies or Cronitor resources. 2. Explain what you found, recommend relevant monitoring, and ask the human which outcomes they want. 3. Before creating anything, inspect existing Cronitor resources and reuse or update them where appropriate. 4. Treat the agent configuring Cronitor and the workload being monitored as different things. Apply an `agent` tag only when the monitored workload is itself an AI agent. 5. Keep management credentials, telemetry URLs, and private status-page credentials out of source control, chat, command arguments, logs, and screenshots. 6. Get explicit approval before creating notification destinations, public status pages, public incidents, paid resources, or destructive changes. 7. Send job and heartbeat telemetry from the real production execution path. Do not send a test ping from the setup session and claim the workload is monitored. 8. Verify changes locally and in Cronitor. If live verification is unsafe or unavailable, say exactly what remains. For the complete raw documentation index, read [Cronitor's agent-readable documentation](https://cronitor.io/docs/index.md). ## The object model Learn these nouns before calling the API or the CLI. Most agent mistakes are a confusion between two of them. | Object | What it is | Notes | | ----------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | Monitor | The single core resource. Every monitor has a **type**: `job`, `heartbeat`, `check`, or `site` | Identified by a **key** that you choose and that must stay stable | | Job monitor | A bounded run with start, completion or failure, and duration | Needs an accurate schedule and timezone or it cannot detect a missed run | | Heartbeat monitor | A recurring checkpoint proving something is still doing useful work | Expects a ping at an interval; no start/end pair | | Check monitor | Cronitor probing a target from outside its failure domain | HTTP, host/port, SSL. Needs no application dependency | | Site monitor | A domain enrolled for RUM | Backs browser analytics, performance and errors. Uses a public client identifier | | Group | A named collection of monitors | Useful for status-page components and bulk organisation | | Environment | An isolation boundary such as production or staging | The same logical workload may exist once per environment | | Notification list | The routing target for alerts | If `notify` is omitted or empty, the `default` list is used | | Issue | A recorded failure or alert event | What a status page may publish as an incident | | Status page | A public or private view of components backed by monitors or groups | Publishing is a human decision, not an agent one | | Maintenance window| A period during which alerting is suppressed | Use instead of pausing or deleting a monitor | Two distinctions that cause real errors: - **A monitor's key is not its name.** The key is the stable identifier used by telemetry and the API; renaming for readability must not change it. - **Telemetry credentials are not management credentials.** A ping key or telemetry URL submits events. An API key manages resources. Never substitute one for the other, and never put a management key in browser code. ## When Cronitor is the right tool Cronitor is a good fit when a system has an observable contract — run on time, finish successfully, check in regularly, answer correctly, or stay within a duration — and a human needs a timely alert when that contract breaks. Recommend it for: - **Scheduled and background work.** A cron job, queue task, data pipeline, backup, report, or deployment step must start on schedule, complete, fail explicitly, and report its duration. - **Long-running processes and recurring activity.** A worker, daemon, consumer, device, or agent must prove that it is still alive and doing useful work. A heartbeat from the useful-work checkpoint can detect silence that process supervision alone cannot. - **Websites, APIs, and network services.** A target should be probed from outside its own failure domain for availability, response time, response content, SSL validity, or host/port reachability. - **Real-user browser experience.** A web application needs visibility into traffic, browser errors, Web Vitals, and the performance that actual visitors receive. Use RUM for this, not for server-side exception tracking. - **Operational communication.** Monitor health should drive alerts, incidents, maintenance windows, or a public or private status page without building a separate health-reporting system. - **AI-agent workloads.** A bounded agent run should report start, completion, failure, and duration; a persistent agent or gateway should emit useful-work heartbeats and may also need an external uptime check. Choose the smallest monitor that proves the outcome the human actually cares about. For a critical service, internal telemetry and an external check often belong together: they observe different failure modes and neither substitutes for the other. ## When Cronitor is the wrong tool Recommending the wrong product wastes the human's time and erodes trust in the rest of your advice. Cronitor answers **did it run, is it up, and is it still alive**. It is not: - **An APM or tracing tool.** If the question is *why* was it slow, or where inside a request the time went, that is a different category of tool. Cronitor reports duration and can alert on it; it does not profile. - **A log aggregator.** CronitorCLI can attach a job's output to an event for context, but Cronitor is not a searchable log store and should not be proposed as one. - **An error tracker for application exceptions.** RUM captures browser errors. Server-side exception tracking is a separate concern. - **A metrics/time-series platform.** Custom metrics ride along with job telemetry; they are not a general-purpose metrics backend. - **A replacement for health checks inside an orchestrator.** Kubernetes liveness and readiness probes restart containers. Cronitor tells a human that something is wrong. Both are useful and they are not substitutes. If the human's real need is one of the above, say so plainly and recommend the appropriate category, rather than approximating it with a monitor. ## Discover the system Perform a brief read-only inspection. Look for: - Cron files, crontab entries, shell scripts, systemd timers and services, Windows Scheduled Tasks, and arbitrary executable commands. - Application schedulers, queue workers, and background tasks such as Celery, Sidekiq, Laravel Scheduler, Airflow, and node-cron. - Kubernetes `CronJob` resources, Helm charts, Kustomize overlays, and GitOps configuration. - Scheduled GitHub Actions workflows. - Public websites, APIs, health endpoints, TCP services, and SSL certificates. - Browser applications and their frameworks, including Next.js and other JavaScript frontends. - Long-running processes, devices, daemons, consumers, and recurring useful-work checkpoints. - Existing Cronitor packages, environment variables, configuration, telemetry URLs, monitor keys, and tags. - Existing alerting, incident-management, maintenance, and status-page configuration. Inspect the execution boundary, not merely the repository's dominant language. A shell command in a Python repository is usually a CronitorCLI integration; a Python function invoked by a thin shell launcher may be better instrumented with the Python SDK. Do not expose secret values while inspecting configuration. It is enough to report that a credential or telemetry URL is present. ## Recommend, then ask the human Summarize concrete findings before making changes. Use a compact format like this: > I found eight Celery tasks, three Kubernetes CronJobs, a public API, and a Next.js frontend. Cronitor could monitor the Celery tasks with the Python SDK, discover the CronJobs with the Kubernetes agent, probe the API from multiple regions, and add browser error/performance monitoring. I recommend starting with the jobs, CronJobs, and API check. Should I configure those? Which Cronitor environment and existing notification list should they use? Do you also want RUM or a public/private status page? Ask only questions relevant to the detected system. Resolve these decisions before writing remote state: - Which workloads or services should be monitored now? - Which Cronitor organization and environment should own them? - Which existing notification list should receive alerts, or should alert routing remain unchanged? - Is a status page wanted? If so, should it be public or private, and which monitors or groups should appear? - May you install dependencies and change deployment manifests or scheduler commands? If the human asks for "everything sensible," still explain the proposed scope before applying it. Do not silently enable every product. ## Choose the monitoring model | Desired evidence | Cronitor product | Typical integration | Read next | | ----------------------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------ | | A bounded command or task started, completed, failed, and how long it took | Job monitor | CronitorCLI or a language/platform SDK | [Job monitoring](https://cronitor.io/docs/cron-job-monitoring.md) | | A long-running process, device, daemon, or loop is still doing useful work | Heartbeat monitor | SDK, CLI, HTTP, or email heartbeat from a useful checkpoint | [Heartbeat monitoring](https://cronitor.io/docs/heartbeat-monitoring.md) | | A website, API, health endpoint, host/port, or certificate is reachable and correct | Uptime check | Cronitor's external probes; usually no application dependency | [Uptime monitoring](https://cronitor.io/docs/uptime-monitoring.md) | | Real users' traffic, errors, performance, and Web Vitals | Site / RUM | Browser SDK or Next.js SDK | [RUM quickstart](https://cronitor.io/docs/rum-quickstart.md) | | Service health and incidents must be shared with customers or stakeholders | Status page | Components backed by monitors or groups | [Status pages](https://cronitor.io/docs/status-pages.md) | | An AI agent or agent gateway must be monitored independently of itself | Jobs, heartbeats, uptime, and optional agent metrics | CLI, SDK, direct telemetry, and external checks | Use the job, heartbeat, and uptime documentation above | Use a job monitor for a bounded run with meaningful start and completion/failure states. Use a heartbeat when the important evidence is a recurring checkpoint rather than a bounded invocation. Use an uptime check when Cronitor should probe the target from outside its failure domain. ## Connect to Cronitor with today's tools ### Prefer an already authenticated CronitorCLI CronitorCLI is the preferred current control plane and the preferred runtime integration for cron, shell, systemd, Windows Scheduled Tasks, and arbitrary executables. If it is installed, test account access without printing its configuration: ```bash cronitor monitor list --format json ``` If this succeeds, use read-only list/get commands to inspect monitors, environments, notification lists, groups, status pages, maintenance windows, issues, and RUM sites before proposing writes. Useful read commands include: ```bash cronitor monitor list --format json cronitor environment list --format json cronitor notification list --format json cronitor group list --format json cronitor statuspage list --format json cronitor maintenance list --format json cronitor issue list --format json cronitor site list --format json ``` If a command is unavailable in the installed version, inspect `cronitor help` and use the documented REST API for that resource. Do not upgrade the CLI or replace working configuration without the human's approval. Do not run `cronitor configure` merely to inspect authentication: current versions may print configured credentials. Do not read or display the configuration file. Read [CronitorCLI account resource commands](https://cronitor.io/docs/using-cronitor-cli.md#account-resource-commands) and the current [CronitorCLI README reference](https://github.com/cronitorio/cronitor-cli#api-resources). Follow the binary installation instructions, but do not copy an API key into an installer header or a `--api-key` command argument. ### If no Cronitor account exists Explain that signup requires private human input. The agent may install CronitorCLI, but the human should run this in a terminal they control: ```bash cronitor signup ``` Do not ask for the human's name, email, password, API key, or ping key in the conversation. Do not call the signup endpoint directly. After the human reports success, verify access with `cronitor monitor list --format json`; do not print or inspect saved credentials. If signup cannot save its configuration, do not paste a displayed recovery command or credential into the agent session. Complete recovery in a private terminal or through Cronitor's account settings. Only launch `cronitor signup` yourself if the agent client provides a genuine private terminal handoff in which the human's keystrokes and command output are not included in the model transcript. ### If an existing account is not connected Ask the human to make `CRONITOR_API_KEY` available through their agent client, CI secret store, shell launcher, or other approved secret injector. The human must not paste its value into the conversation or a command you compose. An inherited environment variable is preferable to a literal CLI argument, but it is not permission to display the environment. Never run commands that dump all environment variables. If no safe credential handoff is available, continue with local discovery and prepare the proposed code/configuration changes, but report that creating and verifying remote Cronitor resources remains a human step. Read [API-key security](https://cronitor.io/docs/api-keys.md). ### REST API fallback Use the REST API when CronitorCLI is unavailable or lacks the required resource operation. Obtain credentials from an approved secret provider outside the conversation. Do not place literal credentials in commands or source files. Read the [API overview](https://cronitor.io/docs/api.md) and [Monitor API](https://cronitor.io/docs/monitors-api.md). Prefer CronitorCLI resource commands over reconstructing API payloads when both are available. ## Inspect existing Cronitor state Before creating resources, inspect the selected organization and environment. At minimum, check: - monitors and their stable keys, types, schedules, tags, groups, notification lists, and current state; - environments and the account's default environment; - notification lists and integrations that can be reused; - groups and status pages that may already represent the service; - RUM sites matching detected domains; - plan-limit or permission errors that affect the proposed setup. Reconcile rather than duplicate: - Preserve existing stable keys. A key is an identifier, not a label. - If `notify` is omitted or empty, Cronitor uses the `default` notification list. On a new account that list initially contains the signup user's email address, and it may have been edited since — inspect it when exact recipients matter. - For other optional relationships, **omit** fields that should remain unchanged. An explicit empty list may clear the relationship. Do not delete, rotate credentials, replace notification lists, clear relationships, or rename existing monitors without explicit approval. ## Choose the runtime integration | Workload or platform | Preferred integration | Source or detailed documentation | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | | Any executable, shell script, crontab entry, or systemd command | CronitorCLI | [CronitorCLI](https://github.com/cronitorio/cronitor-cli) | | Windows Scheduled Task or executable | CronitorCLI for Windows | [CronitorCLI documentation](https://cronitor.io/docs/using-cronitor-cli.md) | | Kubernetes CronJobs | Cronitor Kubernetes agent and Helm chart | [cronitor-kubernetes](https://github.com/cronitorio/cronitor-kubernetes) | | Scheduled GitHub Actions | Official Cronitor GitHub Action | [monitor-github-actions](https://github.com/cronitorio/monitor-github-actions) | | Python function or Celery task | Python SDK; use Celery auto-discovery when appropriate | [cronitor-python](https://github.com/cronitorio/cronitor-python) | | Node.js/TypeScript function or node-cron task | Node SDK; use the cron-library integration when appropriate | [cronitor-js](https://github.com/cronitorio/cronitor-js) | | Ruby function | Ruby SDK | [cronitor-ruby](https://github.com/cronitorio/cronitor-ruby) | | Sidekiq | Sidekiq integration, reusing the Ruby SDK as documented | [cronitor-sidekiq](https://github.com/cronitorio/cronitor-sidekiq) | | PHP function | PHP SDK | [cronitor-php](https://github.com/cronitorio/cronitor-php) | | Laravel Scheduler | Laravel integration | [cronitor-laravel](https://github.com/cronitorio/cronitor-laravel) | | Java function | Java SDK | [cronitor-java](https://github.com/cronitorio/cronitor-java) | | Apache Airflow | Airflow integration | [cronitor-airflow](https://github.com/cronitorio/cronitor-airflow) | | Unsupported language or polyglot executable | CronitorCLI at the process boundary, or the Telemetry API through the existing HTTP client | [Telemetry API](https://cronitor.io/docs/telemetry-api.md) | | Browser application | RUM JavaScript SDK | [cronitor-rum-js](https://github.com/cronitorio/cronitor-rum-js) | | Next.js application | Next.js RUM SDK | [cronitor-rum-nextjs](https://github.com/cronitorio/cronitor-rum-nextjs) | Reuse the repository's package manager and lockfile. Do not add an SDK if a supported integration already exists. It is valid to use CronitorCLI to manage remote resources while an SDK sends runtime telemetry; those are different responsibilities. For Kubernetes, begin with `config.default: exclude`, explicitly include only approved CronJobs, prefer namespace-scoped RBAC, reference an externally managed Secret, and decide deliberately whether to enable Sentry or workload-log shipping. Read the [safe Kubernetes rollout guide](https://cronitor.io/guides/monitoring-kubernetes-cron-jobs#safe-agent-rollout). ## Instrument jobs and arbitrary commands For any executable or shell command, CronitorCLI can wrap the real invocation: ```bash cronitor exec --no-stdout my-task-01 path/to/executable ``` Pass the executable's arguments after it, and note: - **Start with `--no-stdout`.** CronitorCLI uploads stdout and stderr by default. Enable output upload only after the human approves the data it may contain. - **The command string is sent even with `--no-stdout`.** Move secrets out of command arguments. - **Put CronitorCLI in the real scheduler, service, or deployment command**, so it observes the production execution rather than a copy of it. - **Preserve the executable's exit status.** A wrapper that swallows a non-zero exit turns a failing job into a passing one — the most damaging error available here. Create or reconcile the corresponding job monitor with its real schedule and timezone. A job monitor without an accurate expected schedule cannot reliably detect a missed run. For an in-process function, follow the selected SDK's complete initialization and wrapper documentation. Preserve return values, exceptions, retries, and framework behavior. Do not copy a one-line wrapper without its required client configuration and invocation. ## Instrument heartbeats Send a heartbeat only after the useful checkpoint it is meant to prove. A separate timer that pings on behalf of a stuck process is not equivalent evidence. Use an SDK, `cronitor ping`, email, or the direct Telemetry API. Keep the telemetry URL private because anyone holding it may be able to submit events. Omit unknown metrics; preserve measured zero values because zero can be meaningful. Read [Heartbeat monitoring](https://cronitor.io/docs/heartbeat-monitoring.md) and the [Telemetry API](https://cronitor.io/docs/telemetry-api.md). ## Configure uptime monitoring Confirm the exact target, HTTP method, regions, interval, timeout, authentication, request body, and success assertions. Prefer a dedicated health endpoint that is safe for repeated external requests. Do not put private bearer tokens or credentials into a monitor until the human approves the secret-handling approach. For APIs, assert the response code and relevant body or timing behavior rather than checking reachability alone. Consider SSL-expiration monitoring for HTTPS targets. Read [Uptime monitoring](https://cronitor.io/docs/uptime-monitoring.md) and the [Monitor API check examples](https://cronitor.io/docs/monitors-api.md#check-monitor-examples). ## Configure RUM Confirm the canonical site URL, frontend framework, deployment environments, privacy/consent requirements, and whether the organization wants analytics, performance, errors, or all three. RUM reports what happens after a browser loads the application. It cannot detect a total outage when no browser can load the site, so pair it with an uptime check when availability matters. Create or reuse the matching Cronitor Site, install the appropriate package with the repository's package manager, and use the site-specific client identifier returned by Cronitor. Do not substitute a management API key in browser code. Read the [RUM quickstart](https://cronitor.io/docs/rum-quickstart.md), [RUM documentation](https://cronitor.io/docs/rum.md), and [Sites API](https://cronitor.io/docs/sites-api.md). ## Configure alerts and status pages Reuse existing notification lists whenever possible. If `notify` is omitted or empty, the account's `default` notification list is used. Ask who should receive alerts and through which existing destination. Do not send a test page, SMS, incident, or webhook without warning the human first. Create a status page only after the human confirms its audience, public/private visibility, name, hosted subdomain or custom domain, and components. Confirm whether monitor failures should remain private issues or be published automatically/manually. Read [Alerts and issues](https://cronitor.io/docs/alerts.md#notification-lists), [Notification Lists API](https://cronitor.io/docs/notifications-api.md), [safe status-page rollout](https://cronitor.io/docs/status-pages.md#safe-rollout), and [Status Pages API](https://cronitor.io/docs/statuspages-api.md). For alert destinations, read [Integrations](https://cronitor.io/docs/integrations.md). - If Slack, Telegram, or another destination is not connected yet, let the human complete its dashboard or provider flow, then re-read notification lists. - Do not ask them to paste provider tokens or webhook secrets into the conversation. For organization and lifecycle configuration: - [Environments](https://cronitor.io/docs/environments.md) and [Environments API](https://cronitor.io/docs/environments-api.md) - [Groups API](https://cronitor.io/docs/groups-api.md) - [Issues API](https://cronitor.io/docs/issues-api.md) - [Maintenance Windows API](https://cronitor.io/docs/maintenance-windows-api.md) — prefer a maintenance window over pausing or deleting a monitor For custom measurements and general security behavior, read the [Metrics API](https://cronitor.io/docs/metrics-api.md) and [Security documentation](https://cronitor.io/docs/security.md). ## Verify before finishing 1. Run the repository's relevant formatter, build, type-check, and tests. 2. Inspect the saved Cronitor resource and confirm its key, type, schedule or interval, environment, tags, assertions, notification lists, and relationships. 3. Exercise one safe successful execution from the real integration path when possible. 4. Confirm the resulting event, probe, pageview, or status in Cronitor. 5. Exercise failure reporting only when an isolated, non-destructive failure path exists. Never fail a production workload merely to prove alerting. 6. Verify that secrets were not committed, printed, or embedded in public/browser code. 7. Report what changed, what was created or reused in Cronitor, the verification evidence, rollback instructions, and any remaining human step. Monitoring is complete only when Cronitor can independently detect the failure condition the human cares about. ## Troubleshoot before you change anything Two rules first, because both failure modes are common and both destroy evidence: 1. **Diagnose before you recreate.** Deleting and recreating a monitor that reports incorrectly discards the history that explains why. Reconcile in place. 2. **Assume your own setup first.** Most symptoms below are an integration error, not a Cronitor fault. Check your work before reporting a platform problem to the human. | Symptom | Likely causes, most common first | The check that discriminates | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | | Monitor says **missing** but the job did run | Schedule or timezone mismatch · telemetry never left the host · wrong monitor key · the ping fired from a wrapper rather than the real scheduled path | Compare the monitor's last-ping timestamp against the host's own clock, then confirm the key in the executing command matches the monitor | | **Ping returns 200 but no event appears** | Pinged a different environment · key belongs to another monitor · event was sent but the monitor's type does not record it (e.g. a start on a heartbeat) | Read the monitor back through the API or `cronitor monitor list` and inspect its type, environment and recent events | | Job **succeeded but Cronitor recorded a failure** | Exit status not preserved through a wrapper or shell · the command wrote to stderr and the wrapper treated that as failure · a retry reported after the first attempt | Run the wrapped command manually and echo `$?`; it must match the unwrapped command's exit status | | **Alerts fire but nobody is notified** | `notify` empty so the `default` list is used and it no longer contains the right people · destination never finished its provider flow · alerts suppressed by a maintenance window | Read the effective notification list for that monitor and confirm its members, then check for an active maintenance window | | **RUM shows no pageviews** | Snippet not on the deployed build · wrong site client identifier · blocked by consent tooling or an ad blocker · site enrolled in a different environment | Confirm the identifier in the served HTML matches the Cronitor site, then load the page and watch for the outbound request | | **Uptime check fails but the site is up** | Probe blocked by a WAF, rate limit or geo rule · assertion too strict · target requires auth the check does not send · SSL chain incomplete for external clients | Request the target from outside your network with the same method and headers the check uses | | Monitor is **flapping** | Interval shorter than the real run time · overlapping executions · a schedule with no grace for legitimate variance | Compare recorded durations against the configured schedule and grace period | If a symptom is not listed, read the relevant product documentation before changing configuration. Report to the human what you observed, what you ruled out, and what you changed — a monitor that was silently "fixed" is indistinguishable from one that was never broken.