> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olostep.com/llms.txt
> Use this file to discover all available pages before exploring further.

# モニター

> ページをスケジュールで監視し、変更アラートを送信

Olostepの`/v1/monitors`エンドポイントを通じて、固定スケジュールで実行される永続的なモニターを作成し、ページの変更を検出し、メール、Slack、SMS、または専用のWebhookを通じて通知を受け取ることができます。

* 自然言語の`query`からモニターを作成
* `source_policy`でソースをスコープ
* 自然言語のスケジュールでチェックを実行（最小10分ごと、UTC）
* `notification.channels`とオプションの`webhook`配信を設定
* サーバー送信イベントでプロビジョニングの進行をストリーム（`?stream=1`）
* モニターを一覧表示、検査、更新、一時停止、再開、削除
* スナップショットイベント、計画アーティファクト、実行ログ、ライブエージェントログを読む

デフォルトでは、各モニター実行は監視対象ページの**完全なスナップショット**をキャプチャします — その時点での現在の状態の完全な画像です。モニターが実行間で新しいものや変更されたもの（デルタ）のみを表面化するようにしたい場合は、`query`でその意図を表現してください。

## インストール

<CodeGroup>
  ```python Python theme={null}
  # pip install requests

  import requests
  ```

  ```js Node theme={null}
  // npm install node-fetch

  // ESM
  import fetch from 'node-fetch'

  // CommonJS
  const fetch = require('node-fetch')
  ```

  ```bash cURL theme={null}
  # macOS: 内蔵のcurlで問題ありません
  ```
</CodeGroup>

## モニターを作成

`POST /v1/monitors`でモニターを作成します。APIは入力を検証し、モニターレコードを予約し、シャドウエージェントをプロビジョニングし、ワークフロースペックを生成し、DAG計画をキューに入れ、繰り返しスケジュールを作成します。

* `query`は必須です — 自然言語で監視内容を説明します。
* `frequency`はオプションで、デフォルトは`毎時`です。`毎日午前9時`のようなスケジューリングフレーズを使用します（スケジュールは**UTC**で実行されます; 最小間隔は**10分**です）。
* `source_policy`は、`include_urls`、`exclude_urls`、`include_domains`、`exclude_domains`をオプションで制約します。
* `notification`は、いつどのようにアラートを行うかを設定します（`events` + `channels`）。チャネル配信はモニターパイプラインによって実行時に解決されます — DAGに受信者を渡すことはありません。
* `webhook`は、`notification.channels`に加えてHTTPコールバック用の別のオブジェクト（`{ "url": "https://…" }`）です。
* `output_schema`は、構造化された抽出をオプションで強制します（有効なJSONスキーマ）。

作成の応答はHTTP `202`で、`status: provisioning`です。モニターは計画が`tracked`ターゲットを解決した後に`active`に移行します。`GET /v1/monitors/:monitor_id`をポーリングするか、`?stream=1`（または`Accept: text/event-stream`）を渡して、プロビジョニングフェーズとSSE上のスペック推論トークンを追跡します。

### リクエスト例

