MENU navbar-image

Introduction

This documentation aims to provide you with all the information you need to integrate WebChange Detector into your workflow.

Our Quick Start Guide gives you a quick overview to help you with the integration.

If you need help with the integration or miss something here, don't hesitate to contact us at: support@webchangedetector.com. We are happy to help.

Quick Start Guide

WebChange Detector captures screenshots of your URLs and compares them across time to detect visual changes. This guide walks you through the basic setup, manual pre/post-update checks, and continuous monitoring — all using default settings. For more detailed customisations, refer to the per-endpoint docs below.

Core Concepts

Initial Setup

Get API Token

Create a free trial account at webchangedetector.com. After account activation, get the API token from the dashboard at API & WP Websites. Send it as a Bearer token (see Authentication above).

Create Group

POST /api/v2/groups

Create the container that will hold your URLs and their shared settings (schedule, threshold, CSS injection, basic auth, etc.). The response contains the Group id you'll need for the next steps.

Create URLs

POST /api/v2/urls

Register the URLs you want to monitor. URLs exist independently of Groups — the same URL can be referenced from multiple Groups.

Add URLs to Group

POST /api/v2/groups/{uuid}/add-urls

Assign your URLs to the Group. By default, checks for both desktop and mobile are enabled per URL.

POST /api/v2/webhooks

Webhooks notify your application when checks finish or changes are detected. Available events for the v2 API:

Event Fires when
batch_finished All Screenshots in a Batch are complete.
comparison_status_new A new Comparison has been created (one per detected change).
queue_status_done A single Screenshot finishes successfully.
queue_status_failed A single Screenshot fails terminally.

If you can't host a webhook listener (e.g. local development), polling is a valid alternative — see "Wait for screenshots to finish" below.

Manual Checks

Manual checks compare a "before" state of your site to an "after" state. Run them around any change you want to verify (plugin updates, deployments, content edits).

  1. Take pre-update screenshots

    POST /api/v2/screenshots/take with sc_type = "pre" and the group_ids you want to capture. The response contains a batch_id — keep it for the next steps.

  2. Wait for screenshots to finish

    Either wait for the batch_finished webhook, or poll GET /api/v2/queues?batch_id={batch_id}&status=open,processing until the response is empty.

  3. Install updates

    Once the pre-update screenshots are done, perform your updates / changes on the site.

  4. Take post-update screenshots

    Same as Step 1, but with sc_type = "post" and the same group_ids. The API matches each post-Screenshot with its pre-counterpart and creates Comparisons automatically.

  5. Wait for screenshots to finish

    Wait for batch_finished (or poll as in Step 2). For each Comparison whose pixel diff exceeds the threshold, you'll additionally receive a comparison_status_new webhook.

  6. Check the differences

    GET /api/v2/comparisons?batch_id={batch_id} — filter by the post Batch to scope the result to this run. Each Comparison includes a public link for visual review.

(7. Optional: Re-check after fixes)

If you've made corrections on your site, run Step 4 again with a new sc_type = "post" Batch. The new post-Screenshots are compared against the original pre-Screenshots, so you can verify your fixes without redoing pre-capture.

That's all. You can now review all differences and make corrections on your site if something is broken, or roll back the updates.

Monitoring

For continuous monitoring (e.g. detecting surprises during the day), create the Group with monitoring = true:

POST /api/v2/groups
{
    "name": "example.com — Monitoring",
    "monitoring": true,
    "interval_in_h": 24,
    "alert_emails": ["ops@example.com"]
}

All URLs added to this Group are then captured and compared on the configured interval. Use the same Webhooks as for Manual Checks — comparison_status_new is typically the most useful event here.

Webhooks Verification

All webhook requests are signed with a SHA256 HMAC. The signature is sent in the Signature HTTP header.

Retrieve your webhook secret from GET /api/v2/account.

// PHP example
$signature = hash_hmac('sha256', $payloadJson, $secret);
if (! hash_equals($signature, $_SERVER['HTTP_SIGNATURE'])) {
    http_response_code(401);
    exit;
}

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your token on webchangedetector.com or via the plugin.

AI Feedback Rules

Manage rules for ignoring recurring false positives in AI verification results.

List AI Feedback Rules

requires authentication

Returns a paginated list of all AiFeedbackRule for the current user.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'scope' => 'url',
            'is_active' => '1',
            'website_id' => '21cf8800-f906-4fa3-b1db-ed3d2977354d',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/ai-feedback-rules?scope=url&is_active=1&website_id=21cf8800-f906-4fa3-b1db-ed3d2977354d" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules"
);

const params = {
    "scope": "url",
    "is_active": "1",
    "website_id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules'
params = {
  'scope': 'url',
  'is_active': '1',
  'website_id': '21cf8800-f906-4fa3-b1db-ed3d2977354d',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
            "scope": "url",
            "description": "Slider showing different slide",
            "region_context": {
                "bbox": {
                    "x": 0,
                    "y": 100,
                    "w": 1920,
                    "h": 300
                }
            },
            "is_active": true,
            "last_matched_at": null,
            "match_count": 0,
            "url_id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "group_id": null,
            "website_id": null,
            "created_at": "2026-02-21 13:37:00",
            "updated_at": "2026-02-21 13:37:00"
        }
    ]
}
 

Request   

GET api/v2/ai-feedback-rules

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

scope   string  optional  

Filter by scope. Example: url

Must be one of:
  • url
  • group
  • website
is_active   boolean  optional  

Filter by active status. Example: true

website_id   string  optional  

Filter by website UUID. Example: 21cf8800-f906-4fa3-b1db-ed3d2977354d

Create AI Feedback Rule

requires authentication

Creates a new AiFeedbackRule from a comparison region. The backend auto-resolves whether the group belongs to a website and sets the scope accordingly.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'type' => 'visual',
            'comparison_id' => '21cf8800-f906-4fa3-b1db-ed3d2977354d',
            'region_id' => 0,
            'console_entry' => '[Vue warn]: Component is missing template or render function.',
            'scope' => 'url',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"type\": \"visual\",
    \"comparison_id\": \"21cf8800-f906-4fa3-b1db-ed3d2977354d\",
    \"region_id\": 0,
    \"console_entry\": \"[Vue warn]: Component is missing template or render function.\",
    \"scope\": \"url\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": "visual",
    "comparison_id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
    "region_id": 0,
    "console_entry": "[Vue warn]: Component is missing template or render function.",
    "scope": "url"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules'
payload = {
    "type": "visual",
    "comparison_id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
    "region_id": 0,
    "console_entry": "[Vue warn]: Component is missing template or render function.",
    "scope": "url"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
        "scope": "url",
        "description": "Slider showing different slide",
        "region_context": {
            "bbox": {
                "x": 0,
                "y": 100,
                "w": 1920,
                "h": 300
            }
        },
        "is_active": true,
        "last_matched_at": null,
        "match_count": 0,
        "url_id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "group_id": null,
        "website_id": null,
        "created_at": "2026-02-21 13:37:00",
        "updated_at": "2026-02-21 13:37:00"
    }
}
 

Request   

POST api/v2/ai-feedback-rules

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

type   string  optional  

Feedback target. visual (default) trains the AI on a specific image region of a Comparison. console trains it on a browser-console log entry to ignore. Example: visual

Must be one of:
  • visual
  • console
comparison_id   string   

UUID of the comparison containing the region. Example: 21cf8800-f906-4fa3-b1db-ed3d2977354d

region_id   integer   

The region ID within the AI verification result. Example: 0

console_entry   string  optional  

Verbatim console-log line to teach the AI to ignore. Required when type=console. Max 500 chars. This field is required when type is console. Must not be greater than 500 characters. Example: [Vue warn]: Component is missing template or render function.

scope   string   

Scope for the rule: "url" for this URL only, "group_or_website" for all URLs. Example: url

Must be one of:
  • url
  • group_or_website

Update AI Feedback Rule

requires authentication

Update the active status and/or scope of an AiFeedbackRule.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'is_active' => false,
            'scope' => 'url',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"is_active\": false,
    \"scope\": \"url\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "is_active": false,
    "scope": "url"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut'
payload = {
    "is_active": false,
    "scope": "url"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
        "scope": "url",
        "description": "Slider showing different slide",
        "region_context": null,
        "is_active": false,
        "last_matched_at": null,
        "match_count": 0,
        "url_id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "group_id": null,
        "website_id": null,
        "created_at": "2026-02-21 13:37:00",
        "updated_at": "2026-02-21 13:37:00"
    }
}
 

Request   

PUT api/v2/ai-feedback-rules/{id}

PATCH api/v2/ai-feedback-rules/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the ai feedback rule. Example: aut

ai_feedback_rule   string   

The UUID of the AI Feedback Rule. Example: 21cf8800-f906-4fa3-b1db-ed3d2977354d

Body Parameters

is_active   boolean  optional  

Set the active status of the rule. Example: false

scope   string  optional  

Change the scope: "url" for this URL only, "group_or_website" for all URLs. Example: url

Must be one of:
  • url
  • group_or_website

Delete AI Feedback Rule

requires authentication

Permanently deletes an AiFeedbackRule.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request DELETE \
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/ai-feedback-rules/aut'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Request   

DELETE api/v2/ai-feedback-rules/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the ai feedback rule. Example: aut

ai_feedback_rule   string   

The UUID of the AI Feedback Rule. Example: 21cf8800-f906-4fa3-b1db-ed3d2977354d

Account

This object represents your account with WCD

Get Account

requires authentication

Retrieves your Account. The fields plan, plan_name, company and magic_login_secret only come for full accounts (not sub accounts).

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/account';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/account" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/account"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/account'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "041c6528-783f-4e7e-b831-1a424ffeb8f3",
        "name_first": "Hans",
        "name_last": "Hacker",
        "email": "mail@example.com",
        "webhook_secret": "zq3csqdst0txgo5qe9mkqsourrxo56wd",
        "is_subaccount": false,
        "account_level": 0,
        "can_manage_subaccounts": false,
        "can_create_subaccounts": false,
        "plan_label": null,
        "invitation_accepted": true,
        "plan_features": {
            "ai_verification": true,
            "browser_console": true
        },
        "checks_done": 6982,
        "checks_left": 3018,
        "checks_limit": 10000,
        "timezone": "UTC",
        "status": "active",
        "renewal_at": "2025-01-01 13:37:42",
        "plan": "agency",
        "plan_name": "Agency",
        "company": "ACME Ltd",
        "magic_login_secret": "WdKnLLcsDxpJdfmv"
    }
}
 

Request   

GET api/v2/account

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Update Account

requires authentication

Updates your Account by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/account';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name_first' => 'Jane',
            'name_last' => 'Doe',
            'company' => 'ACME LLC',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/account" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name_first\": \"Jane\",
    \"name_last\": \"Doe\",
    \"company\": \"ACME LLC\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/account"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name_first": "Jane",
    "name_last": "Doe",
    "company": "ACME LLC"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/account'
payload = {
    "name_first": "Jane",
    "name_last": "Doe",
    "company": "ACME LLC"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "041c6528-783f-4e7e-b831-1a424ffeb8f3",
        "name_first": "Jane",
        "name_last": "Doe",
        "email": "mail@example.com",
        "webhook_secret": "zq3csqdst0txgo5qe9mkqsourrxo56wd",
        "is_subaccount": false,
        "account_level": 0,
        "can_manage_subaccounts": false,
        "can_create_subaccounts": false,
        "plan_label": null,
        "invitation_accepted": true,
        "plan_features": {
            "ai_verification": true,
            "browser_console": true
        },
        "checks_done": 42,
        "checks_left": 1337,
        "checks_limit": 1379,
        "timezone": "UTC",
        "status": "active",
        "renewal_at": "2025-01-01 13:37:42",
        "plan": "agency",
        "plan_name": "Agency",
        "company": "ACME LLC",
        "magic_login_secret": "WdKnLLcsDxpJdfmv"
    }
}
 

Request   

PUT api/v2/account

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name_first   string  optional  

First Name Example: Jane

name_last   string  optional  

Last Name Example: Doe

company   string  optional  

Company Name Example: ACME LLC

Get Account Stats

requires authentication

Returns aggregated statistics for the authenticated account. Currently includes estimated monthly monitoring checks across all enabled monitoring groups.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/account/stats';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/account/stats" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/account/stats"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/account/stats'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "estimated_monthly_checks": 4520
    }
}
 

Request   

GET api/v2/account/stats

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Batch

This object represents Batches of Queues.

List Batches

requires authentication

Returns a list of all Batch. The Batches are sorted by creation date, with the most recent Batches appearing first.

source is one of manual, monitoring, auto_update. ai_summary is null for accounts without the ai-verification feature; ai_summary.overall_status is one of everything_ok, needs_attention.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/batches';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'above_threshold' => '0',
            'from' => '2024-07-01',
            'to' => '2024-07-04',
            'status' => 'to_fix,false_positive',
            'queue_type' => 'post,comparison',
            'group_ids' => '023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230',
            'urls' => '023c282c-6513-420a-a36b-a654312ab229',
            'websites' => '023c282c-6513-420a-a36b-a654312ab229',
            'source' => 'manual,auto_update',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/batches?above_threshold=&from=2024-07-01&to=2024-07-04&status=to_fix%2Cfalse_positive&queue_type=post%2Ccomparison&group_ids=023c282c-6513-420a-a36b-a654312ab229%2C023c282c-6513-420a-a36b-a654312ab230&urls=023c282c-6513-420a-a36b-a654312ab229&websites=023c282c-6513-420a-a36b-a654312ab229&source=manual%2Cauto_update" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/batches"
);

