Skip to content

Trigger a crawl

POST
/v1/sites/{id}/crawl
curl --request POST \
--url https://api.overwatch.weareheavy.dev/v1/sites/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/crawl \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '{ "chainA11y": true }'

Start a crawl for the site right now. This is idempotent with respect to in-progress crawls: if a crawl is already running, no new crawl is started.

  • 202 Accepted — a new crawl was started (started: true).
  • 200 OK — a crawl was already running, so this was a no-op (started: false).

Owners, admins, and API keys can always trigger crawls; a restricted member needs the canCrawl grant. A manual crawl does not advance the scheduled cadence clock — see the Crawl behavior guide.

By default a manual crawl is a full scan — it chains the accessibility render pass when that app is installed. Pass { "chainA11y": false } for a links-only run.

id
required
string format: uuid

The site’s UUID.

Media typeapplication/json
object
chainA11y

Set false to skip the chained accessibility scan.

boolean
default: true

A crawl was already running; nothing was started.

Media typeapplication/json

The result of triggering a crawl.

object
started
required

true if a new crawl was started, false if one was already running.

boolean
status
required

Live crawl state from the crawler. Unlike persisted records, these are camelCase counters describing the in-progress run.

object
state
required
string
Allowed values: seeding crawling idle
runId
required
string format: uuid
pagesCrawled
required
integer
linksChecked
required
integer
brokenCount
required
integer
inFlight
required

URLs currently leased and being checked.

integer
pending
required

URLs waiting in the frontier to be leased.

integer
window
required

The adaptive in-flight window size.

integer
Example
{
"started": false,
"status": {
"state": "crawling",
"runId": "9f1c2e44-5b3a-4d8e-9f10-2a7c6b8e0d11",
"pagesCrawled": 134,
"linksChecked": 512,
"brokenCount": 3,
"inFlight": 8,
"pending": 47,
"window": 16
}
}

A new crawl was started.

Media typeapplication/json

The result of triggering a crawl.

object
started
required

true if a new crawl was started, false if one was already running.

boolean
status
required

Live crawl state from the crawler. Unlike persisted records, these are camelCase counters describing the in-progress run.

object
state
required
string
Allowed values: seeding crawling idle
runId
required
string format: uuid
pagesCrawled
required
integer
linksChecked
required
integer
brokenCount
required
integer
inFlight
required

URLs currently leased and being checked.

integer
pending
required

URLs waiting in the frontier to be leased.

integer
window
required

The adaptive in-flight window size.

integer
Example
{
"started": true,
"status": {
"state": "seeding",
"runId": "9f1c2e44-5b3a-4d8e-9f10-2a7c6b8e0d11",
"pagesCrawled": 0,
"linksChecked": 0,
"brokenCount": 0,
"inFlight": 0,
"pending": 1,
"window": 8
}
}

Missing or invalid credentials.

Media typeapplication/json
object
error
required

A human-readable error message.

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

The caller’s role or key scope does not allow this action.

Media typeapplication/json
object
error
required

A human-readable error message.

string
Example
{
"error": "only owners and admins can edit site settings"
}

No site with that id is visible to the caller.

Media typeapplication/json
object
error
required

A human-readable error message.

string
Example
{
"error": "site not found"
}

Neither the Broken Links nor the Accessibility app is enabled.

Media typeapplication/json
object
error
required

A human-readable error message.

string
Example
{
"error": "neither broken links nor accessibility is enabled for this site"
}