# CountWatch recipe: GitHub activity

Counts a repository's events (pushes here; pull requests or deployment statuses the same way) per 5 minutes and alerts when activity spikes, drops or stops. GitHub calls a webhook URL: no code runs on your side. Needs admin rights on the repository (the person's), and a CountWatch account (the person signs up at https://staging.countwatch.com/login) and a webhook URL the person makes in the dashboard (Sources, https://staging.countwatch.com/dashboard/sources): it is a secret, so the agent never handles it.

## 1. The webhook URL and the watch

The person makes the webhook URL for `github_pushes` in the dashboard (Sources, https://staging.countwatch.com/dashboard/sources) and keeps it: it is a secret for this one metric, so the agent never sees it. The agent creates the watch as a push watch first (a 5-minute bucket without hits is zero; a watch's source is fixed when it is created): over MCP, `send_counts {"source": "push", "points": [{"metric": "github_pushes","dimensions":{"repo":"<repo>"}, "add": 0}]}`; with an API key:

```
curl -sX POST https://staging.countwatch.com/v1/ingest -H "Authorization: Bearer $COUNTWATCH_API_KEY" -H "Content-Type: application/json" \
  -d '{"source":"push","points":[{"metric":"github_pushes","dimensions":{"repo":"<repo>"},"add":0}]}'
```

Query parameters on the link become dimensions: the watch here must have the same ones as the link's hits (each dimension combination is a watch: mind the plan's watch limit).

## 2. Add the repository webhook

The person adds it: repository **Settings → Webhooks → Add webhook**, payload URL the webhook URL with `?repo=<repo>`, content type `application/json`, event **Just the push event**. Or this, with the person's `gh` login; an agent runs it only when the person's request names this webhook:

```
gh api repos/<owner>/<repo>/hooks --method POST --input - <<'JSON'
{"name": "web", "active": true, "events": ["push"], "config": {"url": "<webhook url>?repo=<repo>", "content_type": "json"}}
JSON
```

One metric per event type: make another link (`github_pull_requests`, events `["pull_request"]`) for another type. GitHub sends an `X-GitHub-Delivery` id, so a redelivery counts once. GitHub's first `ping` event counts 1.

## 3. History (optional)

GitHub keeps no full record of past pushes (the events API returns the last 300 events at most), and commits are not pushes (one push carries several), so a commit count would teach the wrong usual level. Skip the import: the watch learns for about 3 weeks, with starter rules meanwhile.

## Check it works

1. **Data arrives.** `check_setup` (or `curl -s https://staging.countwatch.com/v1/status -H "Authorization: Bearer $COUNTWATCH_API_KEY"`): the `github_pushes {repo=<repo>}` watch shows `last_request_at`, and `missing_buckets_24h` stays `0` (explicit watches). Do what `next_actions` says.
2. **History is in.** `GET /v1/imports/{import_id}` shows `status: done` and the rules chosen for `github_pushes {repo=<repo>}`, with the alerts they would have raised. (Skipped the import? The watch learns for about 3 weeks; starter rules apply meanwhile.)
3. **An alert reaches you.** The person turns on e-mail alerts in the dashboard (https://staging.countwatch.com/dashboard), or you add a webhook (`manage add_destination`, then `verify_destination`; the endpoint answers the challenge, see https://staging.countwatch.com/agent). Then `manage {"action": "send_test_alert"}`: every active destination receives a test alert (`test: true`) within a few minutes.