const params = {
    "above_threshold": "0",
    "from": "2024-07-01",
    "to": "2024-07-04",
    "status": "to_fix,false_positive",
    "queue_type": "post,comparison",
    "group_ids": "023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230",
    "urls": "023c282c-6513-420a-a36b-a654312ab229",
    "websites": "023c282c-6513-420a-a36b-a654312ab229",
    "source": "manual,auto_update",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/batches'
params = {
  'above_threshold': '0',
  'from': '2024-07-01',
  'to': '2024-07-04',
  'status': 'to_fix,false_positive',
  'queue_type': 'post,comparison',
  'group_ids': '023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230',
  'urls': '023c282c-6513-420a-a36b-a654312ab229',
  'websites': '023c282c-6513-420a-a36b-a654312ab229',
  'source': 'manual,auto_update',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "0d5f8108-51f1-4961-939a-2d33c7145918",
            "name": "Foobar",
            "source": "monitoring",
            "group_names": [
                "example.com - Monitoring Checks"
            ],
            "sc_version": "2.0",
            "finished_at": "2024-07-29 13:37:42",
            "ai_summary": {
                "summary": "Pricing text updated and navigation menu restructured. New JS error on checkout may affect functionality.",
                "overall_status": "needs_attention",
                "processing_time_ms": 1234
            },
            "comparisons_count": {
                "ok": 0,
                "new": 1,
                "false_positive": 0,
                "to_fix": 0,
                "above_threshold": 10
            },
            "queues_count": {
                "failed": 0
            },
            "browser_console_count": {
                "added": 1,
                "removed": 0,
                "mixed": 0,
                "unchanged": 0
            }
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/batches?page=1",
        "last": "http://api.webchangedetector.test/api/v2/batches?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/batches?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/batches",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/batches

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

above_threshold   boolean  optional  

Only show Batches where there is a change detected between 2 screenshots. Example: false

from   string  optional  

Start date for filter. Must be a valid date. Example: 2024-07-01

to   string  optional  

End date for filter, defaults to today. Must be a valid date. Example: 2024-07-04

status   string  optional  

Comma separated list of Comparison status to filter for. Example: to_fix,false_positive

queue_type   string  optional  

Comma separated list of Queue types to filter for. Example: post,comparison

group_ids   string  optional  

Comma separated list of Group IDs. Example: 023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230

urls   string  optional  

Comma separated list of URL IDs to filter for. Example: 023c282c-6513-420a-a36b-a654312ab229

websites   string  optional  

Comma separated list of Website IDs to filter for. Example: 023c282c-6513-420a-a36b-a654312ab229

source   string  optional  

Comma separated list of Batch sources to filter for (manual, monitoring, auto_update). Example: manual,auto_update

Get Batch

requires authentication

Retrieves a Batch object identfied by their ID.

source is one of manual, monitoring, auto_update. ai_summary is null for accounts without the ai-verification feature; ai_summary.overall_status is one of everything_ok, needs_attention.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "0d5f8108-51f1-4961-939a-2d33c7145918",
        "name": "Foobar",
        "source": "monitoring",
        "group_names": [
            "example.com - Monitoring Checks"
        ],
        "sc_version": "2.0",
        "finished_at": "2024-07-29 13:37:42",
        "ai_summary": {
            "summary": "Pricing text updated and navigation menu restructured. New JS error on checkout may affect functionality.",
            "overall_status": "needs_attention",
            "processing_time_ms": 1234
        },
        "comparisons_count": {
            "ok": 0,
            "new": 1,
            "false_positive": 0,
            "to_fix": 0,
            "above_threshold": 10
        },
        "queues_count": {
            "failed": 0
        },
        "browser_console_count": {
            "added": 1,
            "removed": 0,
            "mixed": 0,
            "unchanged": 0
        }
    }
}
 

Request   

GET api/v2/batches/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Batch. Example: 0d5f8108-51f1-4961-939a-2d33c7145918

Update Batch

requires authentication

Updates the specified Batch by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Foobar',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Foobar\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Foobar"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/batches/0d5f8108-51f1-4961-939a-2d33c7145918'
payload = {
    "name": "Foobar"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "id": "0d5f8108-51f1-4961-939a-2d33c7145918",
    "name": "Foobar",
    "source": "monitoring",
    "group_names": [
        "example.com - Monitoring Checks"
    ],
    "sc_version": "2.0",
    "finished_at": "2024-07-29 13:37:42",
    "ai_summary": {
        "summary": "Pricing text updated and navigation menu restructured. New JS error on checkout may affect functionality.",
        "overall_status": "needs_attention",
        "processing_time_ms": 1234
    },
    "comparisons_count": {
        "ok": 0,
        "new": 1,
        "false_positive": 0,
        "to_fix": 0,
        "above_threshold": 10
    },
    "queues_count": {
        "failed": 0
    },
    "browser_console_count": {
        "added": 1,
        "removed": 0,
        "mixed": 0,
        "unchanged": 0
    }
}
 

Request   

PUT api/v2/batches/{id}

PATCH api/v2/batches/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Batch. Example: 0d5f8108-51f1-4961-939a-2d33c7145918

Body Parameters

name   string   

The name of the Batch. Example: Foobar

Comparison

This object represents the comparison between 2 Screenshots and how they differ.

List Comparisons

requires authentication

Returns a list of all Comparison. The Comparisons are sorted by creation date, with the most recent Comparisons appearing first.

batch_source is one of manual, monitoring, auto_update. browser_console_* fields are null unless the account has the browser-console-comparisons feature. ai_regions, ai_verification_status, and ai_verification_result are null unless the account has the ai-verification feature; ai_verification_status is one of pending, verified, failed, skipped.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/comparisons';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'above_threshold' => '0',
            'from' => '2024-07-01',
            'to' => '2024-07-04',
            'status' => 'to_fix,false_positive',
            'groups' => '023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230',
            'batches' => '0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918',
            'token' => 'et',
            'urls' => '023c282c-6513-420a-a36b-a654312ab229',
            'websites' => '023c282c-6513-420a-a36b-a654312ab229',
            'source' => 'manual,auto_update',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/comparisons?above_threshold=&from=2024-07-01&to=2024-07-04&status=to_fix%2Cfalse_positive&groups=023c282c-6513-420a-a36b-a654312ab229%2C023c282c-6513-420a-a36b-a654312ab230&batches=0d5f8108-51f1-4961-939a-2d33c7145918%2C1d5f8108-51f1-4961-939a-2d33c7145918&token=et&urls=023c282c-6513-420a-a36b-a654312ab229&websites=023c282c-6513-420a-a36b-a654312ab229&source=manual%2Cauto_update" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/comparisons"
);

const params = {
    "above_threshold": "0",
    "from": "2024-07-01",
    "to": "2024-07-04",
    "status": "to_fix,false_positive",
    "groups": "023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230",
    "batches": "0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918",
    "token": "et",
    "urls": "023c282c-6513-420a-a36b-a654312ab229",
    "websites": "023c282c-6513-420a-a36b-a654312ab229",
    "source": "manual,auto_update",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/comparisons'
params = {
  'above_threshold': '0',
  'from': '2024-07-01',
  'to': '2024-07-04',
  'status': 'to_fix,false_positive',
  'groups': '023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230',
  'batches': '0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918',
  'token': 'et',
  'urls': '023c282c-6513-420a-a36b-a654312ab229',
  'websites': '023c282c-6513-420a-a36b-a654312ab229',
  'source': 'manual,auto_update',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
            "screenshot_1": "958dce2c-8468-47d3-8bc2-7dc6bf0aadae",
            "screenshot_1_created_at": "2025-01-01 13:37:00",
            "screenshot_1_updated_at": "2025-01-01 13:37:01",
            "screenshot_1_link": "https://storage.webchangedetector.com/folder/screenshot1.png",
            "screenshot_2": "958dce2c-8468-47d3-8bc2-7dc6bf0aadaf",
            "screenshot_2_created_at": "2025-01-01 13:37:00",
            "screenshot_2_updated_at": "2025-01-01 13:37:01",
            "screenshot_2_link": "https://storage.webchangedetector.com/folder/screenshot2.png",
            "html_title": "Foobar",
            "device": "mobile",
            "monitoring": true,
            "group": "023c282c-6513-420a-a36b-a654312ab229",
            "group_name": "Barfoo",
            "queue": "8ea7b88d-b5c6-4fad-8e9d-1497a54d9266",
            "link": "https://storage.webchangedetector.com/folder/comparison.png",
            "batch": "0d5f8108-51f1-4961-939a-2d33c7145918",
            "batch_name": "Auto Update Checks",
            "batch_source": "monitoring",
            "difference_percent": 0.4,
            "threshold": 0.2,
            "status": "new",
            "public_link": "https://www.webchangedetector.com/show-change-detection?token=f00b4r",
            "token": "f00b4r",
            "url": "https://example.com",
            "url_id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "cms": "wordpress",
            "browser_console_added": null,
            "browser_console_removed": null,
            "browser_console_change": null,
            "ai_regions": [
                {
                    "id": 0,
                    "bbox": {
                        "x": 120,
                        "y": 340,
                        "w": 280,
                        "h": 64
                    },
                    "pixel_count": 1840
                }
            ],
            "ai_verification_status": "verified",
            "ai_verification_result": {
                "summary": "Pricing text updated, may need review.",
                "processing_time_ms": 1234,
                "total_regions": 1,
                "all_good": 0,
                "not_sure": 0,
                "alerts": 1,
                "regions": [
                    {
                        "region_id": 0,
                        "category": "alert",
                        "description": "Pricing changed from $9 to $12",
                        "confidence": 0.92,
                        "reason": "Numeric price text changed in hero section",
                        "matched_feedback_rule": null
                    }
                ],
                "console_analysis": null
            },
            "created_at": "2025-01-01 13:37:00"
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/comparisons?page=1",
        "last": "http://api.webchangedetector.test/api/v2/comparisons?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/comparisons?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/comparisons",
        "per_page": 15,
        "to": 1,
        "total": 1,
        "above_threshold_count": 3
    }
}
 

Request   

GET api/v2/comparisons

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

above_threshold   boolean  optional  

Is a change detected between 2 screenshots. Example: false

from   string  optional  

Start date for filter. Must be a valid date. Example: 2024-07-01

to   string  optional  

End date for filter, defaults to today. Must be a valid date. Example: 2024-07-04

status   string  optional  

Comma separated list of status to filter for. Example: to_fix,false_positive

groups   string  optional  

Comma separated list of group IDs. Example: 023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230

batches   string  optional  

Batch IDs. Example: 0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918

token   string  optional  

Example: et

urls   string  optional  

Comma separated list of URL UUIDs. Example: 023c282c-6513-420a-a36b-a654312ab229

websites   string  optional  

Comma separated list of Website UUIDs. Example: 023c282c-6513-420a-a36b-a654312ab229

source   string  optional  

Comma separated list of Batch sources to filter for (manual, monitoring, auto_update). Example: manual,auto_update

Get Comparison

requires authentication

Retrieves a Comparison object identfied by their ID.

batch_source is one of manual, monitoring, auto_update. browser_console_* fields are null unless the account has the browser-console-comparisons feature. ai_regions, ai_verification_status, and ai_verification_result are null unless the account has the ai-verification feature; ai_verification_status is one of pending, verified, failed, skipped.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
        "screenshot_1": "958dce2c-8468-47d3-8bc2-7dc6bf0aadae",
        "screenshot_1_created_at": "2025-01-01 13:37:00",
        "screenshot_1_updated_at": "2025-01-01 13:37:01",
        "screenshot_1_link": "https://storage.webchangedetector.com/folder/screenshot1.png",
        "screenshot_2": "958dce2c-8468-47d3-8bc2-7dc6bf0aadaf",
        "screenshot_2_created_at": "2025-01-01 13:37:00",
        "screenshot_2_updated_at": "2025-01-01 13:37:01",
        "screenshot_2_link": "https://storage.webchangedetector.com/folder/screenshot2.png",
        "html_title": "Foobar",
        "device": "mobile",
        "monitoring": true,
        "group": "023c282c-6513-420a-a36b-a654312ab229",
        "group_name": "Barfoo",
        "queue": "8ea7b88d-b5c6-4fad-8e9d-1497a54d9266",
        "link": "https://storage.webchangedetector.com/folder/comparison.png",
        "batch": "0d5f8108-51f1-4961-939a-2d33c7145918",
        "batch_name": "Auto Update Checks",
        "batch_source": "monitoring",
        "difference_percent": 0.4,
        "threshold": 0.2,
        "status": "new",
        "public_link": "https://www.webchangedetector.com/show-change-detection?token=f00b4r",
        "token": "f00b4r",
        "url": "https://example.com",
        "url_id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "cms": "wordpress",
        "browser_console_added": null,
        "browser_console_removed": null,
        "browser_console_change": null,
        "ai_regions": [
            {
                "id": 0,
                "bbox": {
                    "x": 120,
                    "y": 340,
                    "w": 280,
                    "h": 64
                },
                "pixel_count": 1840
            }
        ],
        "ai_verification_status": "verified",
        "ai_verification_result": {
            "summary": "Pricing text updated, may need review.",
            "processing_time_ms": 1234,
            "total_regions": 1,
            "all_good": 0,
            "not_sure": 0,
            "alerts": 1,
            "regions": [
                {
                    "region_id": 0,
                    "category": "alert",
                    "description": "Pricing changed from $9 to $12",
                    "confidence": 0.92,
                    "reason": "Numeric price text changed in hero section",
                    "matched_feedback_rule": null
                }
            ],
            "console_analysis": null
        },
        "created_at": "2025-01-01 13:37:00"
    }
}
 

