POST Create Monitor
Create a scheduled website-change monitor
https://api.anakin.io/v1/monitorsCreate a monitor that checks a URL every intervalMinutes and records a change whenever the page differs from the previous check.
A monitor has a scope: page (default) watches a single URL, while site crawls the whole site each run and reports pages added, removed, and changed. See Site monitors for the site-only config, endpoints, and change shape.
Request Body
{
"url": "https://example.com/product/123",
"watchMode": "specific_data",
"outputSchema": {
"type": "object",
"properties": { "price": { "type": "number" }, "inStock": { "type": "boolean" } },
"required": ["price"]
},
"intervalMinutes": 60,
"aiMode": true,
"aiGoal": "only when the price drops or it goes out of stock",
"country": "us",
"alertWebhookUrl": "https://your-app.com/hooks/anakin",
"alertEmails": "you@example.com"
}Only url and intervalMinutes are required. Every other field is optional — the defaults below are used when you omit it.
| Parameter | Type | Description |
|---|---|---|
url required | string | Page (or, for site scope, the root URL) to monitor. Must start with http:// or https://. |
intervalMinutes required | number | How often to check, in minutes. Minimum 15. |
scope optional | string | page (default) — watch this one URL. site — crawl the whole site each run and diff the page set. |
maxPages site only | number | Max pages to crawl per run. Capped at 50. Bills 1 credit per page crawled. |
maxDepth site only | number | Link hops to follow from the root (1–5). Default 2. |
includePatterns site only | string[] | Only crawl URLs matching these globs/URLs. Exact URLs here are how the dashboard's hand-picked page set is stored. |
excludePatterns site only | string[] | Skip URLs matching these globs. |
watchMode optional | string | full_page (default) or specific_data. Site monitors always use full_page. |
watchFormat optional | string | full_page only — what to diff: markdown (default), html, or cleaned_html. Ignored for specific_data. |
outputSchema required for specific_data | object | JSON Schema of the fields to track (AI-extracted). Only used — and required — in specific_data mode; ignored for full_page. |
aiMode optional | boolean | Filter trivial noise and summarize meaningful changes. Adds +1 credit/check. Requires an LLM-enabled server. Default false. |
aiGoal optional | string | Optional even when aiMode is on. A natural-language hint that narrows what counts as meaningful (e.g. "only when the price drops or it goes out of stock"). Omit it and the AI flags any meaningful change on its own. |
useBrowser optional | boolean | Render with a headless browser (needed for JS-heavy pages). Default false. Forced true when sessionId is set. |
country optional | string | Proxy country code. Default "us". See Supported Countries. |
sessionId optional | string | Saved browser session for monitoring logged-in pages. |
isActive optional | boolean | Start active or paused. Default true. |
alertWebhookUrl optional | string | Webhook to POST each detected change to (HMAC-signed). See Alerts. |
alertEmails optional | string | Comma-separated email recipients. Requires email alerts to be enabled on the server. |
Response
201 CreatedReturns the full Monitor object. When you set alertWebhookUrl, the response includes a freshly generated alertWebhookSecret — store it now, it's what you use to verify webhook signatures.
{
"id": "b1e7c2a4-…",
"url": "https://example.com/product/123",
"watchMode": "specific_data",
"intervalMinutes": 60,
"isActive": true,
"aiMode": true,
"creditCostPerRun": 4,
"nextRunAt": "2026-01-01T12:00:00Z",
"alertWebhookUrl": "https://your-app.com/hooks/anakin",
"alertWebhookSecret": "whsec_9f2c…",
"createdAt": "2026-01-01T11:00:00Z",
"updatedAt": "2026-01-01T11:00:00Z"
}The first check runs on the next scheduler tick (usually within a minute). Poll GET /v1/monitors/{id} for lastCheckedAt, or list changes.
Errors
| Status | error | When |
|---|---|---|
400 | invalid_request | Missing/invalid url, intervalMinutes < 15, bad watchMode/watchFormat, missing outputSchema for specific_data, or malformed emails. |
402 | monitor_limit_reached | You're at your plan's active-monitor cap (Free 5 / Pro 20 / Scale 100). |
Code Examples
curl -X POST https://api.anakin.io/v1/monitors \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product/123",
"watchMode": "specific_data",
"outputSchema": { "type": "object", "properties": { "price": { "type": "number" } }, "required": ["price"] },
"intervalMinutes": 60,
"alertWebhookUrl": "https://your-app.com/hooks/anakin"
}'import requests
res = requests.post(
"https://api.anakin.io/v1/monitors",
headers={"X-API-Key": "your_api_key"},
json={
"url": "https://example.com/product/123",
"watchMode": "specific_data",
"outputSchema": {
"type": "object",
"properties": {"price": {"type": "number"}},
"required": ["price"],
},
"intervalMinutes": 60,
"alertWebhookUrl": "https://your-app.com/hooks/anakin",
},
)
monitor = res.json()
print("Created", monitor["id"], "— save secret:", monitor.get("alertWebhookSecret"))const res = await fetch("https://api.anakin.io/v1/monitors", {
method: "POST",
headers: { "X-API-Key": "your_api_key", "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://example.com/product/123",
watchMode: "specific_data",
outputSchema: { type: "object", properties: { price: { type: "number" } }, required: ["price"] },
intervalMinutes: 60,
alertWebhookUrl: "https://your-app.com/hooks/anakin",
}),
});
const monitor = await res.json();
console.log("Created", monitor.id, "— save secret:", monitor.alertWebhookSecret);