# POST /v1/page/lighthouse

Lighthouse scores and core web vitals for a single page.

**Credits:** 2 credits per call.

**Timeout:** 120s

## Parameters

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `url` | string | yes | — | Absolute http(s) page URL to audit. Required, max 2048 chars. |
| `device` | string | no | "mobile" | One of: mobile, desktop. Optional, default "mobile". |

## Request

```http
POST /v1/page/lighthouse HTTP/1.1
Authorization: Bearer sof_live_your_key_here
Content-Type: application/json

{
  "url": "https://example.com/",
  "device": "mobile"
}
```

## Response

Wrapped in the standard envelope (id, object, created_at, elapsed_ms, cache, credits) -- documented once on The Contract. The body below is a real envelope with this endpoint's `data` shape; values vary per request, and a `…` marks an array cut short for display.

```json
{
  "id": "ligh_dc6zakdkvsuuqow4m4vkixb3",
  "request_id": "req_2wyoehatnneitofvmmzcjs2pki",
  "object": "lighthouse",
  "created_at": "2026-08-09T08:28:43Z",
  "elapsed_ms": 180,
  "cache": "miss",
  "credits": {
    "charged": 2,
    "balance": 9857
  },
  "data": {
    "url": "https://example.com/",
    "device": "mobile",
    "scores": {
      "performance": 100,
      "accessibility": 96,
      "best_practices": 96,
      "seo": 80
    },
    "metrics": {
      "lcp_ms": 762,
      "fcp_ms": 611,
      "cls": 0.02,
      "tbt_ms": 40,
      "si_ms": 900,
      "tti_ms": 1100
    },
    "fetched_at": "2026-07-26T10:15:00Z",
    "audits": {
      "largest-contentful-paint": {
        "id": "largest-contentful-paint",
        "title": "Largest Contentful Paint",
        "description": "Largest Contentful Paint marks the time at which the largest text or image is painted.",
        "score": 1,
        "scoreDisplayMode": "numeric",
        "numericValue": 762.4,
        "numericUnit": "millisecond",
        "displayValue": "0.8 s",
        "scoringOptions": {
          "p10": 2500,
          "median": 4000
        }
      },
      "…": "…"
    },
    "screenshots": {
      "full_page": {
        "data": "data:image/webp;base64,…",
        "width": 412,
        "height": 6200
      },
      "final": {
        "data": "data:image/webp;base64,…"
      },
      "thumbnails": [
        {
          "data": "data:image/webp;base64,…",
          "timing": 375
        },
        "…"
      ]
    }
  }
}
```

## Response fields

What each field in `data` (above) means.

| Field | Description |
| --- | --- |
| `data.url` | The final URL Lighthouse actually audited, after any redirects. |
| `data.device` | Device profile the audit ran under: mobile or desktop. |
| `data.scores` | Four Lighthouse category scores, each 0-100. |
| `data.scores.performance` | Performance category score. |
| `data.scores.accessibility` | Accessibility category score. |
| `data.scores.best_practices` | Best-practices category score. |
| `data.scores.seo` | SEO category score. |
| `data.metrics` | Core Web Vitals and related timing metrics. |
| `data.metrics.lcp_ms` | Largest Contentful Paint, in milliseconds. |
| `data.metrics.fcp_ms` | First Contentful Paint, in milliseconds. |
| `data.metrics.cls` | Cumulative Layout Shift (unitless). |
| `data.metrics.tbt_ms` | Total Blocking Time, in milliseconds. |
| `data.metrics.si_ms` | Speed Index, in milliseconds. |
| `data.metrics.tti_ms` | Time to Interactive, in milliseconds. |
| `data.fetched_at` | When this Lighthouse run completed, ISO 8601. |
| `data.audits` | Every Lighthouse audit as produced by the analysis backend, keyed by audit id -- some diagnostic audits are empty depending on backend. Each audit's own `details` payload (e.g. script-treemap-data's node tree) passes through as-is, unfiltered. |
| `data.screenshots` | Screenshot captures produced by this Lighthouse run. |
| `data.screenshots.full_page` | A single stitched screenshot of the entire scrollable page, or null if the backend didn't produce one. |
| `data.screenshots.final` | The page's final-state screenshot, or null if the backend didn't produce one -- carries the image data plus the moment it was captured. |
| `data.screenshots.thumbnails` | Filmstrip of screenshots captured across the page load, oldest first; empty if the backend didn't produce one. |
