# Site Health Suite — One Graded Audit, Six Checks (`alaudinburki/site-health-suite`) Actor

One letter-graded audit combining SSL, security headers, uptime, broken links, structured data and subdomain takeover risk — with a prioritized, plain-English fix list instead of six separate scanner reports. Built for agencies who need a deliverable, not a data dump.

- **URL**: https://apify.com/alaudinburki/site-health-suite.md
- **Developed by:** [alaudin burki](https://apify.com/alaudinburki) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

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?

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

## Site Health Suite — One Grade, Six Checks, No Faked Score

Most "website audit" tools run one check and call it a grade. This runs six —
SSL, security headers, uptime, broken links, structured data, and subdomain
takeover exposure — and combines them into a single letter grade that's
honest about what it couldn't check.

**The one design decision that matters:** if a check can't run (a timeout, a
blocked probe), that check contributes **nothing** to the score — the other
checks are re-weighted to fill the gap. A site that's unreachable for SSL
inspection doesn't silently get graded as if SSL were fine, and it doesn't
get punished for a check that never completed either.

### The six checks and their weights

| Check | Weight | What it catches |
|---|---:|---|
| Subdomain takeover | 25 | The one *active exploitable risk* in this list — weighted highest on purpose |
| SSL | 20 | Certificate validity, expiry, chain |
| Uptime | 20 | Is it actually up right now |
| Broken links | 15 | Dead internal/external links |
| Security headers | 12 | HSTS, CSP, X-Frame-Options, and the rest |
| Structured data | 8 | JSON-LD presence — an SEO signal, not a security one |

A subdomain takeover risk scores worse than 100% broken links, by design — one
is a live exploitable hole, the other is a maintenance issue.

### Input

```json
{ "sites": ["example.com"], "maxSubdomainsToCheck": 50 }
```

### Sample output

```json
{
  "site": "example.com",
  "overallScore": 95,
  "grade": "A",
  "checks": {
    "ssl": { "score": 100, "status": "valid", "expiresInDays": 74 },
    "securityHeaders": { "score": 83, "missing": ["Content-Security-Policy"] },
    "uptime": { "score": 100, "status": "up" },
    "brokenLinks": { "score": 100, "checked": 42, "broken": 0 },
    "structuredData": { "score": 0, "found": false },
    "subdomainTakeover": { "score": 100, "claimable": 0, "suspicious": 0 }
  },
  "fixList": [
    { "priority": "low", "issue": "No structured data (JSON-LD) found", "fix": "Add Organization/WebSite schema markup for richer search results." }
  ]
}
```

### The fix list

Every run returns a priority-sorted, plain-English fix list — not a raw dump
of every check's internals. A buyer wants "here's what to fix, in order,"
not six separate reports to reconcile themselves.

### Typical uses

- **Agency deliverable** — one grade + a fix list is a paragraph you can put
  in a client report, not a data table they have to interpret.
- **Pre-launch checklist** — run before shipping a redesign or migration.
- **Vendor/acquisition due diligence** — a fast read on a site's technical hygiene.

### Pricing

**$5.00 / 1,000 sites checked** (`$0.005` per result) — priced above the
single-check actors in this portfolio because a row here replaces six
separate audits, not one.

### ⚠️ Read before you act

- **Uptime and broken-link checks reflect one moment in time.** Re-run
  periodically for a trend, not a single snapshot as a verdict.
- **Subdomain takeover uses the same passive technique as the standalone
  Subdomain Takeover Auditor** — certificate transparency + DNS-over-HTTPS +
  a public fingerprint database. No scanning, no login.
- **A missing check (timeout, blocked probe) never fakes a score** — it's
  excluded and the grade is renormalized over what actually ran. Check the
  per-check `status` field to see what that run actually measured.

### FAQ

- **Why is subdomain takeover weighted highest?** It's the only check on this
  list that represents an *active, exploitable* risk right now — the others
  are hygiene or performance signals.
- **Can I run just one check?** No — this actor's value is the combined
  grade. For a single check, use the dedicated actor (SSL Certificate
  Checker, Broken Link Checker, Subdomain Takeover Auditor, etc.).

### Related actors

- **Subdomain Takeover Auditor** — the takeover check alone, standalone.
- **SSL Certificate Checker** — the SSL check alone, standalone.
- **Broken Link Checker** — the broken-links check alone, standalone.
- **HTTP Header & Security Analyzer** — a deeper look at security headers alone.

# Actor input Schema

## `sites` (type: `array`):

Domains or URLs to audit. Each gets all six checks: SSL, security headers, uptime, broken links, structured data, and subdomain takeover risk.

## `maxLinksToCheck` (type: `integer`):

How many links from the homepage to check for broken-link scoring.

## `checkSubdomains` (type: `boolean`):

Enumerate subdomains from certificate transparency and check for dangling DNS. Adds time but is weighted heaviest in the grade — it is the one active exploitable risk on this list.

## `maxSubdomainsToCheck` (type: `integer`):

Cap on subdomains checked for takeover risk per site.

## `maxItems` (type: `integer`):

Hard cap on sites returned. You are never charged beyond this.

## Actor input object example

```json
{
  "sites": [
    "example.com"
  ],
  "maxLinksToCheck": 30,
  "checkSubdomains": true,
  "maxSubdomainsToCheck": 40,
  "maxItems": 200
}
```

# Actor output Schema

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

One graded row per site with a prioritized fix list.

## `qualityReport` (type: `string`):

Grade distribution and any check problems.

# 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 = {
    "sites": [
        "example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("alaudinburki/site-health-suite").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 = { "sites": ["example.com"] }

# Run the Actor and wait for it to finish
run = client.actor("alaudinburki/site-health-suite").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 '{
  "sites": [
    "example.com"
  ]
}' |
apify call alaudinburki/site-health-suite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,alaudinburki/site-health-suite"
        }
    }
}

```

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/ZTkn3iuttoM0Ae4vP/builds/glmSruqP1DRDhVPdX/openapi.json
