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 window over the last 2 hours, every 5-minute window, zeros included (generate_series in SQL, WITH FILL in ClickHouse), up to the last complete one, and sends them with set to an explicit watch: a re-send replaces a 5-minute window (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, Watch a Postgres query.
Your own code sees each event (an app, a worker, a job)Client library: npm install countwatch (Node 20.19+, Bun, Deno), then import { CountWatch } from "countwatch"; const cw = new CountWatch();, or pip install countwatch (Python 3.9+), then from countwatch import CountWatch; cw = CountWatch(); then cw.count("orders") where the event happens. It reads COUNTWATCH_API_KEY and defaults to https://api.countwatch.com; for this host set COUNTWATCH_API_URL=https://countwatch.com. 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 window 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 (Senders (Connect), https://countwatch.com/dashboard/connections?tab=senders) 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 5-minute window 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] --tag key:value comes with the npm package and sends with COUNTWATCH_API_KEY instead). A push watch raises the no-data alert only with expected_interval_minutes set (PATCH /v1/watches/{watch_id} with an admin key, the watch_id from GET /v1/status; over MCP manage update_watch): 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 5-minute window (an empty one is a 0), with UTC start times, 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 5-minute window 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 5-minute window, 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 windows). Only the times of single events (sign-up or order timestamps)? Send a watches entry {"metric": …, "events": ["2026-08-01T19:04:44Z", …]} instead of counts (up to 10,000 per entry): each adds 1 to its 5-minute window, and the empty 5-minute windows up to now are filled with 0.

Rules for any method:

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

curl -sX POST https://countwatch.com/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.