Skip to main content
GET
cURL

Authorizations

x-api-key
string
header
required

API key for authentication. You can find your API key in the Site Spy dashboard under Settings → API.

Path Parameters

uuid
string<uuid>
required

Web page change monitor (watch) unique ID

Query Parameters

recheck
enum<string>

Recheck this web page change monitor (watch)

Available options:
1,
true
paused
enum<string>

Set pause state

Available options:
paused,
unpaused
muted
enum<string>

Set mute state

Available options:
muted,
unmuted

Response

Watch information or operation result

uuid
string<uuid>
read-only

Unique identifier

date_created
integer | null
read-only

Unix timestamp of creation

owner_api_key
string | null
read-only

API key that owns this watch (multi-tenant isolation)

url
string<uri>

URL to monitor for changes

Maximum string length: 5000
title
string | null

Custom title for the web page change monitor (watch), not to be confused with page_title

Maximum string length: 5000
tag
string

Tag UUID to associate with this web page change monitor (watch)

Maximum string length: 5000
tags
string[]

Array of tag UUIDs

paused
boolean

Whether the web page change monitor (watch) is paused

paused_by
enum<string> | null
read-only

Non-null when paused=true was set automatically. Values:

  • plan_limit — owner exceeded their plan's watch cap; auto-deleted 30d after paused_at unless user upgrades or un-pauses.
  • reliability — persistent classified failure; retained until a user or administrator resumes it. Null means the watch was paused manually by the user (no auto-delete).
Available options:
plan_limit,
reliability,
null
paused_at
integer
read-only

Unix timestamp when auto-pause was applied. Starts the auto-delete clock for paused_by != null watches. 0 when never auto-paused.

notification_muted
boolean

Whether notifications are muted

notification_rate_limit_per_hour
integer | null

Per-watch cap on notifications sent per hour. null uses the system default, 0 means unlimited.

Required range: x >= 0
notification_rate_limit_per_day
integer | null

Per-watch cap on notifications sent per day. null uses the system default, 0 means unlimited.

Required range: x >= 0
method
enum<string>

HTTP method to use

Available options:
GET,
POST,
DELETE,
PUT
fetch_backend
string
default:system

Backend to use for fetching content. Common values:

  • system (default) - Use the system-wide default fetcher
  • html_requests - Fast requests-based fetcher
  • html_webdriver - Browser-based fetcher (Playwright/Puppeteer)
  • extra_browser_* - Custom browser configurations (if configured)
  • Plugin-provided fetchers (if installed)
Pattern: ^(system|html_requests|html_hybrid|html_webdriver|extra_browser_.+)$
headers
object

HTTP headers to include in requests

body
string | null

HTTP request body

Maximum string length: 5000
proxy
string | null

Proxy configuration

Maximum string length: 5000
ignore_status_codes
boolean | null

Ignore HTTP status code errors (boolean or null)

webdriver_delay
integer | null

Seconds to wait after page load before extracting content (browser backends only). null uses the system default.

Required range: 0 <= x <= 60
disable_javascript
boolean
default:false

Render the page in the browser with JavaScript execution disabled. Forces a browser backend.

mobile_view
boolean
default:false

Render the page with a mobile viewport, device pixel ratio, touch support and a mobile User-Agent. Forces a browser backend.

noise_reduction_ads
boolean | null

Block ads and cookie banners for this watch; null inherits the account-level setting of the same name

webdriver_js_execute_code
string | null

JavaScript code to execute

Maximum string length: 5000
time_between_check
object

Time intervals between checks. All fields must be non-negative. At least one non-zero value required when not using default settings.

time_between_check_use_default
boolean
default:true

Whether to use global settings for time between checks - defaults to true if not set

notification_urls
string[]

Notification URLs for this web page change monitor (watch). Maximum 100 URLs.

Maximum array length: 100
Maximum string length: 1000
notification_title
string | null

Custom notification title

Maximum string length: 5000
notification_body
string | null

Custom notification body

Maximum string length: 5000
notification_format
enum<string>

Format for notifications

Available options:
text,
html,
htmlcolor,
markdown,
System default
track_ldjson_price_data
boolean | null

Whether to track JSON-LD price data

browser_steps
object[]

Browser automation steps. Maximum 100 steps allowed.

Maximum array length: 100
processor
enum<string>
default:text_json_diff

Optional processor mode to use for change detection. image_ssim_diff (screenshot monitoring) requires Pro plan. Defaults to text_json_diff if not specified.

Available options:
restock_diff,
text_json_diff,
image_ssim_diff
screenshot_enabled
boolean
default:false

When true, capture and store screenshots alongside text snapshots on each check. Requires Pro plan and fetch_backend set to a browser-based fetcher (e.g. html_webdriver).