必要なのは`query`と`frequency`だけです。通知チャネルとWebhookは後で`POST /v1/monitors/:monitor_id`で追加できます。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"

  payload = {
      "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
      "frequency": "20分ごと",
  }

  headers = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json",
  }

  response = requests.post(f"{API_URL}/monitors", headers=headers, json=payload)
  print(response.status_code)
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'

  const res = await fetch(`${API_URL}/monitors`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      query: 'Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください',
      frequency: '20分ごと',
    }),
  })

  console.log(res.status)
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -sS -X POST "https://api.olostep.com/v1/monitors" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
      "frequency": "20分ごと"
    }'
  ```
</CodeGroup>

### 応答

成功した作成（非ストリーミング）は、モニターオブジェクトを持つHTTP `202`を返します。`tracked`は計画が終了するまで空です。`GET /v1/monitors/:monitor_id`をポーリングして、`status`が`active`になり、`tracked.urls`が埋められるまで待ちます。

```json theme={null}
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
  "tracked": {
    "type": null,
    "urls": [],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "20分ごと",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": null
  },
  "notification": {
    "events": [],
    "channels": []
  },
  "webhook": null,
  "output_schema": {},
  "status": "provisioning",
  "error_message": null,
  "last_run": null,
  "agent": {
    "id": "agent_forward_deployed_0_fda_nlkxhr5kto"
  },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780063071
}
```

### 構造化モニター出力

特定のJSON構造に従って抽出結果を取得したい場合は、`output_schema`を設定します。スキーマは有効なJSONスキーマでなければなりません。

### プロビジョニングストリーム

モニターが作成される間にSSEイベントを受け取るために`?stream=1`を追加するか、`Accept: text/event-stream`を送信します：

| イベント              | 説明                                         |
| ----------------- | ------------------------------------------ |
| `phase`           | プロビジョニングステップ（`running`、`done`、または`failed`） |
| `reasoning_token` | インクリメンタルなスペックデザインテキスト                      |
| `reasoning_reset` | 失敗したLLM試行後にバッファリングされた推論を切り捨てます             |
| `complete`        | 最終モニターオブジェクト（`202`応答と同じ形状）                 |
| `error`           | 終端の失敗                                      |

## 通知とWebhook

アラートはモニターレコードに設定され、実行時に解決されます — モニタリング`query`にチャネルターゲットを埋め込まないでください。

### `notification`

| フィールド      | 説明                                                                                                                                       |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `events`   | どの実行結果が配信をトリガーするかを指定します。下記の[通知イベント](#notification-events)を参照してください。`channels`を設定して`events`を省略した場合、デフォルトは`changed`と`first_snapshot`の両方です。 |
| `channels` | `{ "type", "target", "events"? }`オブジェクトのリスト                                                                                              |

#### 通知イベント

**いつ**通知を受け取りたいかを`events`で指定します。許可される値：

| イベント             | 意味                                                                             |
| ---------------- | ------------------------------------------------------------------------------ |
| `changed`        | 前のスナップショットと比較して**変更**が検出されたときに通知します（例：新しいコンテンツ、更新された価格、またはパイプラインが変更として分類する差分）。 |
| `first_snapshot` | モニターが**最初のスナップショット**を取得したときに通知します — 後の比較の前に現在のコンテンツを保存する初期ベースライン実行。            |

1つまたは両方を含めることができます。例えば、`["changed"]`はベースライン後の更新のみをアラートします；`["first_snapshot"]`は差分を待たずにセットアップを確認します；`["changed", "first_snapshot"]`は両方をカバーします。

チャネルオブジェクトの`events`は同じ値を使用し、そのチャネルのみに対してトップレベルリストをオーバーライドします。

サポートされているチャネルタイプ：

| `type`  | `target`フォーマット              |
| ------- | --------------------------- |
| `email` | 有効なメールアドレス                  |
| `slack` | SlackのインカミングWebhook URL     |
| `sms`   | E.164電話番号（例：`+14155552671`） |

### `webhook`

`notification.channels`とは別に、`webhook.url`はモニターがコールバックURLを発火したときにHTTP POSTペイロードを受け取ります。同じモニターでWebhookとチャネル通知の両方を使用できます。

### 例

メールのみ：

```json theme={null}
{
  "query": "https://example.com/termsの変更を監視",
  "frequency": "毎日午前10時",
  "notification": {
    "events": ["changed"],
    "channels": [
      { "type": "email", "target": "legal@example.com" }
    ]
  }
}
```

Webhookコールバック：

```json theme={null}
{
  "query": "https://example.com/termsの変更を監視",
  "frequency": "毎日午前10時",
  "webhook": {
    "url": "https://hooks.example.com/olostep-monitor"
  }
}
```

SMS：

```json theme={null}
{
  "query": "https://status.example.comがインシデントを示したときに通知",
  "frequency": "毎時",
  "notification": {
    "channels": [
      { "type": "sms", "target": "+14155552671" }
    ]
  }
}
```

## ソースポリシー

`source_policy`を使用して、プランナーが使用できるURLとドメインを制約します。

```json theme={null}
{
  "source_policy": {
    "include_urls": ["https://example.com/pricing"],
    "exclude_domains": ["ads.example.com"]
  }
}
```

## 頻度

自然言語で`frequency`を設定します。例えば：

* `毎時`（省略時のデフォルト）
* `毎日午前9時`
* `毎週日午後2時30分`

ルール：

* スケジューリング言語として読み取れる必要があります（任意のモニター質問ではありません）。
* 最小間隔：**10分ごと**。
* スケジュールは**UTC**で保存および実行されます（`schedule.timezone`は`UTC`です）。
* 最大長：50文字。

APIは`frequency`テキストからcron式を導出し、`schedule.cron`で公開します。モニターが`active`の場合、`schedule.next_run_at`は次の実行をISO 8601で示します。

## モニターを一覧表示

`GET /v1/monitors`でチームのすべてのモニターを取得します。

デフォルトでは、削除されたモニターはフィルタリングされます。`?include_deleted=true`を使用してそれらを含めます。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"

  headers = { "Authorization": f"Bearer {API_KEY}" }

  response = requests.get(f"{API_URL}/monitors", headers=headers)
  result = response.json()
  print(f"Total monitors: {result['count']}")
  print(json.dumps(result, indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'

  const res = await fetch(`${API_URL}/monitors`, {
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>' }
  })
  const result = await res.json()

  console.log(`Total monitors: ${result.count}`)
  console.log(result.monitors)
  ```

  ```bash cURL theme={null}
  curl -s -X GET "https://api.olostep.com/v1/monitors" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

### 応答の形状

```json theme={null}
{
  "monitors": [
    {
      "id": "monitor_0wj35czpn7",
      "object": "monitor",
      "query": "AirOpsブログで新しいブログ投稿を監視",
      "tracked": {
        "type": "urls",
        "urls": ["https://www.airops.com/blog"],
        "web_query": null
      },
      "source_policy": {},
      "schedule": {
        "frequency": "毎時",
        "cron": "2 * * * ? *",
        "timezone": "UTC",
        "next_run_at": null
      },
      "notification": {
        "channels": [],
        "events": []
      },
      "webhook": null,
      "output_schema": {},
      "status": "paused",
      "error_message": null,
      "last_run": null,
      "agent": { "id": "agent_forward_deployed_0_fda_x4822l9h3i" },
      "metadata": {},
      "created": 1780062756,
      "updated": 1780063025
    },
    {
      "id": "monitor_biglavgvq3",
      "object": "monitor",
      "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
      "tracked": {
        "type": "urls",
        "urls": ["https://www.ycombinator.com/launches/"],
        "web_query": null
      },
      "source_policy": {},
      "schedule": {
        "frequency": "20分ごと",
        "cron": "7/20 * * * ? *",
        "timezone": "UTC",
        "next_run_at": "2026-05-29T14:27:00.000Z"
      },
      "notification": {
        "channels": [],
        "events": []
      },
      "webhook": null,
      "output_schema": {},
      "status": "active",
      "error_message": null,
      "last_run": null,
      "agent": { "id": "agent_forward_deployed_0_fda_nlkxhr5kto" },
      "metadata": {},
      "created": 1780063068,
      "updated": 1780063141
    }
  ],
  "count": 5
}
```

## モニターを取得

`GET /v1/monitors/:monitor_id`で単一のモニターを取得します。

応答には`last_run`（最新のスナップショットの概要）と`total_count`（スナップショットの数）が含まれますが、`include_total_count=false`を渡さない限り。`include-diagram=true`を追加して、モニターDAGの`mermaid_diagram`を含めます。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  headers = { "Authorization": f"Bearer {API_KEY}" }

  response = requests.get(f"{API_URL}/monitors/{MONITOR_ID}", headers=headers)
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}`, {
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>' }
  })
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X GET "https://api.olostep.com/v1/monitors/monitor_biglavgvq3" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

