# Website Uptime Checker (`kinaesthetic_millionaire/website-uptime-checker`) Actor

Monitors websites and APIs for availability, response time, SSL certificate expiry, and expected content, sending email or webhook alerts when something goes wrong.

- **URL**: https://apify.com/kinaesthetic\_millionaire/website-uptime-checker.md
- **Developed by:** [Parsedom Inc](https://apify.com/kinaesthetic_millionaire) (community)
- **Categories:** Automation, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Website Uptime Checker

**Website Uptime Checker** monitors any list of websites or APIs for availability, response time, SSL certificate expiry, and expected page content, and stores a structured result for every check. Give it a list of URLs and get back status codes, response times, and downtime alerts — no server or cron job to maintain.

<img src="https://i.postimg.cc/gj0vCLXZ/how-the-website-upchecker-actor-works-(1).png" alt="How the Website Uptime Checker Apify Actor works: provide input, the actor scrapes the site, get structured output" />

### ✨ Features

- **Check a single site or a large batch** — monitor one URL or hundreds in the same run
- **Bulk import from a file** — paste URLs, upload a `.txt`/`.csv` file of websites, or link to a remote hosted list (e.g. a raw GitHub file or a published Google Sheet CSV export)
- **Availability checks** — sends a request to each URL and classifies the response (online, redirect, client error, or server error/offline)
- **Response time tracking** — measures how long each check took, in milliseconds
- **SSL certificate monitoring** — warns before an HTTPS certificate expires
- **Keyword/content check** — verify a page contains expected text, catching "soft down" pages (e.g. maintenance screens) that still return HTTP 200
- **Email, Slack, Discord, and webhook alerts** — get notified through whichever platform your team already uses when a site goes down, recovers, responds slowly, or its SSL certificate is expiring
- **Downloadable CSV summary** — a plain `url,status` report (e.g. `https://example.com,OK`) saved alongside the detailed dataset, so you can skim results at a glance
- **Proxy support** — optionally route checks through a proxy, e.g. to monitor geo-restricted content

### 🔧 Input Configuration

#### What to put in the input

At minimum, add the website(s) you want to monitor under **Start URLs** — that's the only required field, and the defaults for everything else work well for most use cases. From there:

- Checking one homepage? Just add that single URL and run it.
- Checking a large batch? Paste multiple URLs, upload a `.txt`/`.csv` file of website addresses, or link to a remote hosted file (e.g. a raw GitHub file or a published Google Sheet CSV export) — one URL or domain per line.
- Want to be notified when something breaks? All notification fields are optional — pick whichever your team actually checks, none of them are required: **Alert email address** (plus **Postmark server token** and **Sender email**), **Slack webhook URL**, **Discord webhook URL**, and/or a generic **Alert webhook URL** for other tools (Zapier, Make, n8n). Leave all of them blank and the actor still checks every URL and stores full results — you just won't get pinged.
- Want a "the run is done" ping even when nothing is wrong? Turn on **Notify when the run completes** (also optional, off by default) to get a one-time summary like "8/10 sites online" through whichever channel(s) above you configured.
- Running this on a schedule? Raise **Consecutive failures before alert** so a single slow blip doesn't trigger a false alarm.
- Everything else (timeout, retries, concurrency, SSL warning window, keyword check) is an optional tuning knob — leave the defaults unless you have a specific reason to change them.

#### How to get a Slack, Discord, or email webhook/credential

None of this is required — skip this section entirely and the actor still checks every URL and stores full results. Set up only the channel(s) you actually want to be notified through.

##### Slack webhook URL

1. Go to [api.slack.com/apps](https://api.slack.com/apps) and create a new app ("From scratch"), picking the workspace you want alerts posted to.
2. Open **Incoming Webhooks** under Features, switch it on, then click **Add New Webhook to Workspace** and choose a channel.
3. Copy the generated URL (starts with `https://hooks.slack.com/services/...`) into **Slack webhook URL** in this actor's input.

- Official guide: [Sending messages using incoming webhooks](https://api.slack.com/incoming-webhooks)
- Video walkthrough: [How To Make an Incoming Webhook in Slack](https://www.youtube.com/watch?v=LOS_rRlCr7U)

##### Discord webhook URL

1. In your Discord server, open the target channel's **Edit Channel → Integrations → Webhooks**.
2. Click **New Webhook**, give it a name, then click **Copy Webhook URL**.
3. Paste that URL into **Discord webhook URL** in this actor's input.

- Official guide: [Intro to Webhooks](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks)
- Video walkthrough: [How to Create a Webhook on Your Discord Server](https://www.youtube.com/watch?v=xXPnUGrQpBY)

##### Email alerts (Postmark server token + sender email)

1. Sign up at [postmarkapp.com](https://postmarkapp.com) and create a server in your account.
2. Open that server's **API Tokens** tab and copy the **Server API Token** into **Postmark server token**.
3. Under **Sender Signatures**, add and verify the address you want alerts to come from, then use that same address as **Sender email**.

- Official guide: [Managing sender signatures](https://postmarkapp.com/developer/user-guide/managing-your-account/managing-sender-signatures)

##### Generic webhook URL (Zapier, Make, n8n, or your own endpoint)

Any URL that accepts a JSON `POST` request works here. In Zapier, Make, or n8n, create a scenario/zap that starts with a "Webhook" trigger step — each of those tools gives you a unique URL for that step, which you then paste into **Alert webhook URL**.

| Field                  | Type    | Required | Default                            | Description                                                                                                                                              |
| ---------------------- | ------- | -------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `startUrls`            | array   | ✅       | `[{ "url": "https://apify.com" }]` | Websites to check. A single URL is fine, or check many at once by pasting a list, uploading a `.txt`/`.csv` file, or linking to a remote hosted file     |
| `httpMethod`           | string  | —        | `HEAD`                             | `HEAD` (faster) or `GET` (loads full response body)                                                                                                      |
| `requestTimeoutSecs`   | integer | —        | `30`                               | How long to wait for a response before considering that attempt failed                                                                                   |
| `maxRequestRetries`    | integer | —        | `2`                                | Retries after a connection failure (DNS error, timeout, refused) before reporting a URL offline. A received status code like 404 or 500 is never retried |
| `minConcurrency`       | integer | —        | `1`                                | How many URLs to check in parallel at the start of the run                                                                                               |
| `maxConcurrency`       | integer | —        | `10`                               | The run ramps up parallel checks after a streak of successes, but never above this many at once                                                          |
| `keyword`              | string  | —        | —                                  | Optional text that must be present on the page, or the check is reported as offline. Forces a GET request                                                |
| `maxResponseTimeMs`    | integer | —        | `0`                                | If greater than 0, alert when an online site responds slower than this threshold                                                                         |
| `checkSsl`             | boolean | —        | `true`                             | For `https://` URLs, warn when the SSL certificate is about to expire                                                                                    |
| `sslExpiryWarningDays` | integer | —        | `14`                               | Alert when the SSL certificate expires within this many days                                                                                             |
| `failureThreshold`     | integer | —        | `1`                                | Consecutive failed checks (tracked across runs) required before a DOWN alert fires                                                                       |
| `email`                | string  | —        | —                                  | Not required. Email address to notify. Requires `postmarkToken` and `senderEmail` to actually send                                                       |
| `postmarkToken`        | string  | —        | —                                  | Not required. Postmark server token, used to send alert emails                                                                                           |
| `senderEmail`          | string  | —        | —                                  | Not required. The "From" address for alert emails (must be a Postmark-verified sender)                                                                   |
| `webhookUrl`           | string  | —        | —                                  | Not required. A generic webhook (Zapier, Make, n8n, custom endpoint) that receives a raw JSON POST for every alert                                       |
| `slackWebhookUrl`      | string  | —        | —                                  | Not required. A Slack incoming webhook URL to post alerts to a channel                                                                                   |
| `discordWebhookUrl`    | string  | —        | —                                  | Not required. A Discord channel webhook URL to post alerts to a channel                                                                                  |
| `notifyOnCompletion`   | boolean | —        | `false`                            | Not required. Sends a one-time run summary through the configured channel(s) above when the run finishes                                                 |
| `proxyConfiguration`   | object  | —        | `{ "useApifyProxy": false }`       | Optional proxy to route checks through                                                                                                                   |

**Supported URL types:**
Any absolute `http://` or `https://` URL — a homepage, a specific page, or an API endpoint you want to monitor.

### 📦 Output

The dataset schema defines two views: **Overview**, a compact table of URL, online status, status code, category, response time, and check timestamp; and **Full details**, which adds the HTTP method used, keyword check results, SSL certificate info, alerts sent, and any connection error.

Every run also saves a plain **CSV report** to the key-value store under the key `OUTPUT_REPORT` — a simple two-column `url,status` file, e.g.:

```csv
url,status
https://example.com,OK
https://example.com/missing-page,Not Found
https://example.com/checkout,Internal Server Error
https://unreachable-example.com,Offline
```

Find it on the **Output** tab, or download it directly from the run's key-value store.

**Sample dataset output:**

```json
[
    {
        "url": "https://apify.com/",
        "checkedAt": "2026-07-23T09:45:27.768Z",
        "isOnline": true,
        "statusCode": 200,
        "statusCategory": "OK",
        "statusMessage": "OK - website is online.",
        "responseTimeMs": 576,
        "httpMethod": "HEAD",
        "keyword": null,
        "keywordFound": null,
        "ssl": {
            "checked": true,
            "valid": true,
            "expiresAt": "2027-01-16T23:59:59.000Z",
            "daysRemaining": 177,
            "error": null
        },
        "error": null,
        "alertsSent": []
    },
    {
        "url": "https://apify.com/this-page-does-not-exist-xyz",
        "checkedAt": "2026-07-23T09:45:27.791Z",
        "isOnline": true,
        "statusCode": 404,
        "statusCategory": "CLIENT_ERROR",
        "statusMessage": "Not Found - website is online, but that page doesn't exist.",
        "responseTimeMs": 606,
        "httpMethod": "HEAD",
        "keyword": null,
        "keywordFound": null,
        "ssl": {
            "checked": true,
            "valid": true,
            "expiresAt": "2027-01-16T23:59:59.000Z",
            "daysRemaining": 177,
            "error": null
        },
        "error": null,
        "alertsSent": []
    }
]
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### 💡 Uses of This Data

- Getting paged the moment a production site or API goes down
- Tracking response time trends to catch performance regressions before they become outages
- Getting ahead of SSL certificate expiry instead of finding out from an angry user
- Verifying a status page or maintenance banner isn't stuck live on a "recovered" site
- Feeding uptime history into an internal dashboard or incident report

### 🚀 How to Use

1. [Sign up](https://apify.com/sign-up) for a free Apify account — includes **$5 monthly credit**.
2. Open the actor page and click **Try for free**.
3. Fill in the **Input** fields — at minimum, add the URLs you want to monitor under **Start URLs**.
4. Click **Start** and wait for the run to complete.
5. Download results from the **Output** tab in JSON, CSV, or Excel format.

You can also run this actor via the [Apify API](https://docs.apify.com/api/v2) or integrate it directly into your workflows using [Zapier](https://zapier.com/apps/apify), [Make](https://www.make.com/), or [n8n](https://n8n.io/). Schedule it on Apify to run every few minutes for continuous monitoring, and raise `failureThreshold` so a single slow response doesn't trigger a false alarm.

### ⚠️ Limitations & Known Issues

- **JavaScript-rendered content** — the actor checks the raw HTTP response, not a rendered page, so a keyword that only appears after client-side JavaScript runs won't be found.
- **Rate limiting** — checking the same site very frequently may trigger rate limits on the target server; space out scheduled runs accordingly.

### 📝 Notes

- **No notification field is mandatory** — `email`/`postmarkToken`/`senderEmail`, `webhookUrl`, `slackWebhookUrl`, `discordWebhookUrl`, and `notifyOnCompletion` are all optional. Leave every one of them blank and the actor still checks every URL and stores full results in the dataset and CSV report; you simply won't be notified anywhere.
- **Email alerts need all three email fields** — `email`, `postmarkToken`, and `senderEmail` must all be set together for emails to actually send.
- **Mix and match channels freely** — e.g. Slack for your team plus email for yourself; every configured channel gets every alert.

### 🤝 Support

Need help or have questions?

- Email us at <info@parsedom.com>
- Or visit [parsedom.com](https://parsedom.com)
- Visit our profile on Fiverr: [fiverr.com/s/rEmNqEb](https://www.fiverr.com/s/rEmNqEb)
- Apify public page: [apify.com/kinaesthetic\_millionaire](https://apify.com/kinaesthetic_millionaire)
- You can also contact us if you want to build a custom actor.

Ready to keep your sites online? Add your URLs and start monitoring! 🚀

# Actor input Schema

## `startUrls` (type: `array`):

Websites or APIs to check. Paste one or many, upload a .txt/.csv file, or link to a hosted list.

## `httpMethod` (type: `string`):

HEAD is faster. Switch to GET if a site rejects HEAD requests.

## `requestTimeoutSecs` (type: `integer`):

Max wait per request before that attempt is considered failed.

## `maxRequestRetries` (type: `integer`):

Retries connection failures only (DNS/timeout/refused) - never retries a real status code like 404 or 500.

## `minConcurrency` (type: `integer`):

URLs checked in parallel at the start of the run.

## `maxConcurrency` (type: `integer`):

Ramps up after a streak of clean results, but never above this.

## `keyword` (type: `string`):

If set, missing text = reported offline (catches maintenance pages that still return 200). Forces GET.

## `maxResponseTimeMs` (type: `integer`):

Alert when an online site is slower than this. 0 disables it.

## `checkSsl` (type: `boolean`):

Warn before an HTTPS certificate expires.

## `sslExpiryWarningDays` (type: `integer`):

How many days ahead of expiry to start warning.

## `failureThreshold` (type: `integer`):

Raise this on scheduled runs to ignore one-off blips.

## `email` (type: `string`):

Needs Postmark server token + Sender email below to actually send.

## `postmarkToken` (type: `string`):

From your Postmark account - used to send alert emails.

## `senderEmail` (type: `string`):

A Postmark-verified "From" address.

## `webhookUrl` (type: `string`):

Generic JSON webhook - Zapier, Make, n8n, or a custom endpoint.

## `slackWebhookUrl` (type: `string`):

A Slack incoming webhook URL for posting alerts to a channel.

## `discordWebhookUrl` (type: `string`):

A Discord channel webhook URL for posting alerts to a channel.

## `notifyOnCompletion` (type: `boolean`):

Send a one-time summary (e.g. "8/10 online") via the channels above when the run finishes.

## `proxyConfiguration` (type: `object`):

Not needed for most sites.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ],
  "httpMethod": "HEAD",
  "requestTimeoutSecs": 30,
  "maxRequestRetries": 2,
  "minConcurrency": 1,
  "maxConcurrency": 10,
  "maxResponseTimeMs": 0,
  "checkSsl": true,
  "sslExpiryWarningDays": 14,
  "failureThreshold": 1,
  "notifyOnCompletion": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `report` (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 = {
    "startUrls": [
        {
            "url": "https://apify.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kinaesthetic_millionaire/website-uptime-checker").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 = { "startUrls": [{ "url": "https://apify.com" }] }

# Run the Actor and wait for it to finish
run = client.actor("kinaesthetic_millionaire/website-uptime-checker").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 '{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ]
}' |
apify call kinaesthetic_millionaire/website-uptime-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kinaesthetic_millionaire/website-uptime-checker"
        }
    }
}

```

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/aAuWqCDxmZhCzhDoB/builds/przYvYL9cFuWxLvHH/openapi.json