Request   

GET api/v2/comparisons/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Comparison. Example: 21cf8800-f906-4fa3-b1db-ed3d2977354d

Update Comparison

requires authentication

Updates the specified Comparison by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

batch_source is one of manual, monitoring, auto_update. browser_console_* fields are null unless the account has the browser-console-comparisons feature. ai_regions, ai_verification_status, and ai_verification_result are null unless the account has the ai-verification feature; ai_verification_status is one of pending, verified, failed, skipped.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'status' => 'false_positive',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"status\": \"false_positive\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status": "false_positive"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/comparisons/21cf8800-f906-4fa3-b1db-ed3d2977354d'
payload = {
    "status": "false_positive"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "id": "21cf8800-f906-4fa3-b1db-ed3d2977354d",
    "screenshot_1": "958dce2c-8468-47d3-8bc2-7dc6bf0aadae",
    "screenshot_1_created_at": "2025-01-01 13:37:00",
    "screenshot_1_updated_at": "2025-01-01 13:37:01",
    "screenshot_1_link": "https://storage.webchangedetector.com/folder/screenshot1.png",
    "screenshot_2": "958dce2c-8468-47d3-8bc2-7dc6bf0aadaf",
    "screenshot_2_created_at": "2025-01-01 13:37:00",
    "screenshot_2_updated_at": "2025-01-01 13:37:01",
    "screenshot_2_link": "https://storage.webchangedetector.com/folder/screenshot2.png",
    "html_title": "Foobar",
    "device": "mobile",
    "monitoring": true,
    "group": "023c282c-6513-420a-a36b-a654312ab229",
    "group_name": "Barfoo",
    "queue": "8ea7b88d-b5c6-4fad-8e9d-1497a54d9266",
    "link": "https://storage.webchangedetector.com/folder/comparison.png",
    "batch": "0d5f8108-51f1-4961-939a-2d33c7145918",
    "batch_name": "Auto Update Checks",
    "batch_source": "monitoring",
    "difference_percent": 0.4,
    "threshold": 0.2,
    "status": "new",
    "public_link": "https://www.webchangedetector.com/show-change-detection?token=f00b4r",
    "token": "f00b4r",
    "url": "https://example.com",
    "url_id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
    "cms": "wordpress",
    "browser_console_added": null,
    "browser_console_removed": null,
    "browser_console_change": null,
    "ai_regions": [
        {
            "id": 0,
            "bbox": {
                "x": 120,
                "y": 340,
                "w": 280,
                "h": 64
            },
            "pixel_count": 1840
        }
    ],
    "ai_verification_status": "verified",
    "ai_verification_result": {
        "summary": "Pricing text updated, may need review.",
        "processing_time_ms": 1234,
        "total_regions": 1,
        "all_good": 0,
        "not_sure": 0,
        "alerts": 1,
        "regions": [
            {
                "region_id": 0,
                "category": "alert",
                "description": "Pricing changed from $9 to $12",
                "confidence": 0.92,
                "reason": "Numeric price text changed in hero section",
                "matched_feedback_rule": null
            }
        ],
        "console_analysis": null
    },
    "created_at": "2025-01-01 13:37:00"
}
 

Request   

PUT api/v2/comparisons/{id}

PATCH api/v2/comparisons/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Comparison. Example: 21cf8800-f906-4fa3-b1db-ed3d2977354d

Body Parameters

status   string   

Mark the comparison as a false positive, as fixed or simply ok. Example: false_positive

Must be one of:
  • false_positive
  • ok
  • to_fix

Group

This object groups together a list of URLs and group wide settings for them.

List Groups

requires authentication

Returns a list of all Groups. The Groups are sorted by creation date, with the most recent Groups appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'per_page' => '15',
            'monitoring' => '0',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/groups?per_page=15&monitoring=" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups"
);

const params = {
    "per_page": "15",
    "monitoring": "0",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups'
params = {
  'per_page': '15',
  'monitoring': '0',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "023c282c-6513-420a-a36b-a654312ab229",
            "name": "Example Group",
            "monitoring": true,
            "enabled": true,
            "hour_of_day": 0,
            "interval_in_h": 24,
            "alert_emails": "hello@example.com,test@foobar.com",
            "css": null,
            "js": null,
            "cms": "wordpress",
            "threshold": 0.2,
            "urls_count": 42,
            "selected_urls_count": 37,
            "basic_auth_user": null,
            "has_basic_auth": false,
            "proxy_type": "none",
            "proxy_country": null
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/groups?page=1",
        "last": "http://api.webchangedetector.test/api/v2/groups?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/groups?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/groups",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/groups

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

per_page   integer  optional  

Maximum number of Groups per page. Example: 15

monitoring   boolean  optional  

Filter to monitoring (true) or manual-checks (false) groups only. Omit to return both. Example: false

Create Group

requires authentication

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Example Group',
            'monitoring' => true,
            'enabled' => true,
            'hour_of_day' => 0,
            'interval_in_h' => 24,
            'schedule_type' => 'interval',
            'schedule_days' => [
                1,
                3,
                5,
            ],
            'quiet_hours_start' => 22,
            'quiet_hours_end' => 6,
            'alert_emails' => [
                'hello@example.com',
                'mail@example.com',
            ],
            'cms' => 'wordpress',
            'basic_auth_user' => 'admin',
            'basic_auth_password' => 'secret123',
            'proxy_type' => 'static',
            'proxy_country' => 'de',
            'screenshot_delay' => 10,
            'css' => '.btn {visibility: none;}',
            'js' => '',
            'threshold' => 0.4,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/groups" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Example Group\",
    \"monitoring\": true,
    \"enabled\": true,
    \"hour_of_day\": 0,
    \"interval_in_h\": 24,
    \"schedule_type\": \"interval\",
    \"schedule_days\": [
        1,
        3,
        5
    ],
    \"quiet_hours_start\": 22,
    \"quiet_hours_end\": 6,
    \"alert_emails\": [
        \"hello@example.com\",
        \"mail@example.com\"
    ],
    \"cms\": \"wordpress\",
    \"basic_auth_user\": \"admin\",
    \"basic_auth_password\": \"secret123\",
    \"proxy_type\": \"static\",
    \"proxy_country\": \"de\",
    \"screenshot_delay\": 10,
    \"css\": \".btn {visibility: none;}\",
    \"js\": \"\",
    \"threshold\": 0.4
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Example Group",
    "monitoring": true,
    "enabled": true,
    "hour_of_day": 0,
    "interval_in_h": 24,
    "schedule_type": "interval",
    "schedule_days": [
        1,
        3,
        5
    ],
    "quiet_hours_start": 22,
    "quiet_hours_end": 6,
    "alert_emails": [
        "hello@example.com",
        "mail@example.com"
    ],
    "cms": "wordpress",
    "basic_auth_user": "admin",
    "basic_auth_password": "secret123",
    "proxy_type": "static",
    "proxy_country": "de",
    "screenshot_delay": 10,
    "css": ".btn {visibility: none;}",
    "js": "",
    "threshold": 0.4
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups'
payload = {
    "name": "Example Group",
    "monitoring": true,
    "enabled": true,
    "hour_of_day": 0,
    "interval_in_h": 24,
    "schedule_type": "interval",
    "schedule_days": [
        1,
        3,
        5
    ],
    "quiet_hours_start": 22,
    "quiet_hours_end": 6,
    "alert_emails": [
        "hello@example.com",
        "mail@example.com"
    ],
    "cms": "wordpress",
    "basic_auth_user": "admin",
    "basic_auth_password": "secret123",
    "proxy_type": "static",
    "proxy_country": "de",
    "screenshot_delay": 10,
    "css": ".btn {visibility: none;}",
    "js": "",
    "threshold": 0.4
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "023c282c-6513-420a-a36b-a654312ab229",
        "name": "Example Group",
        "monitoring": true,
        "enabled": true,
        "hour_of_day": 0,
        "interval_in_h": 24,
        "schedule_type": "interval",
        "schedule_days": null,
        "quiet_hours_start": null,
        "quiet_hours_end": null,
        "alert_emails": "hello@example.com,test@foobar.com",
        "css": ".btn {visibility: none;}",
        "js": "",
        "cms": "wordpress",
        "threshold": 0.2,
        "urls_count": 42,
        "selected_urls_count": 37,
        "basic_auth_user": null,
        "has_basic_auth": false,
        "proxy_type": "none",
        "proxy_country": null
    }
}
 

Request   

POST api/v2/groups

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Name of the Group. Example: Example Group

monitoring   boolean  optional  

Defaults to false. Example: true

Must be one of:
  • true
  • false
enabled   boolean  optional  

Defaults to true. Example: true

Must be one of:
  • true
  • false
hour_of_day   integer  optional  

Which hour of the day are the auto updates executed. Defaults to 0 Example: 0

interval_in_h   number  optional  

One of the following intervals of the hour. Defaults to 24 Example: 24

Must be one of:
  • 0.25
  • 0.5
  • 3
  • 6
  • 12
  • 24
schedule_type   string  optional  

Schedule type: interval (default), weekly, or monthly Example: interval

Must be one of:
  • interval
  • weekly
  • monthly
schedule_days   string[]  optional  

Days for weekly (1=Mon..7=Sun) or monthly (1-30 or "last") schedules

quiet_hours_start   integer  optional  

Hour (0-23) when quiet period starts. No checks during quiet hours. Example: 22

quiet_hours_end   integer  optional  

Hour (0-23) when quiet period ends Example: 6

alert_emails   string[]  optional  

A list of emails to notify. Defaults to the account email.

cms   string  optional  

Optional CMS hint used by the screenshot pipeline (e.g. wordpress). Allowed values: see config/enums.cms. Example: wordpress

Must be one of:
  • wordpress
basic_auth_user   string  optional  

Username for HTTP Basic Authentication Example: admin

basic_auth_password   string  optional  

Password for HTTP Basic Authentication Example: secret123

proxy_type   string  optional  

Proxy type to use for screenshots Example: static

Must be one of:
  • none
  • static
  • residential
proxy_country   string  optional  

Country code for residential proxy (2-letter ISO code) Example: de

screenshot_delay   integer  optional  

Minimum seconds between consecutive screenshot dispatches for this group, per user (7-60). Higher values reduce load on the screenshoter and target site, useful for groups with many URLs. Must be at least 7. Must not be greater than 60. Example: 10

css   string  optional  

CSS to be injected before the screenshot is taken for all URLs in this group Example: .btn {visibility: none;}

js   string  optional  

JavaScript to be injected before the screenshot is taken for all URLs in this group

threshold   numeric  optional  

Difference in percent of when this counts as a change detection for all URLs in this group Example: 0.4

Get Group

requires authentication

Retrieves a Group object identfied by their ID

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "023c282c-6513-420a-a36b-a654312ab229",
        "name": "Example Group",
        "monitoring": true,
        "enabled": true,
        "hour_of_day": 0,
        "interval_in_h": 24,
        "alert_emails": "hello@example.com,test@foobar.com",
        "css": null,
        "js": null,
        "cms": "wordpress",
        "threshold": 0.2,
        "urls_count": 42,
        "selected_urls_count": 37,
        "basic_auth_user": null,
        "has_basic_auth": false,
        "proxy_type": "none",
        "proxy_country": null
    }
}
 

Request   

GET api/v2/groups/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

Update Group

requires authentication

Updates the specified Group by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Example Group',
            'monitoring' => true,
            'enabled' => true,
            'hour_of_day' => 0,
            'interval_in_h' => 24,
            'schedule_type' => 'interval',
            'schedule_days' => [
                1,
                3,
                5,
            ],
            'quiet_hours_start' => 22,
            'quiet_hours_end' => 6,
            'alert_emails' => [
                'hello@example.com',
                'mail@example.com',
            ],
            'css' => '.btn {visibility: none;}',
            'js' => '',
            'threshold' => 0.4,
            'basic_auth_user' => 'admin',
            'basic_auth_password' => 'secret123',
            'proxy_type' => 'none',
            'proxy_country' => 'de',
            'screenshot_delay' => 10,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Example Group\",
    \"monitoring\": true,
    \"enabled\": true,
    \"hour_of_day\": 0,
    \"interval_in_h\": 24,
    \"schedule_type\": \"interval\",
    \"schedule_days\": [
        1,
        3,
        5
    ],
    \"quiet_hours_start\": 22,
    \"quiet_hours_end\": 6,
    \"alert_emails\": [
        \"hello@example.com\",
        \"mail@example.com\"
    ],
    \"css\": \".btn {visibility: none;}\",
    \"js\": \"\",
    \"threshold\": 0.4,
    \"basic_auth_user\": \"admin\",
    \"basic_auth_password\": \"secret123\",
    \"proxy_type\": \"none\",
    \"proxy_country\": \"de\",
    \"screenshot_delay\": 10
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Example Group",
    "monitoring": true,
    "enabled": true,
    "hour_of_day": 0,
    "interval_in_h": 24,
    "schedule_type": "interval",
    "schedule_days": [
        1,
        3,
        5
    ],
    "quiet_hours_start": 22,
    "quiet_hours_end": 6,
    "alert_emails": [
        "hello@example.com",
        "mail@example.com"
    ],
    "css": ".btn {visibility: none;}",
    "js": "",
    "threshold": 0.4,
    "basic_auth_user": "admin",
    "basic_auth_password": "secret123",
    "proxy_type": "none",
    "proxy_country": "de",
    "screenshot_delay": 10
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229'
payload = {
    "name": "Example Group",
    "monitoring": true,
    "enabled": true,
    "hour_of_day": 0,
    "interval_in_h": 24,
    "schedule_type": "interval",
    "schedule_days": [
        1,
        3,
        5
    ],
    "quiet_hours_start": 22,
    "quiet_hours_end": 6,
    "alert_emails": [
        "hello@example.com",
        "mail@example.com"
    ],
    "css": ".btn {visibility: none;}",
    "js": "",
    "threshold": 0.4,
    "basic_auth_user": "admin",
    "basic_auth_password": "secret123",
    "proxy_type": "none",
    "proxy_country": "de",
    "screenshot_delay": 10
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "023c282c-6513-420a-a36b-a654312ab229",
        "name": "Example Group",
        "monitoring": true,
        "enabled": true,
        "hour_of_day": 0,
        "interval_in_h": 24,
        "schedule_type": "interval",
        "schedule_days": null,
        "quiet_hours_start": null,
        "quiet_hours_end": null,
        "alert_emails": "hello@example.com,test@foobar.com",
        "css": ".btn {visibility: none;}",
        "js": "",
        "cms": "wordpress",
        "threshold": 0.2,
        "urls_count": 42,
        "selected_urls_count": 37,
        "basic_auth_user": "admin",
        "has_basic_auth": true,
        "proxy_type": "static",
        "proxy_country": "de"
    }
}
 

