List monitors
curl --request GET \
--url https://api.prefetch.io/monitor \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.prefetch.io/monitor"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.prefetch.io/monitor', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prefetch.io/monitor",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.prefetch.io/monitor"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.prefetch.io/monitor")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prefetch.io/monitor")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"monitors": [
{
"id": "mon_3f9a1c2b7d4e4f6a8b0c1d2e3f4a5b6c",
"name": "Competitor pricing",
"status": "active",
"schedule": {
"cron": "0 9 * * 1-5",
"timezone": "Europe/Athens",
"text": "every weekday at 9am"
},
"next_run_at": "2026-10-13T06:00:00.000Z",
"last_run_at": "2026-10-12T06:00:04.112Z",
"current_check_id": null,
"goal": "Alert me when a plan price or its included features change",
"judge_enabled": true,
"targets": [
{
"id": "tgt_8d1e0f2a3b4c5d6e",
"type": "scrape",
"urls": [
"https://example.com/pricing"
],
"scrape_options": {
"only_main_content": true,
"include_links": true,
"include_images": false,
"include_selectors": [],
"exclude_selectors": []
},
"change_tracking": {
"modes": [
"json"
],
"json_prompt": "Each plan: name, monthly price, headline features"
}
},
{
"id": "tgt_1a2b3c4d5e6f7a8b",
"type": "crawl",
"url": "https://example.com/changelog",
"crawl_options": {
"limit": 25,
"max_depth": 2,
"include_paths": [
"^/changelog/"
],
"exclude_paths": [],
"allow_subdomains": false,
"ignore_query_params": true,
"respect_robots_txt": true,
"use_sitemap": true,
"delay_ms": 0,
"concurrency": 2
},
"scrape_options": {
"only_main_content": true,
"include_links": true,
"include_images": false,
"include_selectors": [],
"exclude_selectors": []
},
"change_tracking": {
"modes": [
"markdown"
]
}
}
],
"webhook": {
"url": "https://you.example.org/hooks/prefetch",
"headers": {},
"metadata": {
"env": "production"
},
"events": [
"monitor.page",
"monitor.check.completed"
],
"secret": "whsec_4f1c9e2a7b3d8e6f0a5c1b9d2e7f3a8c4b6d0e1f9a2c5b7d"
},
"retention_days": 30,
"estimated_credits_per_check": 55,
"estimated_credits_per_month": 1155,
"last_check_summary": {
"check_id": "chk_8e2d4f6a1b3c4d5e6f7a8b9c0d1e2f3a",
"status": "completed",
"finished_at": "2026-10-12T06:01:27.930Z",
"total_pages": 19,
"same": 16,
"new": 1,
"changed": 1,
"removed": 1,
"error": 0
},
"created_at": "2026-10-09T10:00:00.000Z",
"updated_at": "2026-10-09T10:00:00.000Z"
}
],
"total": 1,
"next": null
},
"meta": {
"requestId": "c9a2e3f4-5b6c-4d7e-9f80-1a2b3c4d5e6f",
"durationMs": 47
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}Monitoring
GET /monitor
List the monitors your API key owns, newest first. Free.
GET
/
monitor
List monitors
curl --request GET \
--url https://api.prefetch.io/monitor \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.prefetch.io/monitor"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.prefetch.io/monitor', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.prefetch.io/monitor",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.prefetch.io/monitor"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.prefetch.io/monitor")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.prefetch.io/monitor")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"monitors": [
{
"id": "mon_3f9a1c2b7d4e4f6a8b0c1d2e3f4a5b6c",
"name": "Competitor pricing",
"status": "active",
"schedule": {
"cron": "0 9 * * 1-5",
"timezone": "Europe/Athens",
"text": "every weekday at 9am"
},
"next_run_at": "2026-10-13T06:00:00.000Z",
"last_run_at": "2026-10-12T06:00:04.112Z",
"current_check_id": null,
"goal": "Alert me when a plan price or its included features change",
"judge_enabled": true,
"targets": [
{
"id": "tgt_8d1e0f2a3b4c5d6e",
"type": "scrape",
"urls": [
"https://example.com/pricing"
],
"scrape_options": {
"only_main_content": true,
"include_links": true,
"include_images": false,
"include_selectors": [],
"exclude_selectors": []
},
"change_tracking": {
"modes": [
"json"
],
"json_prompt": "Each plan: name, monthly price, headline features"
}
},
{
"id": "tgt_1a2b3c4d5e6f7a8b",
"type": "crawl",
"url": "https://example.com/changelog",
"crawl_options": {
"limit": 25,
"max_depth": 2,
"include_paths": [
"^/changelog/"
],
"exclude_paths": [],
"allow_subdomains": false,
"ignore_query_params": true,
"respect_robots_txt": true,
"use_sitemap": true,
"delay_ms": 0,
"concurrency": 2
},
"scrape_options": {
"only_main_content": true,
"include_links": true,
"include_images": false,
"include_selectors": [],
"exclude_selectors": []
},
"change_tracking": {
"modes": [
"markdown"
]
}
}
],
"webhook": {
"url": "https://you.example.org/hooks/prefetch",
"headers": {},
"metadata": {
"env": "production"
},
"events": [
"monitor.page",
"monitor.check.completed"
],
"secret": "whsec_4f1c9e2a7b3d8e6f0a5c1b9d2e7f3a8c4b6d0e1f9a2c5b7d"
},
"retention_days": 30,
"estimated_credits_per_check": 55,
"estimated_credits_per_month": 1155,
"last_check_summary": {
"check_id": "chk_8e2d4f6a1b3c4d5e6f7a8b9c0d1e2f3a",
"status": "completed",
"finished_at": "2026-10-12T06:01:27.930Z",
"total_pages": 19,
"same": 16,
"new": 1,
"changed": 1,
"removed": 1,
"error": 0
},
"created_at": "2026-10-09T10:00:00.000Z",
"updated_at": "2026-10-09T10:00:00.000Z"
}
],
"total": 1,
"next": null
},
"meta": {
"requestId": "c9a2e3f4-5b6c-4d7e-9f80-1a2b3c4d5e6f",
"durationMs": 47
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}{
"error": "Credit limit exceeded",
"error_code": "CREDITS_EXHAUSTED",
"retryable": false,
"success": false,
"retryAfterSeconds": 123,
"limit": 123,
"meta": {
"requestId": "a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d",
"durationMs": 1842
}
}Overview
Returns your monitors with their settings, next run, credit estimate and the summary of each one’s last check. Results are paginated: follownext until it is null.
An API key sees only the monitors it created.
Example request
curl "https://api.prefetch.io/monitor?limit=25" \
-H "X-API-Key: $PREFETCH_API_KEY"
const res = await fetch("https://api.prefetch.io/monitor", {
headers: { "X-API-Key": process.env.PREFETCH_API_KEY },
});
const { data } = await res.json();
for (const m of data.monitors) {
const last = m.last_check_summary;
console.log(m.name, m.status, last ? `${last.changed} changed` : "no check yet");
}
import os, requests
data = requests.get(
"https://api.prefetch.io/monitor",
headers={"X-API-Key": os.environ["PREFETCH_API_KEY"]},
).json()["data"]
for m in data["monitors"]:
print(m["name"], m["status"], m["next_run_at"])
Example response
{
"success": true,
"data": {
"monitors": [
{
"id": "mon_3f9a1c2b7d4e4f6a8b0c1d2e3f4a5b6c",
"name": "Competitor pricing",
"status": "active",
"schedule": { "cron": "0 9 * * 1-5", "timezone": "Europe/Athens", "text": "every weekday at 9am" },
"next_run_at": "2026-10-13T06:00:00.000Z",
"last_run_at": "2026-10-12T06:00:04.112Z",
"last_check_summary": {
"check_id": "chk_8e2d4f6a1b3c4d5e6f7a8b9c0d1e2f3a",
"status": "completed",
"finished_at": "2026-10-12T06:01:27.930Z",
"total_pages": 19, "same": 16, "new": 1, "changed": 1, "removed": 1, "error": 0
},
"...": "the rest of the monitor, as in GET /monitor/{id}"
}
],
"total": 1,
"next": null
},
"meta": {
"requestId": "c9a2e3f4-5b6c-4d7e-9f80-1a2b3c4d5e6f",
"durationMs": 47
}
}
Related
GET /monitor/{id}
One monitor in full.
POST /monitor
Create a monitor.
Authorizations
Your Prefetch API key. Obtain one from the dashboard.
Query Parameters
Items to return per request.
Required range:
1 <= x <= 100Items to skip. Use the next link rather than building this by hand.
Required range:
x >= 0