# Adding telemetry to a repo

Guide for coding agents. Use it when the user asks for usage telemetry, analytics or a phone-home in a project and no telemetry project exists yet. Service: `https://telemetry.anyr.workers.dev`.

## 1. Create the project with its first event

A project is created by its first valid event. There is no signup step.

Pick a slug: lowercase letters, digits and `-`, 2 to 39 chars, usually the repo name. Check that it is free: `curl -s -o /dev/null -w '%{http_code}' https://telemetry.anyr.workers.dev/api/<slug>/stats` prints `404` for a free slug. If it prints `200` and the user does not own it, pick another slug.

Send the first event from your shell, not from the app:

```sh
curl -sS -X POST https://telemetry.anyr.workers.dev/<slug> -H 'content-type: application/json' -d '{"event":"ping"}'
# {"accepted":1,"dropped":0,"project":{"slug":"<slug>","created":true,"admin_token":"tk_...","page_url":"https://telemetry.anyr.workers.dev/<slug>"}}
```

- `project.admin_token` is shown once. It is also in the `x-telemetry-admin-token` header. Tell the user to save it outside the repo, for example in `~/.config/telemetry/<slug>.token`. Never commit it. It is needed to rename the project, rotate the token, import, roll up or delete.
- No `project` in the response means the slug already existed.
- `429` with `new project limit reached for today` means the caps were hit (3 new projects per IP, 100 in total, per UTC day). Try again the next UTC day.
- Optional: set a display name with `PATCH https://telemetry.anyr.workers.dev/api/<slug>` (see https://telemetry.anyr.workers.dev/docs). The slug itself cannot change.

## 2. Follow the project playbook

Fetch `https://telemetry.anyr.workers.dev/<slug>/install.md` and follow it step by step. It has the exact endpoint, payload, snippets for each language, the opt-out rules, a test to add, and a README template.

## Rules

- Anonymous only. No PII: no paths, hostnames, emails, usernames or argument values.
- Honor `DO_NOT_TRACK` and `<APP>_TELEMETRY_DISABLED` (set means any value except empty, `0` or `false`). Skip in CI unless `<APP>_TELEMETRY_CI=1`. `<APP>_TELEMETRY_DEBUG=1` prints the payload instead of sending, with no side effects.
- Fail closed: if the id or the daily stamp cannot be saved, send nothing.
- Fire and forget, timeout 1 second or less, no retries, never block or crash the app.
- Any event with an id counts that id as an active user for the UTC day. Send `install` once, then at most one `ping` per UTC day, plus a few meaningful events.
- Add a test for the opt-outs and a "Telemetry" section in the README.

## More

- API reference: https://telemetry.anyr.workers.dev/docs (raw: https://telemetry.anyr.workers.dev/llms.txt)
- Stats for a project: https://telemetry.anyr.workers.dev/api/<slug>/stats