Request   

PUT api/v2/groups/{id}

PATCH api/v2/groups/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

Body Parameters

name   string  optional  

Name of the Group. Example: Example Group

monitoring   boolean  optional  

Defaults to false. Example: true

Must be one of:
  • true
  • false
enabled   boolean  optional  

Defaults to true. Example: true

Must be one of:
  • true
  • false
hour_of_day   integer  optional  

Which hour of the day are the auto updates executed. Defaults to 0 Example: 0

interval_in_h   number  optional  

One of the following intervals of the hour. Defaults to 24 Example: 24

Must be one of:
  • 0.25
  • 0.5
  • 3
  • 6
  • 12
  • 24
schedule_type   string  optional  

Schedule type: interval (default), weekly, or monthly Example: interval

Must be one of:
  • interval
  • weekly
  • monthly
schedule_days   string[]  optional  

Days for weekly (1=Mon..7=Sun) or monthly (1-30 or "last") schedules

quiet_hours_start   integer  optional  

Hour (0-23) when quiet period starts. No checks during quiet hours. Example: 22

quiet_hours_end   integer  optional  

Hour (0-23) when quiet period ends Example: 6

alert_emails   string[]  optional  

A list of emails to notify. Defaults to the account email.

css   string  optional  

CSS to be injected before the screenshot is taken for all URLs in this group Example: .btn {visibility: none;}

js   string  optional  

JavaScript to be injected before the screenshot is taken for all URLs in this group

threshold   numeric  optional  

Difference in percent of when this counts as a change detection for all URLs in this group Example: 0.4

basic_auth_user   string  optional  

Username for HTTP Basic Authentication Example: admin

basic_auth_password   string  optional  

Password for HTTP Basic Authentication Example: secret123

proxy_type   string  optional  

Proxy type to use for screenshots Example: none

Must be one of:
  • none
  • static
  • residential
proxy_country   string  optional  

Country code for residential proxy (2-letter ISO code) Example: de

screenshot_delay   integer  optional  

Minimum seconds between consecutive screenshot dispatches for this group, per user (7-60). Higher values reduce load on the screenshoter and target site, useful for groups with many URLs. Must be at least 7. Must not be greater than 60. Example: 10

Delete Group

requires authentication

Permanently deletes a Group. This cannot be undone.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request DELETE \
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Example response (200):


{
    "message": "{ID} deleted"
}
 

Request   

DELETE api/v2/groups/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

Add Urls To Group

requires authentication

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/add-urls';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'urls' => [
                [
                    'id' => '418e0748-a9cf-480b-86d6-88b00bac00b9',
                    'desktop' => true,
                ],
                [
                    'id' => '418e0748-a9cf-480b-86d6-88b00bac00c1',
                    'mobile' => false,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/add-urls" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"urls\": [
        {
            \"id\": \"418e0748-a9cf-480b-86d6-88b00bac00b9\",
            \"desktop\": true
        },
        {
            \"id\": \"418e0748-a9cf-480b-86d6-88b00bac00c1\",
            \"mobile\": false
        }
    ]
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/add-urls"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "urls": [
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "desktop": true
        },
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00c1",
            "mobile": false
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/add-urls'
payload = {
    "urls": [
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "desktop": true
        },
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00c1",
            "mobile": false
        }
    ]
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "count": "{Amount of URLs added}"
}
 

Request   

POST api/v2/groups/{id}/add-urls

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

Body Parameters

urls   string[]   

Array of URLs with their settings in this Group

id   string   

UUID of an existing URL (registered via POST /api/v2/urls). Must be a valid UUID. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

desktop   boolean  optional  

Capture desktop screenshots for this URL in the Group. Example: false

mobile   boolean  optional  

Capture mobile screenshots for this URL in the Group. Example: false

css   string  optional  

URL-level CSS overrides applied on top of the Group CSS before screenshotting.

js   string  optional  

URL-level JavaScript overrides applied on top of the Group JS before screenshotting.

Remove Urls From Group

requires authentication

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/remove-urls';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'urls' => [
                '418e0748-a9cf-480b-86d6-88b00bac00b9',
                '418e0748-a9cf-480b-86d6-88b00bac00c1',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/remove-urls" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"urls\": [
        \"418e0748-a9cf-480b-86d6-88b00bac00b9\",
        \"418e0748-a9cf-480b-86d6-88b00bac00c1\"
    ]
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/remove-urls"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "urls": [
        "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "418e0748-a9cf-480b-86d6-88b00bac00c1"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/remove-urls'
payload = {
    "urls": [
        "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "418e0748-a9cf-480b-86d6-88b00bac00c1"
    ]
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "count": "{Amount of URLs removed}"
}
 

Request   

POST api/v2/groups/{id}/remove-urls

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

Body Parameters

urls   string[]   

Array of URL IDs

List Urls For Group

requires authentication

Returns a list of all Urls. The Urls are sorted by creation date, with the most recent Urls appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'per_page' => '25',
            'type' => 'posts',
            'category' => 'types',
            'search' => 'about',
            'url_ids' => '91e9c9fd-b86f-4269-a3f4-f02810167a6d,b3a9d2e5-2c64-4a16-8f1c-9e3b21f8a4e7',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls?per_page=25&type=posts&category=types&search=about&url_ids=91e9c9fd-b86f-4269-a3f4-f02810167a6d%2Cb3a9d2e5-2c64-4a16-8f1c-9e3b21f8a4e7" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls"
);

const params = {
    "per_page": "25",
    "type": "posts",
    "category": "types",
    "search": "about",
    "url_ids": "91e9c9fd-b86f-4269-a3f4-f02810167a6d,b3a9d2e5-2c64-4a16-8f1c-9e3b21f8a4e7",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls'
params = {
  'per_page': '25',
  'type': 'posts',
  'category': 'types',
  'search': 'about',
  'url_ids': '91e9c9fd-b86f-4269-a3f4-f02810167a6d,b3a9d2e5-2c64-4a16-8f1c-9e3b21f8a4e7',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "html_title": "Example Title",
            "url": "example.com/foobar",
            "last_crawled_at": "2025-01-01 13:37:42",
            "desktop": true,
            "mobile": true,
            "css": null,
            "js": null,
            "threshold": null,
            "group": "023c282c-6513-420a-a36b-a654312ab229"
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls?page=1",
        "last": "http://api.webchangedetector.test/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls",
        "per_page": 15,
        "to": 1,
        "total": 1,
        "selected_urls_count": 1
    }
}
 

Request   

GET api/v2/groups/{id}/urls

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

type   string   

URL Type. Example: foobar

category   string   

Category. Example: barfoo

search   string   

Search in html_title and url. Example: loremipsum

url_ids   string   

Comma separated list of URL UUIDs Example: est

Query Parameters

per_page   integer  optional  

Maximum number of URLs per page. Example: 25

type   string  optional  

Filter by post-type slug (e.g. posts, pages, products). Example: posts

category   string  optional  

Filter by URL category (e.g. types, taxonomies, frontpage). Example: types

search   string  optional  

Substring match against the URL or its title. Example: about

url_ids   string  optional  

Comma-separated list of URL UUIDs to restrict the result to. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d,b3a9d2e5-2c64-4a16-8f1c-9e3b21f8a4e7

Update Url In Group

requires authentication

Updates a URL within a group.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls/418e0748-a9cf-480b-86d6-88b00bac00b9';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'desktop' => true,
            'mobile' => true,
            'css' => '.btn {visibility: none;}',
            'js' => 'dolores',
            'threshold' => 0.4,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls/418e0748-a9cf-480b-86d6-88b00bac00b9" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"desktop\": true,
    \"mobile\": true,
    \"css\": \".btn {visibility: none;}\",
    \"js\": \"dolores\",
    \"threshold\": 0.4
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls/418e0748-a9cf-480b-86d6-88b00bac00b9"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "desktop": true,
    "mobile": true,
    "css": ".btn {visibility: none;}",
    "js": "dolores",
    "threshold": 0.4
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls/418e0748-a9cf-480b-86d6-88b00bac00b9'
payload = {
    "desktop": true,
    "mobile": true,
    "css": ".btn {visibility: none;}",
    "js": "dolores",
    "threshold": 0.4
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "html_title": "Example Title",
        "url": "example.com/foobar",
        "last_crawled_at": "2025-01-01 13:37:42",
        "desktop": true,
        "mobile": true,
        "css": ".btn {visibility: none;}",
        "js": null,
        "threshold": null,
        "group": "023c282c-6513-420a-a36b-a654312ab229"
    },
    "meta": {
        "selected_urls_count": 1
    }
}
 

Request   

PUT api/v2/groups/{group_id}/urls/{url_id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

group_id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

url_id   string   

The ID of the URL in that Group. Example: 418e0748-a9cf-480b-86d6-88b00bac00b9

Body Parameters

desktop   boolean  optional  

Should a desktop screenshot be taken Example: true

Must be one of:
  • true
  • false
mobile   boolean  optional  

Should a mobile screenshot be taken Example: true

Must be one of:
  • true
  • false
css   string  optional  

CSS to be injected before the screenshot is taken Example: .btn {visibility: none;}

js   string  optional  

JavaScript to be injected before the screenshot is taken Example: dolores

threshold   numeric  optional  

Difference in percent of when this counts as a change detection Example: 0.4

Update All Urls In Group

requires authentication

Updates all URLs within a group.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'urls' => [
                [
                    'id' => '418e0748-a9cf-480b-86d6-88b00bac00b9',
                    'desktop' => true,
                    'mobile' => true,
                    'css' => null,
                    'js' => null,
                    'threshold' => 0.4,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"urls\": [
        {
            \"id\": \"418e0748-a9cf-480b-86d6-88b00bac00b9\",
            \"desktop\": true,
            \"mobile\": true,
            \"css\": null,
            \"js\": null,
            \"threshold\": 0.4
        }
    ]
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "urls": [
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "desktop": true,
            "mobile": true,
            "css": null,
            "js": null,
            "threshold": 0.4
        }
    ]
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/groups/023c282c-6513-420a-a36b-a654312ab229/urls'
payload = {
    "urls": [
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "desktop": true,
            "mobile": true,
            "css": null,
            "js": null,
            "threshold": 0.4
        }
    ]
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "message": "42 URLs in Group 023c282c-6513-420a-a36b-a654312ab229 changed"
}
 

Request   

PUT api/v2/groups/{group_id}/urls

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

group_id   string   

The ID of the Group. Example: 023c282c-6513-420a-a36b-a654312ab229

Body Parameters

urls   string[]  optional  

Array of URLs with settings

desktop   boolean  optional  

Should a desktop screenshot be taken Example: true

Must be one of:
  • true
  • false
mobile   boolean  optional  

Should a mobile screenshot be taken Example: true

Must be one of:
  • true
  • false
css   string  optional  

CSS to be injected before the screenshot is taken Example: .btn {visibility: none;}

js   string  optional  

JavaScript to be injected before the screenshot is taken

threshold   numeric  optional  

Difference in percent of when this counts as a change detection Example: 0.4

id   string   

The ID of the URL in that Group. Example: 418e0748-a9cf-480b-86d6-88b00bac00b9

Queue

This object represents a log of taking screenshots, comparing screenshots and their status.

List Queues

requires authentication

Returns a list of all Queues. The Queues are sorted by creation date, with the most recent Queues appearing first.

When filtering by batch or batches parameter, the response includes additional metadata:

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/queues';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'status' => 'done,failed',
            'groups' => '023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230',
            'batches' => '0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/queues?status=done%2Cfailed&groups=023c282c-6513-420a-a36b-a654312ab229%2C023c282c-6513-420a-a36b-a654312ab230&batches=0d5f8108-51f1-4961-939a-2d33c7145918%2C1d5f8108-51f1-4961-939a-2d33c7145918" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/queues"
);

