Skip to content

Get the SEO report

GET
/v1/sites/{id}/seo-report
curl --request GET \
--url https://api.overwatch.weareheavy.dev/v1/sites/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/seo-report \
--header 'x-api-key: <x-api-key>'

The on-page SEO report, derived live from the latest crawl that extracted SEO data: issues grouped by rule (ranked by severity, then by recoverable score points), a worst-first per-page view, and a summary with the 0-100 score and an indexability verdict.

Issues are derived at read time from per-page field snapshots, so changes to the site’s excludePaths globs apply retroactively - duplicate detection recomputes from the filtered page set. The score frozen on the run row feeds the trend; the report’s live score can differ briefly after a settings change.

id
required
string format: uuid

The site’s UUID.

The latest SEO-extracting run, its issues, and summary.

Media typeapplication/json
object
run
required

A single crawl run and its summary metrics.

object
id
required
string format: uuid
tenant_id
required
string
site_id
required
string format: uuid
started_at
required

Epoch ms the run started.

integer
finished_at
required

Epoch ms the run finished, or null while running.

integer | null
state
required
string
Allowed values: running completed failed
pages_crawled
required
integer
links_checked
required
integer
broken_count
required

Distinct broken link targets found in the run.

integer
pages_with_broken_count
required

Distinct source pages that had at least one broken link.

integer
internal_broken
required
integer
external_broken
required
integer
a11y_score
required

Synthesized 0–100 accessibility score, or null when the run didn’t scan.

integer | null
<= 100
a11y_critical
required

Confirmed violations with critical impact.

integer
a11y_serious
required
integer
a11y_moderate
required
integer
a11y_minor
required
integer
a11y_pages_scanned
required

Internal pages the accessibility scan covered in this run.

integer
a11y_issue_count
required

Distinct confirmed (page, rule) accessibility violations this run (0 for crawl runs).

integer
a11y_resolved
required

Violations present in the previous accessibility run but gone in this one (the “fixed” trend).

integer
seo_score

Synthesized 0-100 SEO score, or null when the run didn’t extract SEO data.

integer | null
<= 100
seo_critical
integer
seo_serious
integer
seo_moderate
integer
seo_minor
integer
seo_pages_scanned

Pages an SEO snapshot was captured for (at most pages_crawled).

integer
seo_issue_count

Derived SEO issues at the time the run finalized.

integer
error
required

Failure reason if state is failed, otherwise null.

string | null
kind
required

crawl for a broken-link crawl, a11y for a standalone accessibility scan.

string
Allowed values: crawl a11y
byRule
required

Issues grouped per rule, most severe and most impactful first.

Array<object>
object
rule
required

Stable rule id (e.g. title-missing, meta-noindex).

string
severity
required
string
Allowed values: critical serious moderate minor
title
required
string
help
required

One-paragraph editor-facing remediation guidance.

string
pages
required

Pages affected by this rule.

integer
gain
required

Score points recoverable by fixing this rule site-wide.

integer
examples
required

Affected pages (capped), each with an optional detail string and the offending value itself (the title/description/canonical/robots text).

Array<object>
object
url
required
string format: uri
detail
required
string | null
content
required
string | null
byPage
required

Every page with at least one issue, ranked worst-first.

Array<object>
object
url
required
string format: uri
score
required

The page’s own 0-100 score.

integer
issues
required
integer
findings
required

The page’s findings, with the offending content where applicable.

Array<object>
object
rule
required
string
severity
required
string
Allowed values: critical serious moderate minor
title
required
string
detail
required
string | null
content
required
string | null
summary
required
object
score
required
integer
<= 100
critical
required
integer
serious
required
integer
moderate
required
integer
minor
required
integer
issueCount
required
integer
pagesScanned
required
integer
verdict
required
object
indexable
required

false iff something actively blocks search visibility - a noindex on a sitemap/root page, or a canonical crediting another site.

boolean
risk
required
string | null
Allowed values: high moderate low
structuredData
required

JSON-LD posture (informational): coverage, the site’s type inventory, and pages carrying none. Broken or rich-results-ineligible blocks surface as issues.

object
pagesWith
required
integer
total
required
integer
types
required

The site’s JSON-LD type inventory, most-used first.

Array<object>
object
type
required
string
pages
required
integer
pagesWithout
required

Pages with no structured data at all (capped).

Array<string>
Example
{
"run": {
"state": "running",
"kind": "crawl"
},
"byRule": [
{
"severity": "critical"
}
],
"byPage": [
{
"findings": [
{
"severity": "critical"
}
]
}
],
"summary": {
"verdict": {
"risk": "high"
}
}
}

Missing or invalid credentials.

Media typeapplication/json
object
error
required

A human-readable error message.

string
Example
{
"error": "invalid api key"
}

The site was not found, the SEO app is not enabled, or no completed crawl has extracted SEO data yet.

Media typeapplication/json
object
error
required

A human-readable error message.

string
Example
{
"error": "no runs yet"
}