### 応答の形状

```json theme={null}
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.ycombinator.com/launches/"],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "20分ごと",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T14:27:00.000Z"
  },
  "notification": {
    "channels": [],
    "events": []
  },
  "webhook": null,
  "output_schema": {},
  "status": "active",
  "error_message": null,
  "last_run": {
    "id": "run_iwsoafcpyx",
    "status": "completed",
    "change_detected": false,
    "ran_at": "2026-05-29T14:03:15.963Z"
  },
  "agent": {
    "id": "agent_forward_deployed_0_fda_nlkxhr5kto"
  },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780063141,
  "total_count": 1
}
```

## モニターイベントを一覧表示

`GET /v1/monitors/:monitor_id/events`を使用して、モニターのスナップショットイベントを一覧表示します。

ページネーション：

* `limit`（デフォルト`25`、最大`100`）
* `cursor`（`next_cursor`からの不透明なトークン）
* `count_only=true`は`{ "total_count": N }`のみを返します

イベントは新しいものから順に返されます。各アイテムには短命の署名付き`snapshot_url`が含まれます。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  headers = { "Authorization": f"Bearer {API_KEY}" }

  response = requests.get(
      f"{API_URL}/monitors/{MONITOR_ID}/events?limit=10",
      headers=headers,
  )
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}/events?limit=10`, {
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>' }
  })
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X GET "https://api.olostep.com/v1/monitors/monitor_biglavgvq3/events?limit=10" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

### 応答の形状

```json theme={null}
{
  "data": [
    {
      "id": "run_iwsoafcpyx",
      "run_id": "run_iwsoafcpyx",
      "created": 1780063395,
      "changed": false,
      "summary": "このモニターの最初のスナップショットが撮影されました。現在のコンテンツをベースラインとして保存しました。",
      "snapshot_url": "https://olostep-monitor-snapshots.s3.amazonaws.com/monitor_biglavgvq3/run_iwsoafcpyx_snapshot.json?X-Amz-Expires=600&..."
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total_count": 1
}
```

## モニタープランニングを取得

`GET /v1/monitors/:monitor_id/planning`を使用して、プロビジョニング後のFDAワークフロースペックとプランナーDAGを検査します。

```json theme={null}
{
  "spec": {
    "saved_at": "2026-05-29T12:00:00.000000+00:00",
    "status": "complete",
    "goal": "example.comの価格を追跡",
    "reasoning": "...",
    "constraints": "...",
    "assumptions": "...",
    "input": { "query": "...", "urls": ["https://www.ycombinator.com/launches/"] },
    "output": { "type": "free_text" },
    "chat_history": []
  },
  "dag": {
    "user_query": "...",
    "graph": { "nodes": [], "edges": [] },
    "has_unresolved": false,
    "unresolved": [],
    "validation": { "is_valid": true, "attempts": 1, "history": [] }
  }
}
```

## モニター実行を取得

`GET /v1/monitors/:monitor_id/runs/:run_id`を使用して、1回の実行（`run_id`は`run_`で始まる必要があります）のスナップショットメタデータと解析されたエージェントログイベントを取得します。

```json theme={null}
{
  "monitor_id": "monitor_biglavgvq3",
  "run_id": "run_v7k2p9m3",
  "snapshot": { "changed": true, "summary": "..." },
  "log_group": "/aws/ecs/olostep-agents/...",
  "events": [
    {
      "id": "...",
      "ts": 1777960800123,
      "message": "Run run_v7k2p9m3 completed. Files uploaded: 2",
      "event": { "type": "run_complete", "run_id": "run_v7k2p9m3", "files_uploaded": 2 }
    }
  ]
}
```

## エージェントログをストリーム

`GET /v1/monitors/:monitor_id/agent-logs?stream=1`（または`Accept: text/event-stream`）を使用して、モニターのエージェントのCloudWatchログをこの`monitor_id`にフィルタリングして追跡します。

オプションのクエリパラメータ`since`はミリ秒のタイムスタンプです（デフォルト：30分前）。

SSEイベントタイプ：`ready`、`log`、`heartbeat`、`error`。

## モニターを更新

`POST /v1/monitors/:monitor_id`でモニターを更新します。

サポートされているフィールド（変更したいものだけを含めてください）：

* `metadata` — 既存のキーとマージされます; 空の文字列値はキーを削除します
* `frequency` — 内部スケジュールを再作成し、`status`を`active`に戻します
* `notification` — 通知オブジェクト全体を置き換えます
* `webhook` — 削除するには`null`を渡します

`status`が`provisioning`の間は`409`を返します。

`notification.channels`を`events`なしで追加すると、APIはデフォルトで`events`を`["changed", "first_snapshot"]`に設定します。

### メール通知を追加

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  payload = {
      "notification": {
          "channels": [
              {"type": "email", "target": "you@example.com"}
          ]
      }
  }

  headers = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json",
  }

  response = requests.post(
      f"{API_URL}/monitors/{MONITOR_ID}",
      headers=headers,
      json=payload,
  )
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      notification: {
        channels: [{ type: 'email', target: 'you@example.com' }]
      }
    })
  })
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/monitors/monitor_biglavgvq3" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "notification": {
        "channels": [
          { "type": "email", "target": "you@example.com" }
        ]
      }
    }'
  ```
</CodeGroup>

```json theme={null}
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.ycombinator.com/launches/"],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "20分ごと",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T14:27:00.000Z"
  },
  "notification": {
    "events": ["changed", "first_snapshot"],
    "channels": [
      { "type": "email", "target": "you@example.com" }
    ]
  },
  "webhook": null,
  "output_schema": {},
  "status": "active",
  "error_message": null,
  "last_run": null,
  "agent": { "id": "agent_forward_deployed_0_fda_nlkxhr5kto" },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780064634
}
```

### Webhookを追加

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  payload = {
      "webhook": { "url": "https://webhook.site/your-unique-id" }
  }

  headers = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json",
  }

  response = requests.post(
      f"{API_URL}/monitors/{MONITOR_ID}",
      headers=headers,
      json=payload,
  )
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      webhook: { url: 'https://webhook.site/your-unique-id' }
    })
  })
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/monitors/monitor_biglavgvq3" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "webhook": { "url": "https://webhook.site/your-unique-id" }
    }'
  ```
</CodeGroup>

```json theme={null}
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.ycombinator.com/launches/"],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "20分ごと",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T14:47:00.000Z"
  },
  "notification": {
    "channels": [
      { "type": "email", "target": "you@example.com" }
    ],
    "events": ["changed", "first_snapshot"]
  },
  "webhook": {
    "url": "https://webhook.site/your-unique-id"
  },
  "output_schema": {},
  "status": "active",
  "error_message": null,
  "last_run": null,
  "agent": { "id": "agent_forward_deployed_0_fda_nlkxhr5kto" },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780065538
}
```

## モニターを一時停止

`POST /v1/monitors/:monitor_id/pause`でモニターを一時停止します。

一時停止すると、基礎となるスケジュールが無効になり、`status`が`paused`に設定されます。`status: active`のモニターのみが一時停止できます。リクエストボディは空です。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  response = requests.post(
      f"{API_URL}/monitors/{MONITOR_ID}/pause",
      headers={ "Authorization": f"Bearer {API_KEY}" },
  )
  print(response.status_code)
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}/pause`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>' }
  })
  console.log(res.status)
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/monitors/monitor_biglavgvq3/pause" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

