# Scheduled reports

> Make a daily, weekly or monthly report of a site or a project, and get it as a webhook, through MCP or with ce report.

A report is the numbers of one window, against the window before, with significance tests. A schedule makes a report each day, week or month, and sends the webhook `report.ready`.

> **Note**
> Checkend sends no email. A report goes out as a webhook, and you read it with `ce report`, the MCP tool `get_report`, the REST API or the Reports view of the web UI.

## What a report contains

Each report covers one window in whole days of a time zone. It compares the window with the window before.

| Part | Content |
|---|---|
| Main numbers | Page views, visitors, conversions and the conversion rate, each with the change, the test, the p-value and the result. |
| Top lists | The top pages, sources and channels. |
| Goals | The numbers of each goal. |
| Revenue | The revenue for each currency, and the revenue of the window before. Checkend never adds currencies. |
| Web vitals | The p75 of each metric. |
| Search | The search totals of the window, when a search source is connected. |
| Findings | The findings opened and closed in the window. |
| Outcomes | The outcomes measured in the window. |
| Warnings | One sentence for each `got_worse` outcome of the window. |
| Annotations | The changes and releases of the window. |
| Summary | One fixed sentence for each site, and one for the loop. |

A report contains computed data and fixed templates only. No model writes its text.

### The windows

| Frequency | Window |
|---|---|
| Daily | The day before the run day. |
| Weekly | The 7 days before the run day. |
| Monthly | The calendar month before. |

The window before has the same number of days. For a monthly report, it is the month before.

### The tests

A count uses the Poisson rate test, with the hours of each window as the exposure. The conversion rate uses the two-proportion z-test. A metric has no test when the window before has no data. The report then says why.

## Add a schedule

Admins and Members can manage schedules.

```sh
ce report schedules add example.com --frequency weekly --weekday monday --hour 7 --time-zone Europe/Berlin
```

| Flag | Meaning | Default |
|---|---|---|
| `--frequency` | `daily`, `weekly` or `monthly`. Monthly runs on day 1. | Required |
| `--weekday` | The weekday of a weekly report. | Monday |
| `--hour` | The local hour, 0 to 23. | 6 |
| `--time-zone` | An IANA time zone, for example `Europe/Berlin`. | UTC |
| `--project` | A report of all sites of a project, in place of one site. | None |

You can also add schedules in the Reports view of the web UI. It proposes the time zone of your browser.

Other commands:

```sh
ce report schedules list
ce report schedules set <id> --hour 8
ce report schedules delete <id> --yes
```

An organization has at most 50 schedules. There are no MCP tools for schedules: an agent reads reports, and a person decides what Checkend sends.

## How a schedule runs

A job checks the schedules every 5 minutes. Change the interval with `--reports-every`. For each schedule, the job finds each run time of the last 30 days that has no report yet. It makes these reports, oldest first, one time for each window. It stores each report and sends `report.ready`.

Thus after downtime, the missed reports of the last 30 days come too. A run time before the schedule existed makes no report.

Checkend keeps reports for 13 months.

## The report.ready webhook

Add a webhook that gets the event `report.ready`:

```sh
ce webhooks add https://agents.example.com/checkend --event report.ready
```

The webhook body has the full report in `report`, and no brief. See [Webhooks](/docs/guides/webhooks.md) for the signature check.

## Read reports

```sh
ce report show example.com                  # the newest report of the site
ce report show --project <id> --frequency monthly
ce report show example.com --date 2026-10-20  # the report whose window has this day
ce report list                              # the stored reports, newest first
```

To get the report as Markdown, add `--format md`. On a pipe, the JSON has the text in `markdown`:

```sh
ce report show example.com --format md | jq -r .markdown
```

The MCP tool `get_report` gives a report by `id`, or the newest report of a `site` or a `project`. With `format` set to `md`, it adds the Markdown text.

## Make a report now

`ce report run` makes a report of the newest complete window now. It needs write access. It sends no webhook.

```sh
ce report run example.com --frequency weekly --time-zone Europe/Berlin
```

Add `--dry-run` to check the request. Checkend then makes no report.

## Prompt for a coding agent

```text
Set up a weekly Checkend report for example.com. Replace example.com with my site.
1. Ask me for my time zone, for example Europe/Berlin.
2. Run `ce report schedules add example.com --frequency weekly --weekday monday --hour 7 --time-zone <zone>`.
3. Run `ce report run example.com --frequency weekly --time-zone <zone>` to make the first report now.
4. Run `ce report show example.com --format md` and summarize the report for me in five lines.
```