const params = {
    "status": "done,failed",
    "groups": "023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230",
    "batches": "0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/queues'
params = {
  'status': 'done,failed',
  'groups': '023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230',
  'batches': '0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3",
            "url": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "batch": "0d5f8108-51f1-4961-939a-2d33c7145918",
            "group": "023c282c-6513-420a-a36b-a654312ab229",
            "device": "desktop",
            "status": "open",
            "error_msg": null,
            "sc_type": "pre",
            "css": null,
            "js": null,
            "monitoring": true,
            "url_link": "https://example.com",
            "html_title": "Example Title",
            "image_link": "https://images.webchangedetector.com/image.jpg",
            "created_at": "2024-08-08 13:37:42",
            "updated_at": "2024-08-08 13:37:42"
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/queues?page=1",
        "last": "http://api.webchangedetector.test/api/v2/queues?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/queues?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/queues",
        "per_page": 15,
        "to": 1,
        "total": 1,
        "status_counts": {
            "open": 15,
            "processing": 3,
            "done": 42,
            "failed": 2,
            "by_type": {
                "pre": {
                    "open": 5,
                    "processing": 1,
                    "done": 14,
                    "failed": 0
                },
                "post": {
                    "open": 5,
                    "processing": 1,
                    "done": 14,
                    "failed": 1
                },
                "comparison": {
                    "open": 5,
                    "processing": 1,
                    "done": 14,
                    "failed": 1
                }
            }
        },
        "status_counts_by_batch": {
            "0d5f8108-51f1-4961-939a-2d33c7145918": {
                "open": 10,
                "processing": 2,
                "done": 30,
                "failed": 1
            },
            "a2b3c4d5-e6f7-8901-2345-6789abcdef01": {
                "open": 5,
                "processing": 1,
                "done": 12,
                "failed": 1
            }
        }
    }
}
 

Request   

GET api/v2/queues

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

status   string  optional  

Comma separated list of status to filter for. Example: done,failed

groups   string  optional  

Comma separated list of Group UUIDs to filter for. Example: 023c282c-6513-420a-a36b-a654312ab229,023c282c-6513-420a-a36b-a654312ab230

batches   string  optional  

Comma separated list of Batch UUIDs to filter for. Example: 0d5f8108-51f1-4961-939a-2d33c7145918,1d5f8108-51f1-4961-939a-2d33c7145918

Get Queue

requires authentication

Retrieves a Queue object identfied by their ID

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/queues/3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/queues/3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/queues/3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/queues/3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3",
        "url": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "batch": "0d5f8108-51f1-4961-939a-2d33c7145918",
        "group": "023c282c-6513-420a-a36b-a654312ab229",
        "device": "desktop",
        "status": "open",
        "sc_type": "pre",
        "css": null,
        "js": null,
        "monitoring": true,
        "url_link": "https://example.com",
        "html_title": "Example Title",
        "image_link": "https://images.webchangedetector.com/image.jpg",
        "created_at": "2024-08-08 13:37:42",
        "updated_at": "2024-08-08 13:37:42"
    }
}
 

Request   

GET api/v2/queues/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Queue. Example: 3bf0cec1-e8ee-49ba-804e-0db5ed93a7e3

Screenshot

This object represents the actual screenshot and the location it's stored at.

List Screenshots

requires authentication

Returns a list of all Screenshots. The Screenshots are sorted by creation date, with the most recent Screenshots appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/screenshots';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/screenshots" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/screenshots"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/screenshots'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "958dce2c-8468-47d3-8bc2-7dc6bf0aadae",
            "queue": "8ea7b88d-b5c6-4fad-8e9d-1497a54d9266",
            "domain": "example.com",
            "url": "example.com/foobar",
            "link": "https://images.webchangedetector.com/example.jpg",
            "device": "desktop",
            "sc_type": "pre",
            "monitoring": true,
            "browser_console": {
                "text": "Failed to load resource: the server responded with a status of 404 ()",
                "type": "error",
                "location": {
                    "url": "https://example.com.com/favicon.ico"
                }
            }
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/screenshots?page=1",
        "last": "http://api.webchangedetector.test/api/v2/screenshots?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/screenshots?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/screenshots",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/screenshots

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Get Screenshot

requires authentication

Retrieves a Screenshot object identfied by their ID

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/screenshots/958dce2c-8468-47d3-8bc2-7dc6bf0aadae';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/screenshots/958dce2c-8468-47d3-8bc2-7dc6bf0aadae" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/screenshots/958dce2c-8468-47d3-8bc2-7dc6bf0aadae"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/screenshots/958dce2c-8468-47d3-8bc2-7dc6bf0aadae'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "958dce2c-8468-47d3-8bc2-7dc6bf0aadae",
        "queue": "8ea7b88d-b5c6-4fad-8e9d-1497a54d9266",
        "domain": "example.com",
        "url": "example.com/foobar",
        "link": "https://images.webchangedetector.com/example.jpg",
        "device": "desktop",
        "sc_type": "pre",
        "monitoring": true,
        "browser_console": {
            "text": "Failed to load resource: the server responded with a status of 404 ()",
            "type": "error",
            "location": {
                "url": "https://example.com.com/favicon.ico"
            }
        }
    }
}
 

Request   

GET api/v2/screenshots/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Screenshot. Example: 958dce2c-8468-47d3-8bc2-7dc6bf0aadae

Take Screenshot

requires authentication

Adds screenshots of URLs in the passed groups to the queue. The parameter sc_type indicates if pre-update screenshots are taken (pre) or post-update screenshots and comparisons are taken (post). When post-update screenshots are done, a comparison is automatically triggered.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/screenshots/take';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'group_ids' => '["023c282c-6513-420a-a36b-a654312ab229", "023c282c-6513-420a-a36b-a654312ab230"]',
            'sc_type' => 'pre',
            'source' => 'manual',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/screenshots/take" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"group_ids\": \"[\\\"023c282c-6513-420a-a36b-a654312ab229\\\", \\\"023c282c-6513-420a-a36b-a654312ab230\\\"]\",
    \"sc_type\": \"pre\",
    \"source\": \"manual\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/screenshots/take"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "group_ids": "[\"023c282c-6513-420a-a36b-a654312ab229\", \"023c282c-6513-420a-a36b-a654312ab230\"]",
    "sc_type": "pre",
    "source": "manual"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/screenshots/take'
payload = {
    "group_ids": "[\"023c282c-6513-420a-a36b-a654312ab229\", \"023c282c-6513-420a-a36b-a654312ab230\"]",
    "sc_type": "pre",
    "source": "manual"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200, Success):


{
    "batch": "0d5f8108-51f1-4961-939a-2d33c7145918",
    "amount_screenshots": 42,
    "groups": [
        "023c282c-6513-420a-a36b-a654312ab229",
        "023c282c-6513-420a-a36b-a654312ab230"
    ]
}
 

Example response (402, Not enough credits):


{
    "message": "Bummer, you used your credit already. Please upgrade your account to a bigger plan."
}
 

Request   

POST api/v2/screenshots/take

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

group_ids   string[]   

A list of Groups. Example: ["023c282c-6513-420a-a36b-a654312ab229", "023c282c-6513-420a-a36b-a654312ab230"]

sc_type   string  optional  

Screenshot phase. pre captures the baseline before changes; post captures after changes and triggers comparisons against the matching pre screenshots in the same Batch. Example: pre

Must be one of:
  • pre
  • post
source   string  optional  

Optional batch source tag for filtering / reporting. Allowed values: see Batch::SOURCE_ALL (e.g. manual, auto_update, monitoring). Example: manual

Must be one of:
  • manual
  • monitoring
  • auto_update

Subaccount

This object represents a Subaccount

Verify Invitation

requires authentication

Returns subaccount details for a valid invitation token, including the decrypted API token. Idempotent: can be called multiple times until the invitation is accepted or expires. Does NOT consume the token. Use POST /invitations/accept after the user has finished setting up their account to mark the invitation as consumed. This endpoint does not require authentication.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/invitations/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'invitation_token' => 'est',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/invitations/verify" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"invitation_token\": \"est\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/invitations/verify"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "invitation_token": "est"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/invitations/verify'
payload = {
    "invitation_token": "est"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "17482316-2398-4374-9f70-e0e3e2bf292a",
        "name_first": "Jane",
        "name_last": "Doe",
        "email": "mail@example.com",
        "api_token": "V82abQfqPA3hBXL9ZHfMAt94Ta23VUdYt691D7GO"
    }
}
 

Request   

POST api/v2/invitations/verify

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

invitation_token   string   

The invitation token from the email Example: est

Accept Invitation

requires authentication

Marks a subaccount invitation as accepted, consuming the token. Should be called by the webapp AFTER the local user account has been successfully created — calling this before is a self-DoS because the token is cleared and cannot be re-verified afterwards. This endpoint does not require authentication.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/invitations/accept';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'invitation_token' => 'et',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/invitations/accept" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"invitation_token\": \"et\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/invitations/accept"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "invitation_token": "et"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/invitations/accept'
payload = {
    "invitation_token": "et"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "message": "Invitation accepted"
}
 

Request   

POST api/v2/invitations/accept

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

invitation_token   string   

The invitation token from the email Example: et

List Subaccounts

requires authentication

Returns a list of all Subaccounts. The Subaccounts are sorted by creation date, with the most recent Subaccounts appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/subaccounts';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/subaccounts" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/subaccounts"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/subaccounts'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "17482316-2398-4374-9f70-e0e3e2bf292a",
            "name_first": "Jane",
            "name_last": "Doe",
            "email": "mail@example.com",
            "checks_done": 42,
            "checks_left": 1337,
            "timezone": "UTC",
            "is_subaccount": true
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/subaccounts?page=1",
        "last": "http://api.webchangedetector.test/api/v2/subaccounts?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/subaccounts?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/subaccounts",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/subaccounts

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Create Subaccount

requires authentication

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/subaccounts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name_first' => 'Hans',
            'name_last' => 'Hacker',
            'email' => 'mail@example.com',
            'limit_checks' => 1000.0,
            'plan_label' => 'Agency Starter',
            'can_create_subaccounts' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/subaccounts" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name_first\": \"Hans\",
    \"name_last\": \"Hacker\",
    \"email\": \"mail@example.com\",
    \"limit_checks\": 1000,
    \"plan_label\": \"Agency Starter\",
    \"can_create_subaccounts\": false
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/subaccounts"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name_first": "Hans",
    "name_last": "Hacker",
    "email": "mail@example.com",
    "limit_checks": 1000,
    "plan_label": "Agency Starter",
    "can_create_subaccounts": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/subaccounts'
payload = {
    "name_first": "Hans",
    "name_last": "Hacker",
    "email": "mail@example.com",
    "limit_checks": 1000,
    "plan_label": "Agency Starter",
    "can_create_subaccounts": false
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "17482316-2398-4374-9f70-e0e3e2bf292a",
        "name_first": "Jane",
        "name_last": "Doe",
        "email": "mail@example.com",
        "checks_done": 42,
        "checks_left": 1337,
        "timezone": "UTC",
        "api_token": "V82abQfqPA3hBXL9ZHfMAt94Ta23VUdYt691D7GO",
        "is_subaccount": true
    }
}
 

Request   

POST api/v2/subaccounts

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name_first   string   

First Name Example: Hans

name_last   string   

Last Name Example: Hacker

email   string   

Must be a valid email Example: mail@example.com

limit_checks   number   

Maximum number of checks per renewal period this subaccount may consume. Capped at the parent account's plan limit (not remaining quota). Must be at least 0. Example: 1000

plan_label   string  optional  

Optional display label shown in the subaccount UI (e.g. "Agency Starter"). No billing semantics — purely cosmetic. Must not be greater than 255 characters. Example: Agency Starter

can_create_subaccounts   boolean  optional  

Allow this subaccount to itself manage subaccounts (level-1 reseller). Defaults to false. Example: false

Get Subaccount

requires authentication

Retrieves a Subaccount object identfied by their ID

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "17482316-2398-4374-9f70-e0e3e2bf292a",
        "name_first": "Jane",
        "name_last": "Doe",
        "email": "mail@example.com",
        "checks_done": 42,
        "checks_left": 1337,
        "timezone": "UTC",
        "is_subaccount": true
    }
}
 

Request   

GET api/v2/subaccounts/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Subaccount. Example: 17482316-2398-4374-9f70-e0e3e2bf292a

Update Subaccount

requires authentication

Updates the specified Subaccount by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name_first' => 'Hans',
            'name_last' => 'Hacker',
            'limit_checks' => 1500.0,
            'plan_label' => 'Agency Pro',
            'can_create_subaccounts' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name_first\": \"Hans\",
    \"name_last\": \"Hacker\",
    \"limit_checks\": 1500,
    \"plan_label\": \"Agency Pro\",
    \"can_create_subaccounts\": false
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name_first": "Hans",
    "name_last": "Hacker",
    "limit_checks": 1500,
    "plan_label": "Agency Pro",
    "can_create_subaccounts": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a'
payload = {
    "name_first": "Hans",
    "name_last": "Hacker",
    "limit_checks": 1500,
    "plan_label": "Agency Pro",
    "can_create_subaccounts": false
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "17482316-2398-4374-9f70-e0e3e2bf292a",
        "name_first": "Jane",
        "name_last": "Doe",
        "email": "mail@example.com",
        "checks_done": 42,
        "checks_left": 1337,
        "timezone": "UTC",
        "is_subaccount": true
    }
}
 

Request   

PUT api/v2/subaccounts/{id}

PATCH api/v2/subaccounts/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Subaccount. Example: 17482316-2398-4374-9f70-e0e3e2bf292a

Body Parameters

name_first   string   

First Name Example: Hans

name_last   string   

Last Name Example: Hacker

limit_checks   number  optional  

New per-renewal-period check quota. Capped at the parent account's plan limit. Email is immutable on update. Must be at least 0. Example: 1500

