lovablehtml logo - turn your SPA into a crawler-friendly website BLOGAPI PLATFORMPRICING

SEO Audit API

Trigger on-demand SEO audits for your domains and retrieve run results.

Trigger on-demand SEO audits for your domains, list past runs, and fetch detailed results. The crawler discovers pages, checks for SEO issues, and reports back. Only one audit can run per domain at a time.

All endpoints accept both session auth (dashboard) and API key auth (programmatic access). API keys scoped to a specific domain are restricted to that domain's runs.

API key access requires a Pro plan or above. Lower-tier API keys receive 403 { "error": "plan_required", "requiredPlan": "pro" }.

Start an Audit

POST/api/seo-spider/runs

Start a new SEO audit run for a domain. The crawler will discover and analyze pages based on the selected mode.

Request Body

Parameter Type Description
domainrequired string Domain to audit (e.g., "your-app.com").
urlsrequired string[] Seed URLs to crawl (min 1, must be valid URLs). All URLs must belong to the target domain. In follow mode, typically just the homepage.
moderequired "follow" | "selected" | "sitemap" follow — spider from seed URLs following links. selected — only audit the specified URLs. sitemap — discover URLs from the domain's sitemap.
allowSampling boolean Enable URL pattern sampling on the crawler. Default: true.
newPagesOnly boolean Only audit new or updated pages since the last completed run (sitemap mode). Default: false.
sitemapUrl string (URL) Custom sitemap URL override. Falls back to the domain's configured sitemap if omitted.

Response Body

json
CopyDownload
{
"ok": true,
"runId": "a1b2c3d4-e5f6-...",
"status": "running"
}

Response Codes

200
Success

Audit started. Returns runId and status: "running".

400
Bad Request

Validation failed: invalid_urls, no_sitemap, or schema error.

401
Unauthorized

Missing or invalid API key / session.

403
Forbidden

domain_not_owned, no_seo_spider_access, on_demand_limit_reached, or max_pages_per_month_limit_reached.

409
Conflict

run_already_active. An audit is already running for this domain. Response includes the active runId.

422
Unprocessable

no_new_pages. No new or updated pages found in sitemap since last audit (when newPagesOnly: true).

Example

javascript
CopyDownload
const response = await fetch("https://lovablehtml.com/api/seo-spider/runs", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-lovablehtml-api-key": "<API_KEY>",
},
body: JSON.stringify({
domain: "your-app.com",
urls: ["https://your-app.com"],
mode: "follow",
allowSampling: true,
}),
});
const result = await response.json();
// { "ok": true, "runId": "a1b2c3d4-e5f6-...", "status": "running" }
bash
CopyDownload
curl -X POST \
"https://lovablehtml.com/api/seo-spider/runs" \
-H "Content-Type: application/json" \
-H "x-lovablehtml-api-key: <API_KEY>" \
-d '{
"domain": "your-app.com",
"urls": ["https://your-app.com"],
"mode": "follow",
"allowSampling": true
}'

Limits: Audit access and page-per-run limits depend on your plan. Only one audit can run per domain at a time.

List Runs

GET/api/seo-spider/runs

List the 50 most recent SEO audit runs across your domains, optionally filtered by domain.

Query Parameters

Parameter Type Description
domain string Filter to runs for a single domain. If the API key is scoped to a domain, only that domain's runs are returned regardless of this parameter.

Response Body

json
CopyDownload
{
"runs": [
{
"id": "a1b2c3d4-e5f6-...",
"domain": "your-app.com",
"startedAt": 1762400000000,
"completedAt": 1762400180000,
"status": "success",
"trigger": "manual",
"frequency": "weekly",
"pagesCrawled": 42,
"healthScore": 87.5,
"issueCount": 12,
"deltaIssues": -3,
"deltaHealth": 2.1,
"robotsAnalysis": { "...": "..." },
"crawlStats": { "...": "..." },
"runCount": 1,
"closeReason": "finished",
"needsContinuation": false,
"hitUrlLimit": false,
"errorMessage": null
}
]
}

status is one of queued, running, success, limit_reached, partial, or error. Timestamps are Unix epoch milliseconds. Results are ordered by startedAt descending and capped at 50.

Response Codes

200
Success

Returns up to 50 runs. Empty runs array if the caller has no access to any matching domain.

401
Unauthorized

Missing or invalid API key / session (invalid_api_key).

Example

javascript
CopyDownload
const response = await fetch(
"https://lovablehtml.com/api/seo-spider/runs?domain=your-app.com",
{
headers: {
"x-lovablehtml-api-key": "<API_KEY>",
},
},
);
const { runs } = await response.json();
// runs[0] = { id, domain, status, healthScore, issueCount, ... }
bash
CopyDownload
# All recent runs across your domains
curl "https://lovablehtml.com/api/seo-spider/runs" \
-H "x-lovablehtml-api-key: <API_KEY>"
# Filter to a single domain
curl "https://lovablehtml.com/api/seo-spider/runs?domain=your-app.com" \
-H "x-lovablehtml-api-key: <API_KEY>"

Get Run Details

GET/api/seo-spider/runs/:runId

Fetch a single audit run with its per-page results.

Path Parameters

Parameter Type Description
runIdrequired string The run ID returned by `POST /api/seo-spider/runs`.

Response Body

json
CopyDownload
{
"run": {
"id": "a1b2c3d4-e5f6-...",
"domain": "your-app.com",
"startedAt": 1762400000000,
"completedAt": 1762400180000,
"status": "success",
"trigger": "manual",
"frequency": "weekly",
"pagesCrawled": 42,
"healthScore": 87.5,
"issueCount": 12,
"deltaIssues": -3,
"deltaHealth": 2.1,
"robotsAnalysis": { "...": "..." },
"crawlStats": { "...": "..." },
"runCount": 1,
"closeReason": "finished",
"needsContinuation": false,
"hitUrlLimit": false,
"errorMessage": null,
"sitemapIssues": []
},
"pages": [
{
"id": "page-uuid",
"path": "/",
"statusCode": 200,
"loadTimeMs": 420,
"healthScore": 92,
"previewScore": 88,
"indexable": true,
"issueCount": 2,
"issues": [{ "id": "missing_meta_description", "severity": "warning" }],
"trendPoints": [85, 88, 92]
}
]
}

pages is sourced from the live store while a run is recent and from cold storage once archived; the response shape is identical either way.

Response Codes

200
Success

Returns the run and its pages.

401
Unauthorized

Missing or invalid API key / session (invalid_api_key).

403
Forbidden

api_key_domain_scope_mismatch — the API key is scoped to a different domain. domain_access_forbidden — session user lacks access to the run's domain.

404
Not Found

Run does not exist or does not belong to the authenticated account.

Example

javascript
CopyDownload
const response = await fetch(
"https://lovablehtml.com/api/seo-spider/runs/a1b2c3d4-e5f6-...",
{
headers: {
"x-lovablehtml-api-key": "<API_KEY>",
},
},
);
const { run, pages } = await response.json();
// run.healthScore, run.issueCount, pages[i].path, pages[i].issues, ...
bash
CopyDownload
curl "https://lovablehtml.com/api/seo-spider/runs/a1b2c3d4-e5f6-..." \
-H "x-lovablehtml-api-key: <API_KEY>"
Avatar
How can we help?
Get instant answers to your questions or leave a message for an engineer will reach out
Ask AI about LovableHTML
See our docs
Contact support
Leave a message
We'll get back to you soon
Avatar
Ask AI about LovableHTML
Team is also here to help
Thinking
Preview
Powered by ReplyMaven
Avatar
Aki
Hi, need help with SEO, AI search or getting indexed?