# Monitors

A monitor watches a subject for you: it checks EarlyWave's sources on a schedule, keeps what matches (events, mentions or a briefing), extracts the fields you asked for and answers your standing questions. You create and tune monitors in the app, on the Monitors page or by asking Ask EarlyWave. The API reads them.

| REST | MCP tool | Returns |
|---|---|---|
| `GET /monitors` | `list_monitors` | The account's monitors. |
| `GET /monitors/{monitor_id}/results` | `get_monitor_results` | What one monitor found, with sources and current answers. |

## List your monitors

```bash
curl "https://api.earlywave.ai/api/v1/monitors" \
  -H "Authorization: Bearer $EARLYWAVE_API_KEY"
```

```json
{
  "monitors": [
    {
      "id": "0b7c6a52-4c1e-4e0b-9a51-2f8d3c1e7a90",
      "name": "Battery plants in Europe",
      "form": "events",
      "status": "active",
      "icon": "🔋",
      "results_count": 23,
      "articles_count": 88,
      "last_check_at": "2026-10-19T08:00:12.000Z",
      "next_check_at": "2026-10-19T09:00:00.000Z",
      "last_result_at": "2026-10-18T16:20:45.000Z",
      "created_at": "2026-10-02T09:14:03.000Z",
      "updated_at": "2026-10-19T08:00:12.000Z",
      "conversation_ref": "agent-5d1fa0c2-8e44-4b7a-9c3e-71a0b2f4d6e8",
      "cadence": { "check_every_hours": 1 },
      "delivery_mode": "realtime",
      "calm_since": null
    }
  ],
  "total": 1
}
```

The list returns every monitor at once (no paging). Archived monitors are left out.

| Field | Meaning |
|---|---|
| `id` | The monitor's ID, a UUID. Pass it to the results operation. |
| `form` | `events` (dated events with fields), `mentions` (articles that mention the subject) or `briefing` (a periodic digest). |
| `status` | `draft`, `active`, `paused` or `calm`. A monitor turns `calm` after 14 days without a result; `calm_since` says since when. |
| `results_count` / `articles_count` | Results kept so far, and the articles behind them. |
| `last_check_at` / `next_check_at` | The latest check and the next one. |
| `cadence` | How often it checks: `{ "check_every_hours": 1 }` (1, 3, 6, 12 or 24). |
| `delivery_mode` | How results are delivered: as they come (`realtime`) or on a schedule (`scheduled`). |
| `conversation_ref` | The conversation that created and tunes the monitor. |

## Get a monitor's results

```bash
curl "https://api.earlywave.ai/api/v1/monitors/0b7c6a52-4c1e-4e0b-9a51-2f8d3c1e7a90/results?days=7" \
  -H "Authorization: Bearer $EARLYWAVE_API_KEY"
```

| Parameter | Default | Meaning |
|---|---|---|
| `days` | 30 | The period, 1–90 days back from now. |
| `query` | — | Only results containing this text. |
| `limit` | 20 | Results to return, 1–100. |

```json
{
  "monitor": { "id": "0b7c6a52-4c1e-4e0b-9a51-2f8d3c1e7a90", "name": "Battery plants in Europe", "…": "…" },
  "period_days": 7,
  "total": 4,
  "limit": 20,
  "has_more": false,
  "results": [
    {
      "id": "c1d7e0f4-2b9a-4f61-8d0e-5a3b7c9e1f20",
      "kind": "event",
      "type": "NEW_PLANT",
      "title": "Battery maker confirms a second plant in northern France",
      "summary": "The plant would open in 2028 with 30 GWh of yearly capacity.",
      "event_date": "2026-10-17T00:00:00.000Z",
      "fields": { "company": "Example Cells", "country": "FR", "capacity_gwh": 30 },
      "confidence": 0.86,
      "cluster_id": 48517,
      "sources_count": 3,
      "first_seen_at": "2026-10-17T16:20:45.000Z",
      "updated_at": "2026-10-18T07:02:11.000Z",
      "hidden_at": null,
      "feedback": null,
      "sources": [
        {
          "item_id": 9920113,
          "url": "https://news.example.fr/battery-plant",
          "title": "A second battery plant for the north",
          "publisher": "Example News",
          "published_at": "2026-10-17T15:58:00.000Z",
          "excerpt": "The company confirmed on Friday…",
          "provenance": "feeds"
        }
      ]
    }
  ],
  "answers": [
    {
      "question": "Which countries announced a new plant this month?",
      "answer": "France and Hungary, one plant each.",
      "changed_at": "2026-10-17T16:20:45.000Z"
    }
  ]
}
```

- `results` are newest first. Results you hid in the app are left out.
- `kind` follows the monitor's form: `event`, `mention` or `digest`.
- `fields` holds the values the monitor extracts, under the keys you defined for it. `type` is the value of its main choice field, when it has one.
- `confidence` is between 0 and 1. The app folds results under 0.6 as uncertain; do the same if you show them to people.
- `cluster_id` is the trend the result belongs to, when there is one: open it with `GET /trends/{trend_id}`.
- `sources[].provenance` says where the source was found: `feeds` (your feeds), `library` (EarlyWave's sources), `story` (a trend's articles) or `web`.
- `answers` are the monitor's standing questions with their current answers, and when each answer last changed.

This operation has no `offset`. When `has_more` is `true`, narrow the period with `days`, filter with `query`, or raise `limit` up to 100.

An ID that is not one of the account's monitors answers `404` with code `monitor_not_found`.

## A weekly digest in a few lines

```python
import os
import requests

API = "https://api.earlywave.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['EARLYWAVE_API_KEY']}"}

monitors = requests.get(f"{API}/monitors", headers=HEADERS, timeout=30).json()["monitors"]
for monitor in monitors:
    page = requests.get(
        f"{API}/monitors/{monitor['id']}/results",
        params={"days": 7, "limit": 100},
        headers=HEADERS,
        timeout=30,
    ).json()
    print(f"\n{monitor['name']}: {page['total']} new")
    for result in page["results"]:
        source = result["sources"][0]["url"] if result["sources"] else ""
        print(f"- {result['title']} {source}")
```

Over MCP, the same question is one sentence: *"Summarise what my monitors found this week, with sources."*

---
Source: https://www.earlywave.ai/developers/docs/monitors · All docs: https://www.earlywave.ai/llms.txt
