NewIntroducing semantic snapshotsPair every capture with structured DOM data →

For developers who depend on other people's APIs

Hear about a vendor's breaking change before your integration does

Watch the changelogs and deprecation pages of the services you integrate with, and get a webhook when their text changes.

The problem

Payment providers, shipping APIs and identity platforms announce breaking changes on a changelog page and in an email to whoever signed up three years ago. The first your team hears of it is the integration failing on the date the notice gave.

How domscout handles it

A monitor on each changelog or deprecation page compares the page's rendered text on every run, not its raw HTML, so a rebuild of the vendor's docs site is not a change and a new entry is. The webhook names the run and the two captures, and both are saved, so you can show exactly what was added. Route each monitor's webhook to the team that owns that integration.

Where it shows up

  • A changelog watch for every external API a service calls.
  • Deprecation pages for the SDKs and runtimes you build on.
  • Terms and pricing pages of the platforms you build on top of.

The request

POST /monitors. Monitors start at Pro: 10 monitors, checked as often as every 60 minutes. Business allows 100 every 15 minutes and Enterprise 500 every 5. Each run is billed as a capture; creating and managing a monitor is free.

cURL
curl -X POST https://api.domscout.io/monitors \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Payments API changelog",
    "targetUrl": "https://docs.example.com/changelog",
    "intervalMinutes": 1440,
    "notifyWebhookUrl": "https://your-app.example/hooks/domscout",
    "checkMarkdown": true,
    "checkLinks": false
  }'
Node.js
const response = await fetch("https://api.domscout.io/monitors", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY" },
  body: JSON.stringify({
    name: "Payments API changelog",
    targetUrl: "https://docs.example.com/changelog",
    intervalMinutes: 1440,
    notifyWebhookUrl: "https://your-app.example/hooks/domscout",
    checkMarkdown: true,
    checkLinks: false
  }),
});
console.log(await response.json());
Python
import requests

response = requests.post(
    "https://api.domscout.io/monitors",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "name": "Payments API changelog",
        "targetUrl": "https://docs.example.com/changelog",
        "intervalMinutes": 1440,
        "notifyWebhookUrl": "https://your-app.example/hooks/domscout",
        "checkMarkdown": True,
        "checkLinks": False
    },
)
print(response.json())
Go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	body, _ := json.Marshal(map[string]any{
		"name": "Payments API changelog",
		"targetUrl": "https://docs.example.com/changelog",
		"intervalMinutes": 1440,
		"notifyWebhookUrl": "https://your-app.example/hooks/domscout",
		"checkMarkdown": true,
		"checkLinks": false,
	})
	req, _ := http.NewRequest("POST", "https://api.domscout.io/monitors", bytes.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-api-key", "YOUR_API_KEY")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	raw, _ := io.ReadAll(res.Body)
	fmt.Println(string(raw))
}
PHP
<?php
$ch = curl_init('https://api.domscout.io/monitors');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'x-api-key: YOUR_API_KEY'],
    CURLOPT_POSTFIELDS => json_encode([
        'name' => 'Payments API changelog',
        'targetUrl' => 'https://docs.example.com/changelog',
        'intervalMinutes' => 1440,
        'notifyWebhookUrl' => 'https://your-app.example/hooks/domscout',
        'checkMarkdown' => true,
        'checkLinks' => false
    ]),
]);
$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
echo $response;
Ruby
require "json"
require "net/http"

response = Net::HTTP.post(
  URI("https://api.domscout.io/monitors"),
  {
    name: "Payments API changelog",
    targetUrl: "https://docs.example.com/changelog",
    intervalMinutes: 1440,
    notifyWebhookUrl: "https://your-app.example/hooks/domscout",
    checkMarkdown: true,
    checkLinks: false
  }.to_json,
  "Content-Type" => "application/json",
  "x-api-key" => "YOUR_API_KEY"
)
puts response.body
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Capture {
    public static void main(String[] args) throws Exception {
        String body = """
            {
                "name": "Payments API changelog",
                "targetUrl": "https://docs.example.com/changelog",
                "intervalMinutes": 1440,
                "notifyWebhookUrl": "https://your-app.example/hooks/domscout",
                "checkMarkdown": true,
                "checkLinks": false
            }
            """;
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.domscout.io/monitors"))
            .header("Content-Type", "application/json")
            .header("x-api-key", "YOUR_API_KEY")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
C#
using System.Net.Http.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var response = await client.PostAsJsonAsync("https://api.domscout.io/monitors", new {
    name = "Payments API changelog",
    targetUrl = "https://docs.example.com/changelog",
    intervalMinutes = 1440,
    notifyWebhookUrl = "https://your-app.example/hooks/domscout",
    checkMarkdown = true,
    checkLinks = false
});
Console.WriteLine(await response.Content.ReadAsStringAsync());

Go further

More in Monitoring and alerts: Website change monitoring · A feed for a site without RSS · Competitor price tracking · Minimum advertised price checks · New job posting alerts · Tender, grant and notice alerts · All use cases

Give your product a browser.

Get clean web content and visual proof into your workflow in minutes.