/v1/monitors endpoint you can create persistent monitors that run on a fixed schedule, detect page changes, and notify you through email, Slack, SMS, or a dedicated webhook.
- Create a monitor from a natural language
query - Scope sources with
source_policy - Run checks on natural-language schedules (minimum every 10 minutes, UTC)
- Configure
notification.channelsand optionalwebhookdelivery - Stream provisioning progress with Server-Sent Events (
?stream=1) - List, inspect, update, pause, resume, and delete monitors
- Read snapshot events, planning artifacts, run logs, and live agent logs
query.
Installation
Create a monitor
Create a monitor withPOST /v1/monitors. The API validates your input, reserves a monitor record, provisions a shadow agent, generates a workflow spec, queues DAG planning, and creates a recurring schedule.
queryis required — describe what to watch in natural language.frequencyis optional and defaults toevery hour. Use scheduling phrases such asevery day at 9am(schedules run in UTC; minimum interval is 10 minutes).source_policyoptionally constrainsinclude_urls,exclude_urls,include_domains, andexclude_domains.notificationconfigures when and how to alert (events+channels). Channel delivery is resolved at runtime by the monitor pipeline — you do not pass recipients into the DAG.webhookis a separate object ({ "url": "https://…" }) for HTTP callbacks in addition tonotification.channels.output_schemaoptionally enforces structured extraction (valid JSON Schema).
202 with status: provisioning. The monitor moves to active after planning resolves tracked targets. Poll GET /v1/monitors/:monitor_id or pass ?stream=1 (or Accept: text/event-stream) to follow provisioning phases and spec reasoning tokens over SSE.
Example request
You only needquery and frequency. Notification channels and webhooks can be added later with POST /v1/monitors/:monitor_id.
Response
Successful creation (non-streaming) returns HTTP202 with a monitor object. tracked is empty until planning finishes; poll GET /v1/monitors/:monitor_id until status is active and tracked.urls is populated.
Structured monitor output
Setoutput_schema when you want extraction results to follow a specific JSON structure. The schema must be valid JSON Schema.
Provisioning stream
Add?stream=1 or send Accept: text/event-stream to receive SSE events while the monitor is created:
| Event | Description |
|---|---|
phase | Provisioning step (running, done, or failed) |
reasoning_token | Incremental spec-design text |
reasoning_reset | Truncates buffered reasoning after a failed LLM attempt |
complete | Final monitor object (same shape as the 202 response) |
error | Terminal failure |
Notifications and webhooks
Alerts are configured on the monitor record and resolved at runtime — do not embed channel targets in the monitoringquery.
notification
| Field | Description |
|---|---|
events | Which run outcomes should trigger delivery. See notification events below. If you set channels and omit events, defaults to both changed and first_snapshot. |
channels | List of { "type", "target", "events"? } objects |
Notification events
Useevents to state when you want to be notified. Allowed values:
| Event | Meaning |
|---|---|
changed | Notify when the monitor detects a change compared to the previous snapshot (for example new content, updated price, or a diff the pipeline classifies as changed). |
first_snapshot | Notify when the monitor takes its first snapshot — the initial baseline run that stores current content before later comparisons. |
["changed"] alerts only on updates after the baseline; ["first_snapshot"] confirms setup without waiting for a diff; ["changed", "first_snapshot"] covers both.
Per-channel events on a channel object uses the same values and overrides the top-level list for that channel only.
Supported channel types:
type | target format |
|---|---|
email | Valid email address |
slack | Slack incoming webhook URL |
sms | E.164 phone number (for example +14155552671) |
webhook
Separate from notification.channels, webhook.url receives HTTP POST payloads when the monitor fires your callback URL. You can use both a webhook and channel notifications on the same monitor.
Examples
Email only:Source policy
Usesource_policy to constrain which URLs and domains the planner may use.
Frequencies
Setfrequency in natural language, for example:
every hour(default when omitted)every day at 9amevery weekday at 14:30
- Must read as scheduling language (not an arbitrary monitor question).
- Minimum interval: every 10 minutes.
- Schedules are stored and executed in UTC (
schedule.timezoneisUTC). - Maximum length: 50 characters.
frequency text and exposes it on schedule.cron. When the monitor is active, schedule.next_run_at shows the next run in ISO 8601.
List monitors
Retrieve all monitors for your team withGET /v1/monitors.
By default, deleted monitors are filtered out. Use ?include_deleted=true to include them.
Response shape
Get a monitor
Retrieve a single monitor withGET /v1/monitors/:monitor_id.
The response includes last_run (latest snapshot summary) and total_count (snapshot count) unless you pass include_total_count=false. Add include-diagram=true to include a mermaid_diagram of the monitor DAG.
Response shape
List monitor events
UseGET /v1/monitors/:monitor_id/events to list snapshot events for a monitor.
Pagination:
limit(default25, max100)cursor(opaque token fromnext_cursor)count_only=truereturns only{ "total_count": N }
snapshot_url.
Response shape
Get monitor planning
UseGET /v1/monitors/:monitor_id/planning to inspect the FDA workflow spec and planner DAG after provisioning.
Get a monitor run
UseGET /v1/monitors/:monitor_id/runs/:run_id for snapshot metadata and parsed agent log events for one execution (run_id must start with run_).
Stream agent logs
UseGET /v1/monitors/:monitor_id/agent-logs?stream=1 (or Accept: text/event-stream) to tail CloudWatch logs for the monitor’s agent, filtered to this monitor_id.
Optional query parameter since is a millisecond timestamp (default: 30 minutes ago).
SSE event types: ready, log, heartbeat, error.
Update a monitor
Update a monitor withPOST /v1/monitors/:monitor_id.
Supported fields (include only what you want to change):
metadata— merged with existing keys; empty string values delete keysfrequency— recreates the internal schedule and setsstatusback toactivenotification— replaces the entire notification objectwebhook— passnullto remove
409 while status is provisioning.
When you add notification.channels without events, the API defaults events to ["changed", "first_snapshot"].
Add email notification
Add webhook
Pause a monitor
Pause a monitor withPOST /v1/monitors/:monitor_id/pause.
Pausing disables the underlying schedule and sets status to paused. Only monitors with status: active can be paused. The request body is empty.
200 with the monitor and status: paused. schedule.next_run_at is null while paused.
Resume a monitor
Resume a paused monitor withPOST /v1/monitors/:monitor_id/resume.
Resuming re-enables the schedule and sets status back to active. Only paused monitors can be resumed.
Delete a monitor
Delete a monitor withDELETE /v1/monitors/:monitor_id.
Deletion soft-deletes the monitor row (status: deleted) and removes its schedule and shadow agent resources.
Monitor status
| Status | Meaning |
|---|---|
provisioning | Agent, spec, planner, and schedule are being set up |
active | Schedule enabled; runs execute on schedule.frequency |
paused | Schedule disabled via /pause |
failed | Provisioning or schedule update failed (error_message set) |
deleted | Soft-deleted via DELETE |
Example use cases
Below are common monitor patterns. Each example only needsquery and frequency at creation time; add notification and webhook later if you want alerts on the first run or on changes.
Y Combinator new launches
Watch Y Combinator Launches for newly published startups. After planning,tracked.type is urls and tracked.urls points at the launches page.
active:
channels set and events omitted, the API defaults to ["changed", "first_snapshot"] so you are notified on the baseline run and whenever a change is detected.
Competitor blog posts (AirOps, Profound)
Monitor a competitor blog index for new posts. The planner resolvestracked.urls to the blog URL (for example https://www.airops.com/blog or https://www.tryprofound.com/blog).
events: ["changed"] on notification if you only want alerts when new posts appear, not on the first baseline snapshot.
Stock price threshold (Tesla)
Monitor a structured data source when the condition is numeric rather than a page diff. The planner setstracked.type to data_api and leaves tracked.urls empty.
OpenAI API changelog
Get notified when OpenAI’s API changelog lists new features, model releases, or deprecations. Mention the changelog URL inquery or pin it with source_policy.include_urls.
events to ["changed"] so you are alerted when the changelog content changes, not only when the first snapshot is stored.
Managing multiple monitors
List every monitor for your team to see status, schedules, and resolved targets in one place:data_api price watch, and a YC launches monitor with email and webhook configured—with "count": 4 (or more) in the response.
Common validation errors
The monitor endpoints return clear validation errors for common invalid requests:- Missing or empty
query frequencythat is not scheduling language, resolves too often (under 10 minutes), or exceeds 50 characters- Invalid
source_policyentries (URL arrays must contain validhttp/httpsstrings) - Invalid
notificationshape, unknownevents, or invalid channeltype/target - Invalid
webhook.url(must behttporhttps) - Invalid
output_schema(must be valid JSON Schema) - Invalid
monitor_idorrun_idformat - Update while
statusisprovisioning(409) - Pause/resume when status is not
active/paused