成功すると、`200`とモニターが返され、`status: paused`になります。`schedule.next_run_at`は一時停止中は`null`です。

## モニターを再開

`POST /v1/monitors/:monitor_id/resume`で一時停止されたモニターを再開します。

再開すると、スケジュールが再び有効になり、`status`が`active`に戻ります。一時停止されたモニターのみが再開できます。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  response = requests.post(
      f"{API_URL}/monitors/{MONITOR_ID}/resume",
      headers={ "Authorization": f"Bearer {API_KEY}" },
  )
  print(response.status_code)
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}/resume`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>' }
  })
  console.log(res.status)
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/monitors/monitor_biglavgvq3/resume" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

## モニターを削除

`DELETE /v1/monitors/:monitor_id`でモニターを削除します。

削除はモニターローをソフト削除し（`status: deleted`）、そのスケジュールとシャドウエージェントリソースを削除します。

<CodeGroup>
  ```python Python theme={null}
  import requests
  import json

  API_KEY = "<YOUR_API_KEY>"
  API_URL = "https://api.olostep.com/v1"
  MONITOR_ID = "monitor_biglavgvq3"

  response = requests.delete(
      f"{API_URL}/monitors/{MONITOR_ID}",
      headers={ "Authorization": f"Bearer {API_KEY}" },
  )
  print(json.dumps(response.json(), indent=2))
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'
  const monitorId = 'monitor_biglavgvq3'

  const res = await fetch(`${API_URL}/monitors/${monitorId}`, {
    method: 'DELETE',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>' }
  })
  console.log(await res.json())
  ```

  ```bash cURL theme={null}
  curl -s -X DELETE "https://api.olostep.com/v1/monitors/monitor_biglavgvq3" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY"
  ```
</CodeGroup>

## モニターステータス

| ステータス          | 意味                                              |
| -------------- | ----------------------------------------------- |
| `provisioning` | エージェント、スペック、プランナー、スケジュールが設定中                    |
| `active`       | スケジュールが有効; `schedule.frequency`で実行が行われる         |
| `paused`       | `/pause`でスケジュールが無効                              |
| `failed`       | プロビジョニングまたはスケジュール更新が失敗（`error_message`が設定されている） |
| `deleted`      | `DELETE`でソフト削除                                  |

## 使用例

以下は一般的なモニターパターンです。各例は作成時に`query`と`frequency`のみが必要です; 初回実行または変更時にアラートを受け取りたい場合は、後で`notification`と`webhook`を追加します。

### Y Combinatorの新しいローンチ

[Y Combinator Launches](https://www.ycombinator.com/launches/)で新しく公開されたスタートアップを監視します。計画後、`tracked.type`は`urls`で、`tracked.urls`はローンチページを指します。

<CodeGroup>
  ```python Python theme={null}
  import requests

  API_URL = "https://api.olostep.com/v1"
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json",
  }

  requests.post(
      f"{API_URL}/monitors",
      headers=headers,
      json={
          "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
          "frequency": "20分ごと",
      },
  )
  ```

  ```js Node theme={null}
  const API_URL = 'https://api.olostep.com/v1'

  await fetch(`${API_URL}/monitors`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      query: 'Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください',
      frequency: '20分ごと',
    }),
  })
  ```

  ```bash cURL theme={null}
  curl -sS -X POST "https://api.olostep.com/v1/monitors" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Y Combinator Launchesで新しいスタートアップが立ち上がったら通知してください",
      "frequency": "20分ごと"
    }'
  ```
</CodeGroup>

モニターが`active`になった後にメールとWebhook配信を追加：

```bash theme={null}
curl -s -X POST "https://api.olostep.com/v1/monitors/monitor_biglavgvq3" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "notification": {
      "channels": [{ "type": "email", "target": "you@example.com" }]
    },
    "webhook": { "url": "https://webhook.site/your-unique-id" }
  }'
