const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Acme pricing monitor',
status: 'active',
schedule: {type: 'interval', frequency: 1, unit: 'hours'},
webhook: {url: 'https://example.com/webhook'}
})
};
fetch('https://api.context.dev/v1/monitors/{monitor_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.context.dev/v1/monitors/{monitor_id}"
payload = {
"name": "Acme pricing monitor",
"status": "active",
"schedule": {
"type": "interval",
"frequency": 1,
"unit": "hours"
},
"webhook": { "url": "https://example.com/webhook" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)require 'uri'
require 'net/http'
url = URI("https://api.context.dev/v1/monitors/{monitor_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Acme pricing monitor\",\n \"status\": \"active\",\n \"schedule\": {\n \"type\": \"interval\",\n \"frequency\": 1,\n \"unit\": \"hours\"\n },\n \"webhook\": {\n \"url\": \"https://example.com/webhook\"\n }\n}"
response = http.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.context.dev/v1/monitors/{monitor_id}"
payload := strings.NewReader("{\n \"name\": \"Acme pricing monitor\",\n \"status\": \"active\",\n \"schedule\": {\n \"type\": \"interval\",\n \"frequency\": 1,\n \"unit\": \"hours\"\n },\n \"webhook\": {\n \"url\": \"https://example.com/webhook\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.context.dev/v1/monitors/{monitor_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Acme pricing monitor',
'status' => 'active',
'schedule' => [
'type' => 'interval',
'frequency' => 1,
'unit' => 'hours'
],
'webhook' => [
'url' => 'https://example.com/webhook'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}curl --request PATCH \
--url https://api.context.dev/v1/monitors/{monitor_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme pricing monitor",
"status": "active",
"schedule": {
"type": "interval",
"frequency": 1,
"unit": "hours"
},
"webhook": {
"url": "https://example.com/webhook"
}
}
'{
"mode": "web",
"id": "mon_123",
"name": "Acme pricing monitor",
"target": {
"type": "page",
"url": "https://acme.com/pricing",
"instructions": "Report pricing or plan availability changes. Ignore counters, timestamps, testimonials, and navigation.",
"normalize_whitespace": true,
"include_selectors": [
"#attraction-details"
],
"exclude_selectors": [
".carousel",
"[id^=\"TA_\"]"
],
"actions": [
{
"do": "wait",
"timeMs": 15000
}
]
},
"change_detection": {
"type": "exact"
},
"status": "active",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"schedule": {
"type": "interval",
"frequency": 6,
"unit": "hours"
},
"webhook": {
"url": "https://example.com/webhook",
"events": [
"change.detected",
"run.completed"
],
"retry": {
"delays_seconds": [
10,
60,
300,
1800,
7200,
21600,
57600
]
},
"secret": "whsec_8f3a…"
},
"last_run_at": "2023-11-07T05:31:56Z",
"last_change_at": "2023-11-07T05:31:56Z",
"next_run_at": "2023-11-07T05:31:56Z",
"last_error": {
"code": "fetch_failed",
"message": "The target URL could not be fetched."
},
"webhook_failure": {
"consecutive_failures": 3,
"last_status": "rejected",
"last_message": "Webhook endpoint returned HTTP 429.",
"last_failed_at": "2023-11-07T05:31:56Z"
},
"tags": [
"pricing",
"competitor"
],
"baseline": {
"text": "Acme Pricing\nStarter $9/mo…",
"captured_at": "2023-11-07T05:31:56Z"
},
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"message": "<string>",
"error_code": "RATE_LIMITED",
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}Update a monitor
Update a monitor. Changing its target or change detection replaces the baseline and queues a new baseline run.
const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Acme pricing monitor',
status: 'active',
schedule: {type: 'interval', frequency: 1, unit: 'hours'},
webhook: {url: 'https://example.com/webhook'}
})
};
fetch('https://api.context.dev/v1/monitors/{monitor_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.context.dev/v1/monitors/{monitor_id}"
payload = {
"name": "Acme pricing monitor",
"status": "active",
"schedule": {
"type": "interval",
"frequency": 1,
"unit": "hours"
},
"webhook": { "url": "https://example.com/webhook" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)require 'uri'
require 'net/http'
url = URI("https://api.context.dev/v1/monitors/{monitor_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Acme pricing monitor\",\n \"status\": \"active\",\n \"schedule\": {\n \"type\": \"interval\",\n \"frequency\": 1,\n \"unit\": \"hours\"\n },\n \"webhook\": {\n \"url\": \"https://example.com/webhook\"\n }\n}"
response = http.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.context.dev/v1/monitors/{monitor_id}"
payload := strings.NewReader("{\n \"name\": \"Acme pricing monitor\",\n \"status\": \"active\",\n \"schedule\": {\n \"type\": \"interval\",\n \"frequency\": 1,\n \"unit\": \"hours\"\n },\n \"webhook\": {\n \"url\": \"https://example.com/webhook\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.context.dev/v1/monitors/{monitor_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Acme pricing monitor',
'status' => 'active',
'schedule' => [
'type' => 'interval',
'frequency' => 1,
'unit' => 'hours'
],
'webhook' => [
'url' => 'https://example.com/webhook'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}curl --request PATCH \
--url https://api.context.dev/v1/monitors/{monitor_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme pricing monitor",
"status": "active",
"schedule": {
"type": "interval",
"frequency": 1,
"unit": "hours"
},
"webhook": {
"url": "https://example.com/webhook"
}
}
'{
"mode": "web",
"id": "mon_123",
"name": "Acme pricing monitor",
"target": {
"type": "page",
"url": "https://acme.com/pricing",
"instructions": "Report pricing or plan availability changes. Ignore counters, timestamps, testimonials, and navigation.",
"normalize_whitespace": true,
"include_selectors": [
"#attraction-details"
],
"exclude_selectors": [
".carousel",
"[id^=\"TA_\"]"
],
"actions": [
{
"do": "wait",
"timeMs": 15000
}
]
},
"change_detection": {
"type": "exact"
},
"status": "active",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"schedule": {
"type": "interval",
"frequency": 6,
"unit": "hours"
},
"webhook": {
"url": "https://example.com/webhook",
"events": [
"change.detected",
"run.completed"
],
"retry": {
"delays_seconds": [
10,
60,
300,
1800,
7200,
21600,
57600
]
},
"secret": "whsec_8f3a…"
},
"last_run_at": "2023-11-07T05:31:56Z",
"last_change_at": "2023-11-07T05:31:56Z",
"next_run_at": "2023-11-07T05:31:56Z",
"last_error": {
"code": "fetch_failed",
"message": "The target URL could not be fetched."
},
"webhook_failure": {
"consecutive_failures": 3,
"last_status": "rejected",
"last_message": "Webhook endpoint returned HTTP 429.",
"last_failed_at": "2023-11-07T05:31:56Z"
},
"tags": [
"pricing",
"competitor"
],
"baseline": {
"text": "Acme Pricing\nStarter $9/mo…",
"captured_at": "2023-11-07T05:31:56Z"
},
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"message": "<string>",
"error_code": "INTERNAL_ERROR",
"required_permission": "logs:read",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}{
"message": "<string>",
"error_code": "RATE_LIMITED",
"request_id": "3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91",
"key_metadata": {
"credits_consumed": 123,
"credits_remaining": 123
}
}monitors:write permission. See the guide for examples and usage.Authorizations
Send Authorization: Bearer <API_KEY>. Keys have full access unless restricted to scopes.
Path Parameters
ID of the monitor.
"mon_123"
Body
Send only the fields to change. target replaces the whole target.
Display name for the monitor.
1 - 200"Acme pricing monitor"
Labels for filtering monitors, their changes, and their usage.
201 - 50["pricing", "competitor"]
Set paused to stop scheduled runs or active to resume them.
active, paused What to watch: a page, a sitemap, or data extracted from a site.
- Page target
- Sitemap target
- Extract target
Show child attributes
Show child attributes
How changes are judged. Defaults to semantic for extract targets and page targets with instructions, otherwise exact.
- Exact
- Semantic
Show child attributes
Show child attributes
How often the monitor runs. Defaults to once a day.
Show child attributes
Show child attributes
Set to null to remove the webhook. Changing url issues a new secret.
Show child attributes
Show child attributes
Response
Updated monitor
Always web. Optional.
web "mon_123"
"Acme pricing monitor"
What to watch: a page, a sitemap, or data extracted from a site.
- Page target
- Sitemap target
- Extract target
Show child attributes
Show child attributes
How changes are judged. Defaults to semantic for extract targets and page targets with instructions, otherwise exact.
- Exact
- Semantic
Show child attributes
Show child attributes
Current state. Failed monitors keep running; paused monitors must be resumed with status: "active".
active, paused, failed Unique ID of this request, also in X-Request-Id. Include it when contacting support.
"3f1c2a6e-8b4d-4c1e-9f0a-2d7b5e6c8a91"
How often the monitor runs. Defaults to once a day.
Show child attributes
Show child attributes
Webhook destination and delivery settings. Null means no webhook is configured.
Show child attributes
Show child attributes
When the next scheduled run is due; null while paused.
Error from the most recent failed run; null when the last run succeeded.
Show child attributes
Show child attributes
Present while webhook deliveries are failing consecutively; null when deliveries are healthy or no webhook is configured. Cleared on the next successful delivery and when the webhook URL changes.
Show child attributes
Show child attributes
Labels for filtering monitors, their changes, and their usage.
201 - 50["pricing", "competitor"]
Comparison baseline, included on Retrieve. Null until capture completes or after target changes.
- Page baseline
- Sitemap baseline
- Extract baseline
Show child attributes
Show child attributes
Credits this request used and your remaining balance.
Show child attributes
Show child attributes
Was this page helpful?