include_filters
string[]

CSS/XPath selectors naming the part of the page this watch follows, and the only part that can trigger a notification. In the dashboard, the AI chat and the browser extension this is set by pointing at the page in the element picker rather than typed; the API accepts it directly. A watch with an empty list follows the whole page, which means every timestamp, banner and counter on it counts as a change. Selectors that the backend cannot compile are dropped on save rather than rejected.

Maximum array length: 100
Maximum string length: 5000
subtractive_selectors
string[]

CSS/XPath selectors to remove content from the page

Maximum array length: 100
Maximum string length: 5000
ignore_text
string[]

Text patterns to ignore in change detection

Maximum array length: 100
Maximum string length: 5000
auto_ignore_text
string[]
read-only

Reversible noise patterns applied by automatic watch-quality remediation

Maximum array length: 20
Maximum string length: 5000
auto_noise_reduction_enabled
boolean | null

Enable automatic noise reduction for this watch; null inherits the account smart-filter setting

trigger_text
string[]

Text/regex patterns that must be present to trigger a change

Maximum array length: 100
Maximum string length: 5000
text_should_not_be_present
string[]

Text that should NOT be present (triggers alert if found)

Maximum array length: 100
Maximum string length: 5000
alert_on_state_change
boolean | null

Notify on the check where text_should_not_be_present stops matching, and stay silent otherwise, instead of notifying on every page diff while it does not match. Null derives it: a watch with text_should_not_be_present is waiting for that message to clear unless its stated intent is a generic "any change".

extract_text
string[]

Regex patterns to extract specific text after filtering

Maximum array length: 100
Maximum string length: 5000
trim_text_whitespace
boolean
default:false

Strip leading/trailing whitespace from text

sort_text_alphabetically
boolean
default:false

Sort lines alphabetically before comparison

remove_duplicate_lines
boolean
default:false

Remove duplicate lines from content

check_unique_lines
boolean
default:false

Compare against all history for unique lines

strip_ignored_lines
boolean | null

Remove lines matching ignore patterns

filter_text_added
boolean
default:true

Include added text in change detection

filter_text_removed
boolean
default:true

Include removed text in change detection

filter_text_replaced
boolean
default:true

Include replaced text in change detection

in_stock_only
boolean
default:true

Only trigger on in-stock transitions (restock_diff processor)

follow_price_changes
boolean
default:true

Monitor and track price changes (restock_diff processor)

price_change_threshold_percent
number | null

Minimum price change percentage to trigger notification

has_ldjson_price_data
boolean | null
read-only

Whether page has LD-JSON price data (auto-detected)

notification_screenshot
boolean
default:false

Include screenshot in notifications (if supported by notification URL)

filter_failure_notification_send
boolean
default:true

Send notification when filters fail to match content

use_page_title_in_list
boolean | null

Display page title in watch list (null = use system default)

history_snapshot_max_length
integer | null

Maximum number of history snapshots to keep (null = use system default)

Required range: 1 <= x <= 1000
time_schedule_limit
object

Weekly schedule limiting when checks can run

conditions
object[]

Array of condition rules for change detection logic (empty array when not set)

Maximum array length: 100
conditions_match_logic
enum<string>
default:ALL

Logic operator - ALL (match all conditions) or ANY (match any condition)

Available options:
ALL,
ANY
ai_alert_condition
string | null

Plain-English condition for AI smart alerts (Pro+ only). When set, AI evaluates each change against this condition and suppresses notifications that don't match. Example - "Only notify me if the price drops below $50".

Maximum string length: 500
last_ai_summary
string | null
read-only

AI-generated plain-English summary of the most recent change (Pro+ only, read-only — generated automatically when a change is detected).

last_ai_summary_from
integer
read-only

The older of the two snapshot timestamps last_ai_summary was written from. The summary describes one change, so a client rendering it beside a diff must check that this pair is the pair being shown — otherwise it captions one change with another change's summary. 0 means the pair was not recorded (a summary written before this field existed), in which case the summary is only trustworthy against the watch's newest pair.

Required range: x >= 0
last_ai_summary_to
integer
read-only

The newer of the two snapshot timestamps last_ai_summary was written from. 0 when not recorded.

Required range: x >= 0
last_filter_degraded_alert_ts
integer
read-only

When the owner was last told this watch's filters had degraded.

Required range: x >= 0
state_blocked
boolean | null
read-only

The state gate's verdict at the previous check; null before the first one.

state_last_transition_at
integer
read-only

When the state gate last changed its verdict.

Required range: x >= 0
state_waiting_alert_ts
integer
read-only

When the owner was last sent a "still waiting" note.

Required range: x >= 0
track_what
string | null