```

`channels`が設定され、`events`が省略された場合、APIはデフォルトで`["changed", "first_snapshot"]`に設定されるため、ベースライン実行時と変更が検出されたときに通知されます。

### 競合他社のブログ投稿（AirOps、Profound）

競合他社のブログインデックスを新しい投稿のために監視します。プランナーは`tracked.urls`をブログURL（例：`https://www.airops.com/blog`または`https://www.tryprofound.com/blog`）に解決します。

<CodeGroup>
  ```bash cURL AirOps theme={null}
  curl -sS -X POST "https://api.olostep.com/v1/monitors" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "AirOpsブログで新しいブログ投稿を監視",
      "frequency": "毎時"
    }'
  ```

  ```bash cURL Profound theme={null}
  curl -sS -X POST "https://api.olostep.com/v1/monitors" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "Profoundブログで新しいブログ投稿を監視",
      "frequency": "20分ごと"
    }'
  ```
</CodeGroup>

作成後、このファミリーのモニターは次のようになります：

```json theme={null}
{
  "id": "monitor_588ck513zd",
  "object": "monitor",
  "query": "Profoundブログで新しいブログ投稿を監視",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.tryprofound.com/blog"],
    "web_query": null
  },
  "schedule": {
    "frequency": "20分ごと",
    "cron": "15/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T15:15:00.000Z"
  },
  "status": "active"
}
```