plan_label   string  optional  

Optional display label shown in the subaccount UI. No billing semantics. Must not be greater than 255 characters. Example: Agency Pro

can_create_subaccounts   boolean  optional  

Toggle subaccount-management permission for this user. Example: false

Delete Subaccount

requires authentication

Permanently deletes a Subaccount. This cannot be undone.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request DELETE \
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Example response (200):


{
    "message": "Subaccount deleted"
}
 

Request   

DELETE api/v2/subaccounts/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Subaccount. Example: 17482316-2398-4374-9f70-e0e3e2bf292a

Invite Subaccount

requires authentication

Sends an invitation email to a Subaccount user, allowing them to create their own webapp login. Works for both new and existing subaccounts.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a/invite';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a/invite" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a/invite"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/subaccounts/17482316-2398-4374-9f70-e0e3e2bf292a/invite'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers)
response.json()

Example response (200):


{
    "message": "Invitation sent"
}
 

Request   

POST api/v2/subaccounts/{id}/invite

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The UUID of the Subaccount. Example: 17482316-2398-4374-9f70-e0e3e2bf292a

Url

This object represents a single URL and specific settings

List Urls

requires authentication

Returns a list of all Urls. The Urls are sorted by creation date, with the most recent Urls appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/urls';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/urls" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/urls"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/urls'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
            "html_title": "Example Title",
            "url": "example.com/foobar",
            "last_crawled_at": "2025-01-01 13:37:42",
            "type": "types",
            "category": "Seiten",
            "website": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
            "groups": [
                "023c282c-6513-420a-a36b-a654312ab229",
                "023c282c-6513-420a-a36b-a654312ab230"
            ],
            "status_code": 200,
            "error_count": 0
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/urls?page=1",
        "last": "http://api.webchangedetector.test/api/v2/urls?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/urls?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/urls",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/urls

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Create Url

requires authentication

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/urls';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'url' => 'https://example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/urls" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"url\": \"https:\\/\\/example.com\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/urls"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "url": "https:\/\/example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/urls'
payload = {
    "url": "https:\/\/example.com"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "html_title": "Example Title",
        "url": "example.com/foobar",
        "last_crawled_at": "2025-01-01 13:37:42",
        "type": null,
        "category": null,
        "website": null,
        "groups": [],
        "status_code": 200,
        "error_count": 0
    }
}
 

Request   

POST api/v2/urls

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

url   string   

Must be a valid URL Example: https://example.com

Get Url

requires authentication

Retrieves a Url object identfied by their ID

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "html_title": "Example Title",
        "url": "example.com/foobar",
        "last_crawled_at": "2025-01-01 13:37:42",
        "type": "types",
        "category": "Seiten",
        "website": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
        "groups": [
            "023c282c-6513-420a-a36b-a654312ab229",
            "023c282c-6513-420a-a36b-a654312ab230"
        ],
        "status_code": 200,
        "error_count": 0
    }
}
 

Request   

GET api/v2/urls/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Url. Example: 418e0748-a9cf-480b-86d6-88b00bac00b9

Update Url

requires authentication

Updates the specified Url by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'url' => 'https://example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"url\": \"https:\\/\\/example.com\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "url": "https:\/\/example.com"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9'
payload = {
    "url": "https:\/\/example.com"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "418e0748-a9cf-480b-86d6-88b00bac00b9",
        "html_title": "Example Title",
        "url": "example.com/foobar",
        "last_crawled_at": "2025-01-01 13:37:42",
        "type": "types",
        "category": "Seiten",
        "website": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
        "status_code": 200,
        "error_count": 0,
        "groups": [
            "023c282c-6513-420a-a36b-a654312ab229",
            "023c282c-6513-420a-a36b-a654312ab230"
        ]
    }
}
 

Request   

PUT api/v2/urls/{id}

PATCH api/v2/urls/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Url. Example: 418e0748-a9cf-480b-86d6-88b00bac00b9

Body Parameters

url   string   

Must be a valid URL Example: https://example.com

Delete Url

requires authentication

Permanently deletes a Url. This cannot be undone.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request DELETE \
    "https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/urls/418e0748-a9cf-480b-86d6-88b00bac00b9'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Example response (200):


{
    "message": "URL deleted"
}
 

Request   

DELETE api/v2/urls/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Url. Example: 418e0748-a9cf-480b-86d6-88b00bac00b9

Add From Sitemap

requires authentication

Adds all the URLs found in a sitemap for a given domain.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/urls/add-from-sitemap';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'domain' => 'example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/urls/add-from-sitemap" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"domain\": \"example.com\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/urls/add-from-sitemap"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "domain": "example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/urls/add-from-sitemap'
payload = {
    "domain": "example.com"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "message": "Sitemap parsing started."
}
 

Request   

POST api/v2/urls/add-from-sitemap

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

domain   string   

The domain to parse the sitemap from Example: example.com

Webhook

This object contains the webhook calls a user can set to be notified for various events.

List Webhooks

requires authentication

Returns a list of all Webhooks. The Webhooks are sorted by creation date, with the most recent Webhooks appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/webhooks';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'event' => 'comparison_status_new',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/webhooks?event=comparison_status_new" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/webhooks"
);

const params = {
    "event": "comparison_status_new",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/webhooks'
params = {
  'event': 'comparison_status_new',
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "d86e9245-3524-4f8d-b5d9-e4a472136d27",
            "event": "comparison_status_new",
            "url": "https://example.com"
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/webhooks?page=1",
        "last": "http://api.webchangedetector.test/api/v2/webhooks?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/webhooks?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/webhooks",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/webhooks

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

event   string  optional  

Event of the Queue. Example: comparison_status_new

Must be one of:
  • batch_finished
  • comparison_status_new
  • queue_status_done
  • queue_status_failed

Create Webhook

requires authentication

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/webhooks';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'url' => 'https://example.com/webhooks/wcd',
            'event' => 'batch_finished',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/webhooks" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"url\": \"https:\\/\\/example.com\\/webhooks\\/wcd\",
    \"event\": \"batch_finished\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/webhooks"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "url": "https:\/\/example.com\/webhooks\/wcd",
    "event": "batch_finished"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/webhooks'
payload = {
    "url": "https:\/\/example.com\/webhooks\/wcd",
    "event": "batch_finished"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "d86e9245-3524-4f8d-b5d9-e4a472136d27",
        "event": "comparison_status_new",
        "url": "https://example.com"
    }
}
 

Request   

POST api/v2/webhooks

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

url   string   

HTTPS endpoint that receives the webhook POST. Requests are signed with HMAC-SHA256 in the Signature header — verify against your account webhook secret (GET /api/v2/account). Must be a valid URL. Example: https://example.com/webhooks/wcd

event   string   

Event to subscribe to. Allowed values for the v2 API: batch_finished (all Screenshots in a Batch complete), comparison_status_new (a change was detected), queue_status_done, queue_status_failed. See Webhook::EVENTS_ALL_API_V2. Example: batch_finished

Must be one of:
  • batch_finished
  • comparison_status_new
  • comparison_status_new_collection
  • comparison_summary
  • queue_status_done
  • queue_status_failed
  • wordpress_cron
  • wordpress_single_call

Get Webhook

requires authentication

Retrieves a Webhook object identfied by their ID

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "d86e9245-3524-4f8d-b5d9-e4a472136d27",
        "event": "comparison_status_new",
        "url": "https://example.com"
    }
}
 

Request   

GET api/v2/webhooks/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Webhook. Example: d86e9245-3524-4f8d-b5d9-e4a472136d27

Update Webhook

requires authentication

Updates the specified Webhook by setting the values of the parameters passed.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'url' => 'https://example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"url\": \"https:\\/\\/example.com\"
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "url": "https:\/\/example.com"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27'
payload = {
    "url": "https:\/\/example.com"
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "data": {
        "id": "d86e9245-3524-4f8d-b5d9-e4a472136d27",
        "event": "comparison_status_new",
        "url": "https://example.com"
    }
}
 

Request   

PUT api/v2/webhooks/{id}

PATCH api/v2/webhooks/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Webhook. Example: d86e9245-3524-4f8d-b5d9-e4a472136d27

Body Parameters

url   string   

Must be a valid URL Example: https://example.com

Delete Webhook

requires authentication

Permanently deletes a Webhook. This cannot be undone.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request DELETE \
    "https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/webhooks/d86e9245-3524-4f8d-b5d9-e4a472136d27'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('DELETE', url, headers=headers)
response.json()

Example response (200):


{
    "message": "{ID} deleted"
}
 

Request   

DELETE api/v2/webhooks/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Webhook. Example: d86e9245-3524-4f8d-b5d9-e4a472136d27

Website

This object represents Websites.

List Websites

requires authentication

Returns a list of all Website. The Websites are sorted by creation date, with the most recent Websites appearing first.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/websites';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/websites" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/websites"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/websites'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": [
        {
            "id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
            "manual_detection_group": "023c282c-6513-420a-a36b-a654312ab229",
            "auto_detection_group": "023c282c-6513-420a-a36b-a654312ab230",
            "domain": "example.com",
            "last_seen_at": "2025-07-14T16:19:30Z",
            "plugin_version": "4.0.3",
            "is_multisite_subsite": false,
            "parent_multisite_website": null,
            "sync_url_types": [
                {
                    "url_type_slug": "types",
                    "url_type_name": "Post Types",
                    "post_type_slug": "posts",
                    "post_type_name": "Posts"
                }
            ],
            "auto_update_settings": {
                "auto_update_checks_enabled": false,
                "auto_update_checks_from": "13:37",
                "auto_update_checks_to": "13:42",
                "auto_update_checks_monday": true,
                "auto_update_checks_tuesday": true,
                "auto_update_checks_wednesday": true,
                "auto_update_checks_thursday": true,
                "auto_update_checks_friday": true,
                "auto_update_checks_saturday": false,
                "auto_update_checks_sunday": false,
                "auto_update_checks_emails": "mail@example.com"
            },
            "allowances": {
                "change_detections_view": true,
                "manual_checks_view": true,
                "manual_checks_start": true,
                "manual_checks_settings": true,
                "manual_checks_urls": true,
                "monitoring_checks_view": true,
                "monitoring_checks_settings": true,
                "monitoring_checks_urls": true,
                "logs_view": true,
                "settings_view": true,
                "settings_add_urls": true,
                "settings_account_settings": true,
                "upgrade_account": true,
                "wizard_start": true,
                "only_frontpage": false
            }
        }
    ],
    "links": {
        "first": "http://api.webchangedetector.test/api/v2/websites?page=1",
        "last": "http://api.webchangedetector.test/api/v2/websites?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://api.webchangedetector.test/api/v2/websites?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://api.webchangedetector.test/api/v2/websites",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}
 

Request   

GET api/v2/websites

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Create Website

requires authentication