User's monitoring intent, e.g. "price changes", "new job listings". Set by the add-watch form or AI chat when the user describes what they want to track.

Maximum string length: 500
ai_tuning_started_at
integer
default:0

Unix timestamp set while an automatic filter repair is running for this watch, and zero when it is not. Lets the dashboard show the work as watch state that survives a page refresh.

filters_source
enum<string>
default:manual

Who chose this watch's include filter - 'manual' for a person, 'smart' for the removed smart-configure generator. It decides what happens when the include filter stops matching: a person's selector raises an error, a machine's silently falls back to the whole page. Nothing writes 'smart' any more, and watches configured before it was removed still carry the value with their filters honoured unchanged - but an edit that changes include_filters now records 'manual', since whoever made that edit chose the selector. Send the field explicitly to override that.

Available options:
manual,
smart
last_checked
integer
read-only

Unix timestamp of last check

last_changed
integer
read-only

Unix timestamp of last change

last_error
read-only

Last error message (false when no error, string when error occurred, null if not checked yet)

failure_category
enum<string> | null
read-only

Stable category for the active monitoring failure.

Available options:
internal_error,
network_error,
target_unavailable,
blocked_or_challenged,
rate_limited,
authentication_required,
not_found,
empty_content,
filter_broken,
browser_failure,
self_reference,
notification_failure,
null
failure_code
string | null
read-only

Stable machine-readable code for the active failure.

consecutive_failures
integer
read-only

Consecutive failures in the active category.

Required range: x >= 0
failure_started_at
integer
read-only

Unix timestamp when the active failure lifecycle started.

Required range: x >= 0
last_failure_at
integer
read-only

Unix timestamp of the most recent failed check.

Required range: x >= 0
next_retry_at
integer
read-only

Unix timestamp for the next scheduled recovery attempt; 0 when none is scheduled.

Required range: x >= 0
recovery_stage
integer
read-only

Current category-aware retry/backoff stage.

Required range: x >= 0
last_viewed
integer

Unix timestamp in seconds of the last time the watch was viewed. Setting it to a value higher than last_changed in the "Update watch" endpoint marks the watch as viewed.

Required range: x >= 0

The watch URL rendered in case of any Jinja2 markup, always use this for listing.

label
string
read-only

What to call this watch on screen: the stored title, or the page's own when the stored title is only the watch's own address, or the URL. Resolved server-side so every surface that names a watch — the dashboard row, the email subject, the web push body, the RSS item — agrees. Use title instead when you need the raw stored value, for example to pre-fill a rename field.

page_title
string | null
read-only

HTML tag extracted from the page

check_count
integer
read-only

Total number of checks performed

filter_count
integer
read-only

Number of filters configured on this watch (include filters, subtractive selectors and ignore text combined). Distinguishes a watch the user deliberately filtered from an untouched one, since filters_source defaults to 'manual' either way.

fetch_time
number
read-only

Duration of last fetch in seconds

previous_md5
read-only

MD5 hash of previous content (false if not set)

previous_md5_before_filters
read-only

MD5 hash before filters applied (false if not set)

consecutive_filter_failures
integer
read-only

Counter for consecutive filter match failures

tune_count_today
integer
read-only

User-initiated filter tunes charged to this watch inside the current 24-hour window. Automatic repairs are not counted.

tune_limit
integer
read-only

How many user-initiated filter tunes this watch's owner may spend on it per day, from their plan. Zero or less means unlimited.

last_notification_error
string | null
read-only

Last notification error message

notification_alert_count
integer
read-only

Number of notifications sent

notifications_per_day
number
read-only

Notifications queued per day this watch actually ran, over the last 30 days. The denominator is days observed, never the check count — the check interval comes from the owner's plan, so the same daily volume would otherwise score sixty times lower on a one-minute watch than on an hourly one.

noisy_notifications_per_day
number
read-only

The daily-volume mark above which this watch counts as loud, resolved for its owner's plan. Compare notifications_per_day against this rather than against a locally held constant: it is the same mark the server's own noise-healing gate reads, and it moves with the deployment's configuration.

last_notification_delivery_reason
string | null
read-only

Why the most recent delivery attempt succeeded or failed. Populated on every change-detected event so the dashboard can explain a silent watch to the user. Possible values include delivered_via_user_email, delivered_via_telegram, delivered_via_user_webhook, delivered_via_webpush, delivered_via_watch_url, delivered_via_tag_url, delivered_via_global_url, email_unverified, email_notifications_muted, smtp_not_configured, no_owner_api_key, no_urls_configured, rate_limited, web_push_send_failed, held_search_term_never_seen, held_rotating_selector.

last_notification_delivery_ts
integer
read-only

Unix timestamp of the most recent delivery attempt (success or silent drop)

