> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sitepulse.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Check Results

> Result object shapes per check tool

The `result` field on [Check](/api/resources#check) resources is tool-specific. Values are normalized JSON (enums become strings, nested objects are plain arrays).

## Status check

HTTP reachability check (`type: "status"`).

| Field            | Type      | Description                                                                                                                                                                              |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `up`             | boolean   | `true` when HTTP status is 2xx or 3xx                                                                                                                                                    |
| `code`           | integer   | Status code; `0` on connection failure                                                                                                                                                   |
| `url`            | string    | Requested URL                                                                                                                                                                            |
| `effective_url`  | string    | Final URL after redirects                                                                                                                                                                |
| `response_time`  | float     | Total time in milliseconds                                                                                                                                                               |
| `redirected`     | boolean   | Whether redirects occurred                                                                                                                                                               |
| `redirect_count` | integer   | Number of redirects                                                                                                                                                                      |
| `redirects`      | string\[] | Redirect chain; present only when redirects occurred                                                                                                                                     |
| `error`          | string    | Connection or validation failure message. Present only when the request could not complete (`code` is `0`) - an HTTP error status such as 500 is a completed request and has no `error`. |

### Example (up)

```json theme={null}
{
  "up": true,
  "code": 200,
  "url": "https://example.com",
  "effective_url": "https://example.com",
  "response_time": 142.37,
  "redirected": false,
  "redirect_count": 0
}
```

### Example (down - HTTP error status)

A 5xx response still completes, so there is no `error` field - only `up: false` and the status `code`.

```json theme={null}
{
  "up": false,
  "code": 500,
  "url": "https://example.com",
  "effective_url": "https://example.com",
  "response_time": 523.12,
  "redirected": false,
  "redirect_count": 0
}
```

### Example (down - connection failure)

When the request cannot complete, `code` is `0` and `error` describes the failure.

```json theme={null}
{
  "up": false,
  "code": 0,
  "url": "https://example.com",
  "effective_url": "https://example.com",
  "response_time": 2003.41,
  "redirected": false,
  "redirect_count": 0,
  "error": "cURL error 28: Operation timed out after 5000 milliseconds"
}
```

## SSL check

TLS certificate inspection on port 443 (`type: "ssl"`).

| Field             | Type           | Description                                                                                                                           |
| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `domain`          | string         | Domain checked                                                                                                                        |
| `ip`              | string         | Resolved IP address                                                                                                                   |
| `is_valid`        | boolean        | `true` only when the certificate is current, matches the hostname, and chains to a trusted root                                       |
| `failure_type`    | string \| null | Why validation failed: `expired`, `hostname_mismatch`, `untrusted_chain`, `no_certificate`, or `connection_failed`; `null` when valid |
| `failure_message` | string \| null | Human-readable failure reason; `null` when valid                                                                                      |
| `issuer`          | string         | Issuing CA organization                                                                                                               |
| `issued_to`       | string         | Certificate common name (CN)                                                                                                          |
| `valid_from`      | string \| null | Start datetime; `null` when no certificate was read                                                                                   |
| `valid_to`        | string \| null | Expiry datetime; `null` when no certificate was read                                                                                  |
| `days_left`       | integer        | Days until expiry (`0` when no certificate)                                                                                           |
| `subject`         | string         | Subject CN                                                                                                                            |
| `serial_number`   | string         | Certificate serial number                                                                                                             |
| `fingerprint`     | string         | Certificate hash                                                                                                                      |
| `verified`        | boolean        | Whether the chain verified against the system trust store                                                                             |
| `info`            | object \| null | Raw OpenSSL parse output (`null` when no certificate)                                                                                 |

<Note>
  `valid_from` and `valid_to` are certificate datetimes in `YYYY-MM-DD HH:MM:SS` form (no timezone offset), unlike the ISO 8601 timestamps on resource objects.
</Note>

### Example (valid)

```json theme={null}
{
  "domain": "example.com",
  "ip": "93.184.216.34",
  "is_valid": true,
  "failure_type": null,
  "failure_message": null,
  "issuer": "Let's Encrypt",
  "issued_to": "example.com",
  "valid_from": "2026-04-01 00:00:00",
  "valid_to": "2026-07-01 00:00:00",
  "days_left": 35,
  "subject": "example.com",
  "serial_number": "03A1B2C3D4E5F6...",
  "fingerprint": "a1b2c3d4",
  "verified": true,
  "info": { /* Raw OpenSSL data */ }
}
```

### Example (expired)

```json theme={null}
{
  "domain": "example.com",
  "ip": "93.184.216.34",
  "is_valid": false,
  "failure_type": "expired",
  "failure_message": "The SSL certificate has expired.",
  "issuer": "Let's Encrypt",
  "issued_to": "example.com",
  "valid_from": "2025-12-08 00:00:00",
  "valid_to": "2026-03-08 00:00:00",
  "days_left": -81,
  "subject": "example.com",
  "serial_number": "03A1B2C3D4E5F6...",
  "fingerprint": "a1b2c3d4",
  "verified": true,
  "info": { /* Raw OpenSSL data */ }
}
```

## DNS check

DNS records via Cloudflare DoH (`type: "dns"`).

| Field                   | Type           | Description                                                                      |
| ----------------------- | -------------- | -------------------------------------------------------------------------------- |
| `records`               | object         | Keys: record types (`A`, `AAAA`, `MX`, ...) with record arrays                   |
| `resolver_observations` | object         | Per-resolver lookup results used to detect inconsistencies between DNS resolvers |
| `is_cloudflare`         | boolean        | Domain uses Cloudflare DNS/proxy                                                 |
| `ip_enrichment`         | object         | Public IP enrichment keyed by IP address                                         |
| `hosting_provider`      | object \| null | Detected hosting provider from enriched IP data                                  |
| `reputation`            | object         | Domain and IP reputation details                                                 |

<Note>
  Record shapes vary by type. Each entry includes `host`, `ttl`, `type`, and type-specific fields such as `ip` for A/AAAA.
</Note>

### Example

```json theme={null}
{
  "records": {
    "A": [
      {
        "host": "example.com",
        "ttl": 300,
        "type": "A",
        "ip": "93.184.216.34"
      }
    ],
    "MX": [
      {
        "host": "example.com",
        "ttl": 3600,
        "type": "MX",
        "priority": 10,
        "target": "mail.example.com"
      }
    ]
  },
  "is_cloudflare": false,
  "ip_enrichment": {
    "93.184.216.34": {
      "ip": "93.184.216.34",
      "asn": 15133,
      "asn_name": "EDGECAST",
      "asn_org_name": "Edgecast Inc.",
      "country": "US",
      "country_name": "United States",
      "website": "https://www.edgecast.com/",
      "source": "cloudflare_radar"
    }
  },
  "hosting_provider": {
    "name": "Edgecast Inc.",
    "asn": 15133,
    "country": "US",
    "source": "cloudflare_radar"
  },
  "reputation": {
    "status": "clean",
    "flags": {
      "malware": false,
      "phishing": false
    },
    "risk_score": 0,
    "risk_types": [],
    "suspected_malware_family": null,
    "ip_reputation": {},
    "source": "cloudflare_intel"
  }
}
```

## Broken links check

Site crawl for failing links (`type: "broken-links"`).

| Field     | Type    | Description                                                    |
| --------- | ------- | -------------------------------------------------------------- |
| `found`   | integer | Count of broken links                                          |
| `crawled` | integer | Pages crawled                                                  |
| `urls`    | array   | Broken URL details                                             |
| `crawl`   | object  | Crawl metadata (finish reason, limits, duration, JS rendering) |

### URL object

Each item in the `urls` array contains exactly:

| Field    | Type    | Description                            |
| -------- | ------- | -------------------------------------- |
| `url`    | string  | The broken link URL                    |
| `source` | string  | Page where the link was found          |
| `status` | integer | HTTP status code returned for the link |

<Note>
  Only links whose status is **not** `200`, `301`, `302`, or `303` are counted as broken.
</Note>

### Example

```json theme={null}
{
  "found": 3,
  "crawled": 12,
  "urls": [
    {
      "url": "https://example.com/missing-page",
      "status": 404,
      "source": "https://example.com/blog"
    },
    {
      "url": "https://example.com/broken-image.jpg",
      "status": 404,
      "source": "https://example.com/about"
    }
  ]
}
```

<Info>
  Issue evaluation often uses `found` against configured thresholds.
</Info>

## Performance check

Lighthouse-based performance audit (`type: "performance"`).

| Field           | Type   | Description                   |
| --------------- | ------ | ----------------------------- |
| `response_time` | float  | Direct GET response time (ms) |
| `url`           | string | Audited URL                   |
| `speed_metrics` | object | Lighthouse output             |

### Speed metrics object

| Field               | Type            | Description                       |
| ------------------- | --------------- | --------------------------------- |
| `performance_score` | integer \| null | 0–100 score                       |
| `core_web_vitals`   | object          | Lab metrics (LCP, INP, CLS, etc.) |
| `real_user_metrics` | object          | CrUX page data (Google provider)  |
| `origin_metrics`    | object          | CrUX origin data                  |
| `opportunities`     | array           | Failed audits with savings hints  |

<Note>
  Each core web vital entry typically includes `value`, `display_value`, and `score`.
</Note>

### Example

```json theme={null}
{
  "response_time": 420.5,
  "url": "https://example.com",
  "speed_metrics": {
    "performance_score": 87,
    "core_web_vitals": {
      "lcp": {
        "value": 2400,
        "display_value": "2.4 s",
        "score": 0.92
      },
      "cls": {
        "value": 0.05,
        "display_value": "0.05",
        "score": 0.95
      }
    },
    "opportunities": [
      {
        "id": "render-blocking-resources",
        "title": "Eliminate render-blocking resources",
        "savings": "450 ms"
      }
    ]
  }
}
```

## Errors

When `status` is `failed`, the check may include an `error` field which can be:

* A simple error string
* A structured object with `message`, `code`, and `data` keys

Use `error` together with `result` to diagnose failures.

### Example

```json theme={null}
{
  "uuid": "...",
  "type": "ssl",
  "status": "failed",
  "result": null,
  "error": {
    "message": "Error fetching site SSL details",
    "code": 0,
    "data": "Connection timed out after 10 seconds"
  },
  "completed_at": "2026-05-28T14:30:00+00:00"
}
```

## Polling check runs

<Steps>
  <Step title="Queue checks">
    `POST /sites/{site}/checks` returns `202` with check records in `pending` status.
  </Step>

  <Step title="Poll for completion">
    Poll `GET /checks/{uuid}` until `status` is `completed` or `failed`.
  </Step>

  <Step title="Read results">
    Read `result` when `completed`.
  </Step>
</Steps>

<Tip>
  Status checks often complete synchronously. SSL, DNS, broken-links, and performance checks can take a little longer.
</Tip>

## Check status values

| Status      | Description                  |
| ----------- | ---------------------------- |
| `pending`   | Queued or currently running  |
| `completed` | Finished successfully        |
| `failed`    | Finished with error          |
| `skipped`   | Not run due to configuration |

## See also

* [Endpoints - Checks](/api/endpoints#checks)
* [Using check tools](/guide/checks)
