# SaaS Vendor Watch: Status Pages, Incidents, Changelog & Pricing (`signalloom/saas-vendor-watch`) Actor

Watch SaaS vendors' public status pages: current status, components, active and recent incidents with durations, maintenance. Type slack or github (100 built in) or a domain. Optional changelog and pricing page change tracking. Only-changes mode for alerts.

- **URL**: https://apify.com/signalloom/saas-vendor-watch.md
- **Developed by:** [Signalloom](https://apify.com/signalloom) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 vendor checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## SaaS Vendor Watch: Status Pages, Incidents, Changelog & Pricing

Type the SaaS tools you depend on (`slack`, `github`, `openai`, or any domain) and get one clean record per vendor:

- **current status** and every **component** with its status
- **active incidents** and **recent incidents**, each with impact, start and end time, **duration in minutes**, affected components, the latest update and a link
- **incident stats** for the last N days: count, by impact, total and longest incident minutes
- **scheduled maintenance** (upcoming and in progress), with the planned window
- optional: the vendor's **changelog / release notes** (an RSS/Atom feed when there is one) and its **pricing page** (plans and prices), with **what changed since the last run**
- **Only changes** mode for alerts: one record per new, resolved or escalated incident, status change, new maintenance, new changelog entry or pricing change

**100 popular vendors are built in**, so names just work: GitHub, Slack, OpenAI, Anthropic (Claude), Cloudflare, Notion, Zoom, Atlassian, Jira, Confluence, Trello, Zapier, Make, HubSpot, Shopify, Twilio / SendGrid, Vercel, Netlify, DigitalOcean, Supabase, MongoDB Atlas, Snowflake, New Relic, Sentry, Figma, Canva, Asana, monday.com, Linear, Dropbox, Box, 1Password, Xero, Gusto and more (full list below). For anything else, give a domain or the status page URL.

**Price: $0.002 per vendor checked, $0.003 per changelog or pricing page read, and $0.005 per change alert in Only-changes mode.** The prefilled example (5 vendors) finishes in about 5–10 seconds.

### Use this when…

- you run **IT or ops** and want one dashboard or daily report of the SaaS tools your company depends on: what is down right now, what broke this month and for how long
- you do **competitive intelligence** and want to know when a competitor ships something (changelog) or changes its plans or prices (pricing page)
- you are an **MSP** and report vendor uptime and incidents to clients each month
- you build **n8n, Zapier or Make** workflows: schedule it every 5–15 minutes in Only-changes mode and send each change record to Slack, Teams, email or a ticket

### How to use it

1. Add **vendors**, one per line: a built-in name (`slack`), a domain (`acme.com`) or a status page URL (`https://status.acme.com`).
2. Optional: **incident history (days)** (default 30), **max recent incidents** (default 10), **component list** on or off.
3. Optional: turn on **Watch changelog** and/or **Watch pricing page**. The tool finds the links on the vendor's homepage. If it can't, or you want a specific page, add it under **Changelog URLs** / **Pricing URLs** as `vendor | URL`, for example `github | https://github.blog/changelog/`.
4. For alerts: turn on **Only changes**, give the task a **Monitor ID**, and schedule it. The first run is a baseline: it reports only incidents that are ongoing right now. After that, each run outputs only what changed.

**Recipe: vendor outage alerts in Slack.** A saved task with your 10–30 vendors, Only changes on, Monitor ID `it-alerts`, scheduled every 10 minutes. Connect the dataset to Slack with Zapier, Make or n8n and post the `summary` field. A quiet run costs $0.002 per vendor and outputs nothing.

**Recipe: monthly MSP report.** Incident history 31 days, Only changes off, run on the 1st of each month. `incidentStats` gives incidents, minutes and the longest outage per vendor.

### Output

One record per vendor. Real records from a run of the prefilled input (build 0.1.3, 2026-11-13; long lists shortened):

```json
{
  "vendor": "GitHub",
  "vendorKey": "github",
  "input": "github",
  "matchedBy": "directory",
  "statusPageUrl": "https://www.githubstatus.com",
  "statusProvider": "statuspage",
  "status": "operational",
  "statusIndicator": "none",
  "statusDescription": "All Systems Operational",
  "componentsTotal": 12,
  "componentsNotOperational": [],
  "components": [
    { "name": "Git Operations", "group": null, "status": "operational" },
    { "name": "Webhooks", "group": null, "status": "operational" }
  ],
  "componentsTruncated": false,
  "activeIncidents": [],
  "recentIncidents": [
    {
      "id": "nwbjzl7nfrc2",
      "name": "Disruption with Email Delivery",
      "status": "resolved",
      "impact": "minor",
      "startedAt": "2026-11-12T19:36:45.556Z",
      "resolvedAt": "2026-11-12T21:43:56.551Z",
      "durationMinutes": 127,
      "ongoing": false,
      "affectedComponents": [],
      "lastUpdate": "This incident has been resolved. Thank you for your patience and understanding as we addressed this issue. A detailed root cause analysis will be shared as soon as it is available.",
      "lastUpdateAt": "2026-11-12T21:43:56.551Z",
      "updatesCount": 8,
      "scheduledFor": null,
      "scheduledUntil": null,
      "url": "https://stspg.io/lr8v4v8t7gs2"
    }
  ],
  "incidentStats": {
    "days": 30,
    "incidents": 34,
    "byImpact": { "minor": 20, "critical": 7, "major": 6, "none": 1 },
    "totalIncidentMinutes": 3297,
    "longestIncidentMinutes": 662,
    "lastIncidentAt": "2026-11-12T19:36:45.556Z",
    "historyAvailable": true
  },
  "maintenance": [],
  "robotsNote": "robots.txt Disallow: /api/; the documented public status API is used",
  "baseline": false,
  "changes": [],
  "changeCount": 0,
  "checkedAt": "2026-11-13T00:58:30.532Z"
}
```

Cloudflare in the same run (degraded; 69 of 475 components not operational), with an active incident and a scheduled maintenance:

```json
{
  "vendor": "Cloudflare",
  "status": "degraded",
  "statusDescription": "Partially Degraded Service",
  "componentsTotal": 475,
  "activeIncidents": [
    {
      "id": "9zxr2bkqoct7",
      "name": "Durable Objects increased error rates in North America",
      "status": "monitoring",
      "impact": "minor",
      "startedAt": "2026-11-12T22:39:40.553Z",
      "resolvedAt": null,
      "durationMinutes": 139,
      "ongoing": true,
      "affectedComponents": ["Durable Objects", "Developer Services - Durable Objects"],
      "lastUpdate": "Durable Objects saw an increased error rate in North American colos due to a sudden increase in traffic. Impact has subsided. We are now monitoring.",
      "url": "https://www.cloudflarestatus.com/incidents/9zxr2bkqoct7"
    }
  ],
  "maintenance": [
    {
      "id": "q4grj8hp2ifu",
      "name": "BOS (Boston) on 2026-11-13",
      "status": "scheduled",
      "impact": "maintenance",
      "durationMinutes": 360,
      "affectedComponents": ["Boston, United States - (BOS)", "North America - Boston, United States - (BOS)"],
      "scheduledFor": "2026-11-13T05:30:00.000Z",
      "scheduledUntil": "2026-11-13T11:30:00.000Z",
      "url": "https://www.cloudflarestatus.com/incidents/q4grj8hp2ifu"
    }
  ]
}
```

With **Watch changelog** and **Watch pricing page** on (real run, Linear; links found on its homepage):

```json
{
  "vendor": "Linear",
  "changelog": {
    "url": "https://linear.app/changelog",
    "foundBy": "homepage-link",
    "source": "feed",
    "feedUrl": "https://linear.app/rss/changelog.xml",
    "entriesFound": 20,
    "latestEntries": [
      { "title": "Bring your own key (BYOK)", "date": "2026-11-12T16:36:46.000Z", "url": "https://linear.app/changelog/2026-11-12-bring-your-own-key" },
      { "title": "Mobile Diffs", "date": "2026-11-05T17:49:55.000Z", "url": "https://linear.app/changelog/2026-11-04-mobile-diffs" }
    ]
  },
  "pricing": {
    "url": "https://linear.app/pricing",
    "foundBy": "homepage-link",
    "plans": ["Basic", "Business"],
    "prices": [
      { "plan": "Basic", "price": "$10 per user/month" },
      { "plan": "Business", "price": "$16 per user/month" }
    ],
    "textHash": "3a30b16d6fb74c1815b39a4161b0f5e366ccf3c7"
  }
}
```

In **Only changes** mode each change is its own record. A real record from the baseline run of an alert monitor (Notion had an ongoing incident at that moment):

```json
{
  "vendor": "Notion",
  "vendorKey": "notion",
  "statusPageUrl": "https://www.notion-status.com",
  "currentStatus": "degraded",
  "changeType": "incident_new",
  "atBaseline": true,
  "incident": {
    "id": "01M78NX55B86FBTY90PH64KV7R",
    "name": "Issues with outlook connections",
    "status": "investigating",
    "impact": "minor",
    "startedAt": "2026-11-12T20:06:39Z",
    "durationMinutes": 287,
    "ongoing": true,
    "url": "https://www.notion-status.com/incidents/01M78NX55B86FBTY90PH64KV7R"
  },
  "summary": "Notion: new incident [minor]: Issues with outlook connections",
  "monitorId": "apify-alerts",
  "detectedAt": "2026-11-13T00:53:57.050Z"
}
```

Change types: `incident_new`, `incident_resolved`, `incident_impact_changed`, `status_changed`, `maintenance_scheduled`, `changelog_entry`, `pricing_changed` (with `pricesAdded`, `pricesRemoved`, `textAdded`, `textRemoved`). Every change record has a one-line `summary` for chat messages.

A run summary (vendors read, errors, changes, seconds) is saved as `OUTPUT` in the run's key-value store.

### Built-in vendors (100)

1Password, Airtable, Akamai, Anthropic (Claude), Apify, Asana, Atlassian, Attio, Bitbucket, Box, Brevo, Brex, BrowserStack, Calendly, Canva, CircleCI, ClickUp, Cloudflare, Cloudinary, CockroachDB, Cohere, Coinbase, Confluence, Confluent, Contentful, DigitalOcean, Discord, Docker, Dropbox, Duo, Elastic, ElevenLabs, Figma, Fly.io, Front, GitBook, GitHub, Gong, Grafana, Grammarly, Groq, Gusto, HashiCorp, Help Scout, Honeycomb, Hotjar, HubSpot, Hugging Face, Intercom, Jira, Klaviyo, LaunchDarkly, Linear, Linode, LogRocket, Loom, MailerLite, Mailgun, Make, Miro, Mixpanel, monday.com, MongoDB Atlas, Netlify, New Relic, Notion, npm, OpenAI, Perplexity, Pinecone, Plaid, PlanetScale, Postman, Reddit, Render, Retool, Rippling, Sanity, Segment, Sentry, Shopify, Slack, Smartsheet, Snowflake, Square, Squarespace, Supabase, SurveyMonkey, TeamViewer, Trello, Twilio (incl. SendGrid), Typeform, Upstash, Vercel, Vimeo, Webflow, Wix, Xero, Zapier, Zoom.

Every entry was checked live on 2026-11-12 (all 100 answered).

### Supported status pages

| Status page type | What you get |
|---|---|
| Atlassian Statuspage (most vendors) | status, components, active and last ~50 incidents, maintenance |
| incident.io pages with the Statuspage-compatible JSON | status, components, active and last ~25 incidents |
| Slack Status API | status, active incidents and history (Slack publishes no component list) |
| Better Stack | status, resources with availability, the 5 most recent reports |
| Instatus | status and components only (no incident history) |
| incident.io widget only | ongoing incidents only |

### Limitations

- **Not every vendor has a readable status page.** Some use custom pages with no public feed (for example Stripe, GitLab, Heroku, PagerDuty, Zendesk, Datadog, Auth0, Salesforce, Okta, PayPal). For those the record says so with an error, and you are not charged for the vendor.
- **Incident history is what the vendor publishes**: about the last 50 incidents on Statuspage, 25 on incident.io, 5 on Better Stack. Long windows on busy vendors can be cut off. `incidentStats` counts what is visible. It is not an SLA or uptime measurement.
- **Durations** run from the incident's start to its resolution as the vendor reports them. Ongoing incidents show time so far.
- **Pricing pages**: prices loaded by JavaScript after the page opens, or "contact sales" plans, can't be read. The record then has a note. Price matching is pattern-based ("$10 per user/month"), so check `priceContext` before acting on a change. Text changes on busy marketing pages can be cosmetic.
- **Changelog** discovery uses the homepage's links. When the homepage blocks automated clients (for example openai.com), or has no changelog link, add the URL yourself.
- **Websites protected by bot checks are never bypassed.** The page is skipped and the record says why.
- Unknown names are tried as `<name>.com`. Give the domain or status URL to be sure.

### Data sources and how they are used (legitimacy review)

- **Public sources only, no login.** Vendors' public status pages, homepages, changelog and pricing pages. No accounts, keys, cookies, proxies or browsers.
- **Status pages through their documented public APIs:**
  - Atlassian Statuspage pages publish a JSON API for programmatic access (append `/api` to any Statuspage URL to see its docs). The tool reads `/api/v2/summary.json` and `/api/v2/incidents.json`.
  - Atlassian-hosted pages carry `Disallow: /api/` in robots.txt. That line keeps search crawlers out; it does not restrict the documented API. Atlassian's Acceptable Use Policy allows access through its "publicly supported interfaces" and limits automated load to what a person with a browser could send. So the tool uses the documented API, makes 2 requests per vendor per run, and says so in `robotsNote`.
  - The Slack Status API is documented by Slack (api.slack.com/docs/slack-status).
  - incident.io and Better Stack pages have no robots.txt restrictions on these paths.
- **robots.txt is obeyed for every web page** (homepages, changelog, pricing and feeds), on every redirect. An unreadable robots.txt counts as "disallowed". Crawl-delay is honoured, and sites asking for more than 10 seconds are skipped.
- **Polite:**
  - at least 0.7 seconds between requests to the same host, at most 4 vendors at a time
  - retries with backoff on errors
  - an honest client name (`saas-vendor-watch/0.1, Apify Actor`)
- **No personal data.** Records hold company status information, incident notices and public product and pricing text. Status page contact emails are not copied.
- **Read-only.** The tool never subscribes, signs up, submits forms or takes any action on an account.
- Status, incident, changelog and pricing texts belong to their vendors. The tool reports short facts and links back to the source.

### Questions and issues

Open an issue on this tool's page: https://apify.com/signalloom/saas-vendor-watch. Requests to add a vendor to the built-in list are welcome.

# Actor input Schema

## `vendors` (type: `array`):

One per line: a name from the built-in list of 100 (e.g. slack, github, openai, notion, zoom), a company domain (acme.com) or a status page URL (https://status.acme.com). For other names the tool tries status.<name>.com and the status link on the homepage.

## `incidentDays` (type: `integer`):

Recent incidents and incident stats cover this many days back. Status pages publish about their last 50 incidents, so long windows are limited by that.

## `maxIncidents` (type: `integer`):

How many resolved incidents to list per vendor, newest first. Active incidents are always listed. The stats count all incidents in the window.

## `includeComponents` (type: `boolean`):

List every component (service) with its status. Components that are not operational are always listed in componentsNotOperational.

## `maxComponents` (type: `integer`):

Cap on the component list (Cloudflare alone has about 480 data-center components).

## `includeMaintenance` (type: `boolean`):

List upcoming and in-progress scheduled maintenance.

## `watchChangelog` (type: `boolean`):

Find each vendor's changelog link on its homepage (or use Changelog URLs) and report new entries since the last run. Uses an RSS/Atom feed when the page links one.

## `changelogUrls` (type: `array`):

Optional. One per line, either 'vendor | URL' (e.g. 'github | https://github.blog/changelog/') or a bare URL matched to a vendor by domain. A URL here turns on changelog watching for that vendor.

## `watchPricing` (type: `boolean`):

Find each vendor's pricing link on its homepage (or use Pricing URLs) and report price and text changes since the last run. Pages that load prices with JavaScript can't be read; the record says so.

## `pricingUrls` (type: `array`):

Optional. One per line, 'vendor | URL' or a bare URL matched to a vendor by domain. A URL here turns on pricing watching for that vendor.

## `onlyChanges` (type: `boolean`):

Output one record per change since the last run with the same Monitor ID: new, resolved or escalated incidents, status changes, new maintenance, new changelog entries, pricing changes. The first run is a baseline and reports only incidents ongoing right now. For scheduled runs and n8n / Zapier / Make alerts.

## `monitorId` (type: `string`):

Name for the saved state used to detect changes. Use a different ID for each saved task or schedule.

## `maxRunSeconds` (type: `integer`):

Stop starting new vendors after this many seconds; vendors not reached are listed with an error.

## Actor input object example

```json
{
  "vendors": [
    "github",
    "slack",
    "openai",
    "cloudflare",
    "notion"
  ],
  "incidentDays": 30,
  "maxIncidents": 10,
  "includeComponents": true,
  "maxComponents": 50,
  "includeMaintenance": true,
  "watchChangelog": false,
  "watchPricing": false,
  "onlyChanges": false,
  "monitorId": "default",
  "maxRunSeconds": 240
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "vendors": [
        "github",
        "slack",
        "openai",
        "cloudflare",
        "notion"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalloom/saas-vendor-watch").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "vendors": [
        "github",
        "slack",
        "openai",
        "cloudflare",
        "notion",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("signalloom/saas-vendor-watch").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "vendors": [
    "github",
    "slack",
    "openai",
    "cloudflare",
    "notion"
  ]
}' |
apify call signalloom/saas-vendor-watch --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,signalloom/saas-vendor-watch"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/b5ASHEdbWYRkSgLcI/builds/xAc6ZPxtWQyeHbOr9/openapi.json