Creates a Website by setting the values of the parameters passed. Typically only done by the WordPress plugin.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/websites';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'domain' => 'example.com',
            'manual_detection_group_id' => '91e9c9fd-b86f-4269-a3f4-f02810167a6d',
            'auto_detection_group_id' => '91e9c9fd-b86f-4269-a3f4-f02810167a6d',
            'parent_multisite_website_id' => '91e9c9fd-b86f-4269-a3f4-f02810167a6d',
            'allowances' => [
                'change_detections_view' => true,
                'ai_rules_view' => true,
                'manual_checks_view' => true,
                'manual_checks_start' => true,
                'manual_checks_settings' => true,
                'manual_checks_urls' => true,
                'monitoring_checks_view' => true,
                'monitoring_checks_settings' => true,
                'monitoring_checks_urls' => true,
                'logs_view' => true,
                'settings_view' => true,
                'settings_add_urls' => true,
                'settings_account_settings' => true,
                'upgrade_account' => true,
                'wizard_start' => true,
                'only_frontpage' => false,
            ],
            'sync_url_types' => [
                [
                    'url_type_slug' => 'types',
                    'url_type_name' => 'Post Types',
                    'post_type_slug' => 'posts',
                    'post_type_name' => 'Posts',
                ],
                [
                    'url_type_slug' => 'types',
                    'url_type_name' => 'Post Types',
                    'post_type_slug' => 'pages',
                    'post_type_name' => 'Pages',
                ],
                [
                    'url_type_slug' => 'taxonomies',
                    'url_type_name' => 'Taxonomies',
                    'post_type_slug' => 'category',
                    'post_type_name' => 'Category',
                ],
            ],
            'auto_update_settings' => [
                'auto_update_checks_enabled' => false,
                'auto_update_checks_monday' => true,
                'auto_update_checks_tuesday' => true,
                'auto_update_checks_wednesday' => true,
                'auto_update_checks_thursday' => true,
                'auto_update_checks_friday' => true,
                'auto_update_checks_saturday' => false,
                'auto_update_checks_sunday' => false,
                'auto_update_checks_from' => null,
                'auto_update_checks_to' => null,
                'auto_update_checks_emails' => null,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request POST \
    "https://api.webchangedetector.com/api/v2/websites" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"domain\": \"example.com\",
    \"manual_detection_group_id\": \"91e9c9fd-b86f-4269-a3f4-f02810167a6d\",
    \"auto_detection_group_id\": \"91e9c9fd-b86f-4269-a3f4-f02810167a6d\",
    \"parent_multisite_website_id\": \"91e9c9fd-b86f-4269-a3f4-f02810167a6d\",
    \"allowances\": {
        \"change_detections_view\": true,
        \"ai_rules_view\": true,
        \"manual_checks_view\": true,
        \"manual_checks_start\": true,
        \"manual_checks_settings\": true,
        \"manual_checks_urls\": true,
        \"monitoring_checks_view\": true,
        \"monitoring_checks_settings\": true,
        \"monitoring_checks_urls\": true,
        \"logs_view\": true,
        \"settings_view\": true,
        \"settings_add_urls\": true,
        \"settings_account_settings\": true,
        \"upgrade_account\": true,
        \"wizard_start\": true,
        \"only_frontpage\": false
    },
    \"sync_url_types\": [
        {
            \"url_type_slug\": \"types\",
            \"url_type_name\": \"Post Types\",
            \"post_type_slug\": \"posts\",
            \"post_type_name\": \"Posts\"
        },
        {
            \"url_type_slug\": \"types\",
            \"url_type_name\": \"Post Types\",
            \"post_type_slug\": \"pages\",
            \"post_type_name\": \"Pages\"
        },
        {
            \"url_type_slug\": \"taxonomies\",
            \"url_type_name\": \"Taxonomies\",
            \"post_type_slug\": \"category\",
            \"post_type_name\": \"Category\"
        }
    ],
    \"auto_update_settings\": {
        \"auto_update_checks_enabled\": false,
        \"auto_update_checks_monday\": true,
        \"auto_update_checks_tuesday\": true,
        \"auto_update_checks_wednesday\": true,
        \"auto_update_checks_thursday\": true,
        \"auto_update_checks_friday\": true,
        \"auto_update_checks_saturday\": false,
        \"auto_update_checks_sunday\": false,
        \"auto_update_checks_from\": null,
        \"auto_update_checks_to\": null,
        \"auto_update_checks_emails\": null
    }
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/websites"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "domain": "example.com",
    "manual_detection_group_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "auto_detection_group_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "parent_multisite_website_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "allowances": {
        "change_detections_view": true,
        "ai_rules_view": true,
        "manual_checks_view": true,
        "manual_checks_start": true,
        "manual_checks_settings": true,
        "manual_checks_urls": true,
        "monitoring_checks_view": true,
        "monitoring_checks_settings": true,
        "monitoring_checks_urls": true,
        "logs_view": true,
        "settings_view": true,
        "settings_add_urls": true,
        "settings_account_settings": true,
        "upgrade_account": true,
        "wizard_start": true,
        "only_frontpage": false
    },
    "sync_url_types": [
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "posts",
            "post_type_name": "Posts"
        },
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "pages",
            "post_type_name": "Pages"
        },
        {
            "url_type_slug": "taxonomies",
            "url_type_name": "Taxonomies",
            "post_type_slug": "category",
            "post_type_name": "Category"
        }
    ],
    "auto_update_settings": {
        "auto_update_checks_enabled": false,
        "auto_update_checks_monday": true,
        "auto_update_checks_tuesday": true,
        "auto_update_checks_wednesday": true,
        "auto_update_checks_thursday": true,
        "auto_update_checks_friday": true,
        "auto_update_checks_saturday": false,
        "auto_update_checks_sunday": false,
        "auto_update_checks_from": null,
        "auto_update_checks_to": null,
        "auto_update_checks_emails": null
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/websites'
payload = {
    "domain": "example.com",
    "manual_detection_group_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "auto_detection_group_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "parent_multisite_website_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "allowances": {
        "change_detections_view": true,
        "ai_rules_view": true,
        "manual_checks_view": true,
        "manual_checks_start": true,
        "manual_checks_settings": true,
        "manual_checks_urls": true,
        "monitoring_checks_view": true,
        "monitoring_checks_settings": true,
        "monitoring_checks_urls": true,
        "logs_view": true,
        "settings_view": true,
        "settings_add_urls": true,
        "settings_account_settings": true,
        "upgrade_account": true,
        "wizard_start": true,
        "only_frontpage": false
    },
    "sync_url_types": [
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "posts",
            "post_type_name": "Posts"
        },
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "pages",
            "post_type_name": "Pages"
        },
        {
            "url_type_slug": "taxonomies",
            "url_type_name": "Taxonomies",
            "post_type_slug": "category",
            "post_type_name": "Category"
        }
    ],
    "auto_update_settings": {
        "auto_update_checks_enabled": false,
        "auto_update_checks_monday": true,
        "auto_update_checks_tuesday": true,
        "auto_update_checks_wednesday": true,
        "auto_update_checks_thursday": true,
        "auto_update_checks_friday": true,
        "auto_update_checks_saturday": false,
        "auto_update_checks_sunday": false,
        "auto_update_checks_from": null,
        "auto_update_checks_to": null,
        "auto_update_checks_emails": null
    }
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "domain": "example.com",
    "last_seen_at": "2025-07-14T16:19:30Z",
    "plugin_version": "4.0.3",
    "manual_detection_group": "023c282c-6513-420a-a36b-a654312ab229",
    "auto_detection_group": "023c282c-6513-420a-a36b-a654312ab230",
    "is_multisite_subsite": false,
    "parent_multisite_website": null,
    "allowances": {
        "change_detections_view": true,
        "manual_checks_view": true,
        "manual_checks_start": true,
        "manual_checks_settings": true,
        "manual_checks_urls": true,
        "monitoring_checks_view": true,
        "monitoring_checks_settings": true,
        "monitoring_checks_urls": true,
        "logs_view": true,
        "settings_view": true,
        "settings_add_urls": true,
        "settings_account_settings": true,
        "upgrade_account": true,
        "wizard_start": true,
        "only_frontpage": false
    },
    "sync_url_types": [
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "posts",
            "post_type_name": "Posts"
        },
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "pages",
            "post_type_name": "Pages"
        },
        {
            "url_type_slug": "taxonomies",
            "url_type_name": "Taxonomies",
            "post_type_slug": "category",
            "post_type_name": "Category"
        }
    ],
    "auto_update_settings": {
        "auto_update_checks_enabled": false,
        "auto_update_checks_from": "13:37",
        "auto_update_checks_to": "13:42",
        "auto_update_checks_monday": true,
        "auto_update_checks_tuesday": true,
        "auto_update_checks_wednesday": true,
        "auto_update_checks_thursday": true,
        "auto_update_checks_friday": true,
        "auto_update_checks_saturday": false,
        "auto_update_checks_sunday": false,
        "auto_update_checks_emails": "mail@example.com"
    }
}
 

Request   

POST api/v2/websites

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

domain   string   

The domain of the Website. Example: example.com

manual_detection_group_id   string   

The ID of the Manual Detection Group. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

auto_detection_group_id   string   

The ID of the Auto Detection Group. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

parent_multisite_website_id   string  optional  

UUID of the multisite main Website if this Website is a subsite. Must belong to the same user and not itself be a subsite. Subsites inherit Schedule from the main and may only set auto_update_checks_enabled. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

allowances   string[]  optional  

The allowances of the Website.

change_detections_view   boolean  optional  

Show the Change Detections page in the WP plugin. This field is required when allowances is present. Example: false

ai_rules_view   boolean  optional  

Show the AI Rules page in the WP plugin. This field is required when allowances is present. Example: false

manual_checks_view   boolean  optional  

Show the Manual Checks page. This field is required when allowances is present. Example: false

manual_checks_start   boolean  optional  

Allow user to start a manual checks workflow. This field is required when allowances is present. Example: false

manual_checks_settings   boolean  optional  

Allow user to edit the manual checks group settings. This field is required when allowances is present. Example: false

manual_checks_urls   boolean  optional  

Allow user to edit URL selection for manual checks. This field is required when allowances is present. Example: false

monitoring_checks_view   boolean  optional  

Show the Monitoring page. This field is required when allowances is present. Example: false

monitoring_checks_settings   boolean  optional  

Allow user to edit the monitoring group settings. This field is required when allowances is present. Example: false

monitoring_checks_urls   boolean  optional  

Allow user to edit URL selection for monitoring. This field is required when allowances is present. Example: false

logs_view   boolean  optional  

Show the Logs page. This field is required when allowances is present. Example: false

settings_view   boolean  optional  

Show the Settings page. This field is required when allowances is present. Example: false

settings_add_urls   boolean  optional  

Allow user to add URLs from the Settings page. This field is required when allowances is present. Example: false

settings_account_settings   boolean  optional  

Show account-level settings (token, email, upgrade link). This field is required when allowances is present. Example: false

upgrade_account   boolean  optional  

Show the upgrade-plan call-to-action. This field is required when allowances is present. Example: false

wizard_start   boolean  optional  

Show the onboarding wizard for new sites. This field is required when allowances is present. Example: false

only_frontpage   boolean  optional  

Restrict URL discovery to the homepage only (cheap-plan limit). This field is required when allowances is present. Example: false

sync_url_types   string[]  optional  

The sync url types of the Website.

url_type_slug   string  optional  

Internal slug for the URL type group (e.g. types, taxonomies, frontpage). This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: types

url_type_name   string  optional  

Human-readable label for the URL type group. This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: Post Types

post_type_slug   string  optional  

WordPress post-type or taxonomy slug. This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: posts

post_type_name   string  optional  

Human-readable label for the specific post type / taxonomy. This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: Posts

auto_update_settings   string[]  optional  

The auto update settings of the Website.

auto_update_checks_enabled   boolean  optional  

Run pre/post-update visual checks during WP auto-updates on this Website. Example: false

auto_update_checks_monday   boolean  optional  

Allow auto-updates on Mondays. Example: false

auto_update_checks_tuesday   boolean  optional  

Allow auto-updates on Tuesdays. Example: false

auto_update_checks_wednesday   boolean  optional  

Allow auto-updates on Wednesdays. Example: false

auto_update_checks_thursday   boolean  optional  

Allow auto-updates on Thursdays. Example: false

auto_update_checks_friday   boolean  optional  

Allow auto-updates on Fridays. Example: false

auto_update_checks_saturday   boolean  optional  

Allow auto-updates on Saturdays. Example: false

auto_update_checks_sunday   boolean  optional  

Allow auto-updates on Sundays. Example: false

auto_update_checks_emails   string[]  optional  

Must be a valid email address.

auto_update_checks_from   string  optional  

Start of the daily allowed time window in UTC (HH:mm). Must be a valid date in the format H:i. Example: 09:00

auto_update_checks_to   string  optional  

End of the daily allowed time window in UTC (HH:mm). Must be a valid date in the format H:i. Example: 17:00

Get Website

requires authentication

Retrieves a Website object identified by its ID.

On Multisite Subsites the returned auto_update_settings reflects the effective (inherited) values: Schedule fields (timeframe, weekdays, notification emails) come from the parent main Website, while auto_update_checks_enabled reflects this Subsite's own toggle. The is_multisite_subsite boolean and the nested parent_multisite_website object indicate the link.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request GET \
    --get "https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d'
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "data": {
        "id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
        "manual_detection_group": "023c282c-6513-420a-a36b-a654312ab229",
        "auto_detection_group": "023c282c-6513-420a-a36b-a654312ab230",
        "domain": "example.com",
        "last_seen_at": "2025-07-14T16:19:30Z",
        "plugin_version": "4.0.3",
        "is_multisite_subsite": false,
        "parent_multisite_website": null,
        "sync_url_types": [
            {
                "url_type_slug": "types",
                "url_type_name": "Post Types",
                "post_type_slug": "posts",
                "post_type_name": "Posts"
            }
        ],
        "auto_update_settings": {
            "auto_update_checks_enabled": false,
            "auto_update_checks_from": "13:37",
            "auto_update_checks_to": "13:42",
            "auto_update_checks_monday": true,
            "auto_update_checks_tuesday": true,
            "auto_update_checks_wednesday": true,
            "auto_update_checks_thursday": true,
            "auto_update_checks_friday": true,
            "auto_update_checks_saturday": false,
            "auto_update_checks_sunday": false,
            "auto_update_checks_emails": "mail@example.com"
        },
        "allowances": {
            "change_detections_view": true,
            "manual_checks_view": true,
            "manual_checks_start": true,
            "manual_checks_settings": true,
            "manual_checks_urls": true,
            "monitoring_checks_view": true,
            "monitoring_checks_settings": true,
            "monitoring_checks_urls": true,
            "logs_view": true,
            "settings_view": true,
            "settings_add_urls": true,
            "settings_account_settings": true,
            "upgrade_account": true,
            "wizard_start": true,
            "only_frontpage": false
        }
    }
}
 

Example response (200, Multisite Subsite (auto_update_settings reflect effective inherited values from the parent main Website)):


{
    "data": {
        "id": "b3a9d2e5-2c64-4a16-8f1c-9e3b21f8a4e7",
        "manual_detection_group": "d4d2af0b-7a35-4b99-aa46-5c4f2bb9f1a1",
        "auto_detection_group": "d4d2af0b-7a35-4b99-aa46-5c4f2bb9f1a2",
        "domain": "shop.example.com",
        "last_seen_at": "2025-07-14T16:19:30Z",
        "plugin_version": "4.0.3",
        "is_multisite_subsite": true,
        "parent_multisite_website": {
            "id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
            "domain": "example.com"
        },
        "sync_url_types": [
            {
                "url_type_slug": "types",
                "url_type_name": "Post Types",
                "post_type_slug": "posts",
                "post_type_name": "Posts"
            }
        ],
        "auto_update_settings": {
            "auto_update_checks_enabled": true,
            "auto_update_checks_from": "13:37",
            "auto_update_checks_to": "13:42",
            "auto_update_checks_monday": true,
            "auto_update_checks_tuesday": true,
            "auto_update_checks_wednesday": true,
            "auto_update_checks_thursday": true,
            "auto_update_checks_friday": true,
            "auto_update_checks_saturday": false,
            "auto_update_checks_sunday": false,
            "auto_update_checks_emails": "mail@example.com"
        },
        "allowances": {
            "change_detections_view": true,
            "manual_checks_view": true,
            "manual_checks_start": true,
            "manual_checks_settings": true,
            "manual_checks_urls": true,
            "monitoring_checks_view": true,
            "monitoring_checks_settings": true,
            "monitoring_checks_urls": true,
            "logs_view": true,
            "settings_view": true,
            "settings_add_urls": true,
            "settings_account_settings": true,
            "upgrade_account": true,
            "wizard_start": true,
            "only_frontpage": false
        }
    }
}
 