change_detected_but_not_delivered_count
integer
read-only

Incremented every time a change was detected but no notification was queued. A non-zero value combined with notification_alert_count=0 means the detection engine is working but delivery is blocked — check last_notification_delivery_reason.

content-type
string | null
read-only

Content-Type from last fetch

remote_server_reply
string | null
read-only

Server header from last response

browser_steps_last_error_step
integer | null
read-only

Last browser step that caused an error

viewed
read-only

Computed property - true if watch has been viewed, false otherwise (deprecated, use last_viewed instead)

history_n
integer
read-only

Number of history snapshots available

community_published
boolean
read-only

Whether this watch is published to the community library.

community_slug
string | null
read-only

URL slug of the published community entry.

community_published_at
integer | null
read-only

Unix timestamp the watch was published.

community_clone_count
integer
read-only

Historical count, frozen. One-click cloning of a community entry was removed; the field is still returned for entries that were cloned while it existed and can no longer increase.

Required range: x >= 0
community_cloned_by
string[]
read-only

Historical list, frozen. API keys that cloned the entry while one-click cloning existed. No new entries are added.

community_category
string | null
read-only

Category chosen when publishing.

community_author_name
string | null
read-only

Display name shown on the published entry.

consecutive_check_failures
integer
read-only

Failed checks in a row, used for owner health alerts.

Required range: x >= 0
last_broken_alert_ts
integer
read-only

Unix timestamp of the last generic broken-watch alert.

Required range: x >= 0
last_health_alert_category
string | null
read-only

failure_category last emailed to the owner this episode.

last_health_alert_ts
integer
read-only

Unix timestamp of that category-specific health alert.

Required range: x >= 0
paused_alert_ts
integer
read-only

Unix timestamp the owner was told about an auto-pause; 0 when not yet told.

Required range: x >= 0
last_fetch_backend_used
string
read-only

Fetcher that actually ran, e.g. html_webdriver or html_requests.

last_fetch_content_length
integer
read-only

Size in bytes of the last raw HTML body; 0 before the first check.

Required range: x >= 0
last_fetch_suspicious
object | null
read-only

Set when the last fetch looked like a block or challenge page.

filter_signature
string
read-only

Hash of the filter config that produced the newest stored snapshot.

last_filter_empty_at
integer
read-only

Unix timestamp when include_filters last returned nothing; 0 when healthy.

Required range: x >= 0
last_filter_output_length
integer
read-only

Size in characters of the latest filter output.

Required range: x >= 0
last_filter_selector_matches
object
read-only

Match count per configured selector from the last check.

last_filter_degraded
string | null
read-only

Code for how the filter degraded, e.g. include_no_match; null when healthy.

last_filter_degraded_at
integer
read-only

Unix timestamp the filter was first seen degraded.

Required range: x >= 0
consecutive_filter_degraded
integer
read-only

Consecutive checks where the filter was degraded.

Required range: x >= 0
filter_heal_in_flight_since
integer
read-only

Unix timestamp an automatic filter repair started; 0 when none is running.

Required range: x >= 0
last_watch_quality_intervention_id
string | null
read-only

Identifier of the most recent quality intervention on this watch.

tune_count
integer
read-only

AI filter tunes used inside the current day window.

Required range: x >= 0
tune_day_start
integer
read-only

Unix timestamp the current tune-quota day started.

Required range: x >= 0
tune_source
string | null
read-only

Who requested the last tune - user or system.

last_ai_summary_error
string
read-only

Last error from AI summary generation.

notification_window_start
integer
read-only

Start of the current hourly notification budget.

Required range: x >= 0
notification_window_count
integer
read-only

Notifications already sent inside the current hour.

Required range: x >= 0
notification_day_start
integer
read-only

Start of the current daily notification budget.

Required range: x >= 0
notification_day_count
integer
read-only

Notifications already sent inside the current day.

Required range: x >= 0
notifications_suppressed_count
integer
read-only

Changes held back by the budget, reported by the next send.

Required range: x >= 0
notifications_suppressed_since
integer
read-only

Unix timestamp suppression started; 0 when nothing is held back.

Required range: x >= 0
notification_failure_count
integer
read-only

Consecutive notification delivery failures.

Required range: x >= 0
notification_next_retry_at
integer
read-only

Unix timestamp of the next notification retry; 0 when none is scheduled.

Required range: x >= 0
notification_recovery_stage
integer
read-only

Current notification retry/backoff stage.

Required range: x >= 0
checking_now
boolean
read-only

Whether a worker is fetching this watch right now.

queued
boolean
read-only

Whether this watch is waiting in the recheck queue.

health
object
read-only

User-facing health summary derived from the persisted failure lifecycle. Messages are safe to display and do not include stack traces or URL secrets.