`notification`で`events: ["changed"]`を使用すると、新しい投稿が表示されたときだけアラートを受け取り、最初のベースラインスナップショットではアラートを受け取りません。

### 株価の閾値（テスラ）

ページの差分ではなく、条件が数値である場合に構造化データソースを監視します。プランナーは`tracked.type`を`data_api`に設定し、`tracked.urls`を空にします。

```bash theme={null}
curl -sS -X POST "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "テスラの株価が436ドルを下回ったら通知してください",
    "frequency": "12分ごと"
  }'
```

```json theme={null}
{
  "id": "monitor_7609p3191t",
  "object": "monitor",
  "query": "テスラの株価が436ドルを下回ったら通知してください",
  "tracked": {
    "type": "data_api",
    "urls": [],
    "web_query": null
  },
  "schedule": {
    "frequency": "12分ごと",
    "cron": "2/12 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T15:02:00.000Z"
  },
  "status": "active"
}
```

### OpenAI APIの変更履歴

[OpenAIのAPI変更履歴](https://developers.openai.com/api/docs/changelog)に新しい機能、モデルリリース、または廃止がリストされると通知を受け取ります。`query`で変更履歴URLを言及するか、`source_policy.include_urls`で固定します。

```bash theme={null}
curl -sS -X POST "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "OpenAI APIの変更履歴に新しい更新や機能が追加されたら通知してください https://developers.openai.com/api/docs/changelog",
    "frequency": "毎時",
    "notification": {
      "events": ["changed"],
      "channels": [{ "type": "email", "target": "you@example.com" }]
    }
  }'
```

`events`を`["changed"]`に設定して、変更履歴の内容が変わったときに通知を受け取り、最初のスナップショットが保存されたときだけではありません。

### 複数のモニターを管理

チームのすべてのモニターを一覧表示して、ステータス、スケジュール、および解決されたターゲットを一か所で確認します：

```bash theme={null}
curl -s -X GET "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY"
```

上記の例を実行しているチームは、異なるケイデンスのブログウォッチ、`data_api`価格ウォッチ、メールとWebhookが設定されたYCローンチモニターなど、いくつかのモニターを並べて見ることができ、応答には`"count": 4`（またはそれ以上）が含まれるかもしれません。

## 一般的な検証エラー

モニターエンドポイントは、一般的な無効なリクエストに対して明確な検証エラーを返します：

* `query`が欠落しているか空
* スケジューリング言語ではない`frequency`、10分未満の頻度で解決する、または50文字を超える
* 無効な`source_policy`エントリ（URL配列には有効な`http`/`https`文字列が含まれている必要があります）
* 無効な`notification`形状、未知の`events`、または無効なチャネル`type` / `target`
* 無効な`webhook.url`（`http`または`https`である必要があります）
* 無効な`output_schema`（有効なJSONスキーマである必要があります）
* 無効な`monitor_id`または`run_id`形式
* `status`が`provisioning`の間に更新（`409`）
* ステータスが`active` / `paused`でないときに一時停止/再開

エラーの例：

```json theme={null}
{
  "error": "Could not interpret 'frequency': \"check every second\". Use scheduling language such as \"every hour\" or \"every day at 9am\"."
}
```
