CountWatchDocs

Docs / Connect your data

Any other source

A database, a warehouse, a nightly job or another service: pick the way to send its count.

In short: pick the row that matches where your number lives. Each way sends a count, and the first count starts the watch. If your tool can call a link, a webhook URL is the simplest.

Use a recipe when one fits. Otherwise use one of these general methods: every source fits one, and none needs a new endpoint.

Your sourceMethod
A count you can query: a SQL database (Postgres, MySQL, MariaDB), a warehouse or log store (ClickHouse, Tinybird), another service's APIScheduled query → ingest. A cron job or a CI schedule runs every 5 minutes. It counts per 5-minute bucket over the last 2 hours, every bucket, zeros included (generate_series in SQL, WITH FILL in ClickHouse), up to the last complete bucket, and sends them with set to an explicit watch: a re-send replaces a bucket (never doubles it), late rows are picked up, and a stopped job raises the no-data alert. Written out and run in CI: Watch a ClickHouse query.
Your own code sees each event (an app, a worker, a job)Client library: npm install countwatch (Node 20.19+, Bun, Deno) or pip install countwatch (Python 3.9+), then cw.count("orders"). It reads COUNTWATCH_API_KEY and defaults to https://api.countwatch.com; for this host set COUNTWATCH_API_URL=https://magnum-staging.elirais.workers.dev. No package manager? Paste the counter file from the app-counter recipe: the same count() calls, sent every 5 minutes. Each sums per 5 minutes, sends a 0 for each empty 5-minute bucket of every metric it has seen (an explicit watch: a stopped process raises the no-data alert), sends at the account's interval (send_interval_seconds in GET /v1/status, read again after each send) and retries without double counts. Declare metrics at start (metrics) to get zeros before their first event. Serverless (no timer): call flush() before returning; the watch is then a push watch.
A tool that sends webhooks or can call a URL (forms, no-code tools, CI)Webhook URL: made in the dashboard (https://magnum-staging.elirais.workers.dev/dashboard) and pasted into the tool; each hit adds 1 (or ?n=); a delivery id (?id= or the sender's delivery header) counts a retry once. It makes a push watch: the link is called as things happen, so a bucket with no hits is zero.
A shell script or cron job that finishes something often (every few minutes or more)Webhook URL with curl at the end of the script: curl -fsS "$COUNTWATCH_WEBHOOK_URL" (a push watch; npx countwatch send <metric> [n] --dim key=value comes with the npm package). A push watch raises the no-data alert only with expected_interval_minutes set (PATCH /v1/watches/{id}): set it a little above the job's normal gap.
Past data: the scheduled query over the last 89 days, or an export file (CSV)Import once: count per 5 minutes, every bucket (an empty one is a 0), with UTC bucket starts, and send it with POST /v1/import (resolution: "5m"; the API takes up to 90 days back, and the examples take 89 days so the first bucket is still inside the 90 days when the request arrives), ending where the scheduled sends begin. The API stops an import at a watch's first live bucket, so it never overwrites live counts (the add-0 point that creates a push watch does not count). "1h" or "1d" only for a source that keeps nothing finer (they are spread evenly over 5-minute buckets). Only the times of single events (sign-up or order timestamps)? Send {"metric": …, "events": ["2026-08-01T19:04:44Z", …]} instead of counts (up to 10,000 per entry): each adds 1 to its 5-minute bucket, and the empty buckets up to now are filled with 0.

Rules for any method:

The scheduled query's request (ts is each bucket's start, ISO 8601 or Unix milliseconds, at most 6 hours back):

curl -sX POST https://magnum-staging.elirais.workers.dev/v1/ingest -H "Authorization: Bearer $COUNTWATCH_API_KEY" -H "Content-Type: application/json" \
  -d '{"recipe":"scheduled-query","points":[{"metric":"orders","ts":"<bucket start>","set":7},{"metric":"orders","ts":"<next bucket start>","set":0}]}'

For agents: this page as Markdown.