Request   

GET api/v2/websites/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Website. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

Update Website

requires authentication

Updates the specified Website by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

Example request:
$client = new \GuzzleHttp\Client();
$url = 'https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_TOKEN}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'parent_multisite_website_id' => '91e9c9fd-b86f-4269-a3f4-f02810167a6d',
            'allowances' => [
                'change_detections_view' => true,
                'ai_rules_view' => true,
                'manual_checks_view' => true,
                'manual_checks_start' => true,
                'manual_checks_settings' => true,
                'manual_checks_urls' => true,
                'monitoring_checks_view' => true,
                'monitoring_checks_settings' => true,
                'monitoring_checks_urls' => true,
                'logs_view' => true,
                'settings_view' => true,
                'settings_add_urls' => true,
                'settings_account_settings' => true,
                'upgrade_account' => true,
                'wizard_start' => true,
                'only_frontpage' => false,
            ],
            'sync_url_types' => [
                [
                    'url_type_slug' => 'types',
                    'url_type_name' => 'Post Types',
                    'post_type_slug' => 'posts',
                    'post_type_name' => 'Posts',
                ],
                [
                    'url_type_slug' => 'types',
                    'url_type_name' => 'Post Types',
                    'post_type_slug' => 'pages',
                    'post_type_name' => 'Pages',
                ],
                [
                    'url_type_slug' => 'taxonomies',
                    'url_type_name' => 'Taxonomies',
                    'post_type_slug' => 'category',
                    'post_type_name' => 'Category',
                ],
            ],
            'auto_update_settings' => [
                'auto_update_checks_enabled' => false,
                'auto_update_checks_monday' => true,
                'auto_update_checks_tuesday' => true,
                'auto_update_checks_wednesday' => true,
                'auto_update_checks_thursday' => true,
                'auto_update_checks_friday' => true,
                'auto_update_checks_saturday' => false,
                'auto_update_checks_sunday' => false,
                'auto_update_checks_from' => null,
                'auto_update_checks_to' => null,
                'auto_update_checks_emails' => null,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl --request PUT \
    "https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d" \
    --header "Authorization: Bearer {YOUR_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"parent_multisite_website_id\": \"91e9c9fd-b86f-4269-a3f4-f02810167a6d\",
    \"allowances\": {
        \"change_detections_view\": true,
        \"ai_rules_view\": true,
        \"manual_checks_view\": true,
        \"manual_checks_start\": true,
        \"manual_checks_settings\": true,
        \"manual_checks_urls\": true,
        \"monitoring_checks_view\": true,
        \"monitoring_checks_settings\": true,
        \"monitoring_checks_urls\": true,
        \"logs_view\": true,
        \"settings_view\": true,
        \"settings_add_urls\": true,
        \"settings_account_settings\": true,
        \"upgrade_account\": true,
        \"wizard_start\": true,
        \"only_frontpage\": false
    },
    \"sync_url_types\": [
        {
            \"url_type_slug\": \"types\",
            \"url_type_name\": \"Post Types\",
            \"post_type_slug\": \"posts\",
            \"post_type_name\": \"Posts\"
        },
        {
            \"url_type_slug\": \"types\",
            \"url_type_name\": \"Post Types\",
            \"post_type_slug\": \"pages\",
            \"post_type_name\": \"Pages\"
        },
        {
            \"url_type_slug\": \"taxonomies\",
            \"url_type_name\": \"Taxonomies\",
            \"post_type_slug\": \"category\",
            \"post_type_name\": \"Category\"
        }
    ],
    \"auto_update_settings\": {
        \"auto_update_checks_enabled\": false,
        \"auto_update_checks_monday\": true,
        \"auto_update_checks_tuesday\": true,
        \"auto_update_checks_wednesday\": true,
        \"auto_update_checks_thursday\": true,
        \"auto_update_checks_friday\": true,
        \"auto_update_checks_saturday\": false,
        \"auto_update_checks_sunday\": false,
        \"auto_update_checks_from\": null,
        \"auto_update_checks_to\": null,
        \"auto_update_checks_emails\": null
    }
}"
const url = new URL(
    "https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d"
);

const headers = {
    "Authorization": "Bearer {YOUR_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "parent_multisite_website_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "allowances": {
        "change_detections_view": true,
        "ai_rules_view": true,
        "manual_checks_view": true,
        "manual_checks_start": true,
        "manual_checks_settings": true,
        "manual_checks_urls": true,
        "monitoring_checks_view": true,
        "monitoring_checks_settings": true,
        "monitoring_checks_urls": true,
        "logs_view": true,
        "settings_view": true,
        "settings_add_urls": true,
        "settings_account_settings": true,
        "upgrade_account": true,
        "wizard_start": true,
        "only_frontpage": false
    },
    "sync_url_types": [
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "posts",
            "post_type_name": "Posts"
        },
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "pages",
            "post_type_name": "Pages"
        },
        {
            "url_type_slug": "taxonomies",
            "url_type_name": "Taxonomies",
            "post_type_slug": "category",
            "post_type_name": "Category"
        }
    ],
    "auto_update_settings": {
        "auto_update_checks_enabled": false,
        "auto_update_checks_monday": true,
        "auto_update_checks_tuesday": true,
        "auto_update_checks_wednesday": true,
        "auto_update_checks_thursday": true,
        "auto_update_checks_friday": true,
        "auto_update_checks_saturday": false,
        "auto_update_checks_sunday": false,
        "auto_update_checks_from": null,
        "auto_update_checks_to": null,
        "auto_update_checks_emails": null
    }
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
import requests
import json

url = 'https://api.webchangedetector.com/api/v2/websites/91e9c9fd-b86f-4269-a3f4-f02810167a6d'
payload = {
    "parent_multisite_website_id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "allowances": {
        "change_detections_view": true,
        "ai_rules_view": true,
        "manual_checks_view": true,
        "manual_checks_start": true,
        "manual_checks_settings": true,
        "manual_checks_urls": true,
        "monitoring_checks_view": true,
        "monitoring_checks_settings": true,
        "monitoring_checks_urls": true,
        "logs_view": true,
        "settings_view": true,
        "settings_add_urls": true,
        "settings_account_settings": true,
        "upgrade_account": true,
        "wizard_start": true,
        "only_frontpage": false
    },
    "sync_url_types": [
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "posts",
            "post_type_name": "Posts"
        },
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "pages",
            "post_type_name": "Pages"
        },
        {
            "url_type_slug": "taxonomies",
            "url_type_name": "Taxonomies",
            "post_type_slug": "category",
            "post_type_name": "Category"
        }
    ],
    "auto_update_settings": {
        "auto_update_checks_enabled": false,
        "auto_update_checks_monday": true,
        "auto_update_checks_tuesday": true,
        "auto_update_checks_wednesday": true,
        "auto_update_checks_thursday": true,
        "auto_update_checks_friday": true,
        "auto_update_checks_saturday": false,
        "auto_update_checks_sunday": false,
        "auto_update_checks_from": null,
        "auto_update_checks_to": null,
        "auto_update_checks_emails": null
    }
}
headers = {
  'Authorization': 'Bearer {YOUR_TOKEN}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PUT', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "id": "91e9c9fd-b86f-4269-a3f4-f02810167a6d",
    "domain": "example.com",
    "last_seen_at": "2025-07-14T16:19:30Z",
    "plugin_version": "4.0.3",
    "manual_detection_group": "023c282c-6513-420a-a36b-a654312ab229",
    "auto_detection_group": "023c282c-6513-420a-a36b-a654312ab230",
    "is_multisite_subsite": false,
    "parent_multisite_website": null,
    "allowances": {
        "change_detections_view": true,
        "manual_checks_view": true,
        "manual_checks_start": true,
        "manual_checks_settings": true,
        "manual_checks_urls": true,
        "monitoring_checks_view": true,
        "monitoring_checks_settings": true,
        "monitoring_checks_urls": true,
        "logs_view": true,
        "settings_view": true,
        "settings_add_urls": true,
        "settings_account_settings": true,
        "upgrade_account": true,
        "wizard_start": true,
        "only_frontpage": false
    },
    "sync_url_types": [
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "posts",
            "post_type_name": "Posts"
        },
        {
            "url_type_slug": "types",
            "url_type_name": "Post Types",
            "post_type_slug": "pages",
            "post_type_name": "Pages"
        }
    ],
    "auto_update_settings": {
        "auto_update_checks_enabled": false,
        "auto_update_checks_from": "13:37",
        "auto_update_checks_to": "13:42",
        "auto_update_checks_monday": true,
        "auto_update_checks_tuesday": true,
        "auto_update_checks_wednesday": true,
        "auto_update_checks_thursday": true,
        "auto_update_checks_friday": true,
        "auto_update_checks_saturday": false,
        "auto_update_checks_sunday": false,
        "auto_update_checks_emails": "mail@example.com"
    }
}
 

Request   

PUT api/v2/websites/{id}

PATCH api/v2/websites/{id}

Headers

Authorization      

Example: Bearer {YOUR_TOKEN}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the Website. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

Body Parameters

parent_multisite_website_id   string  optional  

UUID of the multisite main Website. Pass null to detach. On subsites only auto_update_checks_enabled may be set in auto_update_settings; Schedule fields return 422. Example: 91e9c9fd-b86f-4269-a3f4-f02810167a6d

allowances   string[]  optional  

The allowances of the Website.

change_detections_view   boolean  optional  

Show the Change Detections page in the WP plugin. This field is required when allowances is present. Example: false

ai_rules_view   boolean  optional  

Show the AI Rules page in the WP plugin. This field is required when allowances is present. Example: false

manual_checks_view   boolean  optional  

Show the Manual Checks page. This field is required when allowances is present. Example: false

manual_checks_start   boolean  optional  

Allow user to start a manual checks workflow. This field is required when allowances is present. Example: false

manual_checks_settings   boolean  optional  

Allow user to edit the manual checks group settings. This field is required when allowances is present. Example: false

manual_checks_urls   boolean  optional  

Allow user to edit URL selection for manual checks. This field is required when allowances is present. Example: false

monitoring_checks_view   boolean  optional  

Show the Monitoring page. This field is required when allowances is present. Example: false

monitoring_checks_settings   boolean  optional  

Allow user to edit the monitoring group settings. This field is required when allowances is present. Example: false

monitoring_checks_urls   boolean  optional  

Allow user to edit URL selection for monitoring. This field is required when allowances is present. Example: false

logs_view   boolean  optional  

Show the Logs page. This field is required when allowances is present. Example: false

settings_view   boolean  optional  

Show the Settings page. This field is required when allowances is present. Example: false

settings_add_urls   boolean  optional  

Allow user to add URLs from the Settings page. This field is required when allowances is present. Example: false

settings_account_settings   boolean  optional  

Show account-level settings (token, email, upgrade link). This field is required when allowances is present. Example: false

upgrade_account   boolean  optional  

Show the upgrade-plan call-to-action. This field is required when allowances is present. Example: false

wizard_start   boolean  optional  

Show the onboarding wizard for new sites. This field is required when allowances is present. Example: false

only_frontpage   boolean  optional  

Restrict URL discovery to the homepage only (cheap-plan limit). This field is required when allowances is present. Example: false

sync_url_types   string[]  optional  

The sync url types of the Website.

url_type_slug   string  optional  

Internal slug for the URL type group (e.g. types, taxonomies, frontpage). This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: types

url_type_name   string  optional  

Human-readable label for the URL type group. This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: Post Types

post_type_slug   string  optional  

WordPress post-type or taxonomy slug. This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: posts

post_type_name   string  optional  

Human-readable label for the specific post type / taxonomy. This field is required when sync_url_types is present. Must not be greater than 255 characters. Example: Posts

auto_update_settings   string[]  optional  

The auto update settings of the Website.

auto_update_checks_enabled   boolean  optional  

Run pre/post-update visual checks during WP auto-updates on this Website. Example: false

auto_update_checks_monday   boolean  optional  

Allow auto-updates on Mondays. Example: false

auto_update_checks_tuesday   boolean  optional  

Allow auto-updates on Tuesdays. Example: false

auto_update_checks_wednesday   boolean  optional  

Allow auto-updates on Wednesdays. Example: false

auto_update_checks_thursday   boolean  optional  

Allow auto-updates on Thursdays. Example: false

auto_update_checks_friday   boolean  optional  

Allow auto-updates on Fridays. Example: false

auto_update_checks_saturday   boolean  optional  

Allow auto-updates on Saturdays. Example: false

auto_update_checks_sunday   boolean  optional  

Allow auto-updates on Sundays. Example: false

auto_update_checks_emails   string[]  optional  

Must be a valid email address.

auto_update_checks_from   string  optional  

Start of the daily allowed time window in UTC (HH:mm). Must be a valid date in the format H:i. Example: 09:00

auto_update_checks_to   string  optional  

End of the daily allowed time window in UTC (HH:mm). Must be a valid date in the format H:i. Example: 17:00

domain   string  optional