Create broken link scans

View as MarkdownOpen in Claude
Launches one Broken Links Checker scan per eligible website of an explicit selection (`type: full`), or one scan per website behind specific pages or findings to re-check (`type: page`). A scan takes from minutes to several hours: there is no answer to wait on for it to finish - follow it through "List broken link scans" and read `status` (`pending` while running; `done`, `failed` or `failed_partial` once it ends). **Body** (JSON), `type` decides the rest - the two scopes never mix: - `type` (string, required): `full` or `page`. - `sites` (integer array): required and the only accepted target for `full`; prohibited for `page`. Exact website ids, 1 to 200, scoped to the token's organization. - `pages` (integer array): only for `page`, required unless `issues` carries at least one id - an empty array is accepted for `pages` when `issues` does. Exact `site-broken-link-pages` ids, 0 to 200. - `issues` (integer array): only for `page`, required unless `pages` carries at least one id - an empty array is accepted for `issues` when `pages` does. Exact `site-broken-link-issues` ids, 0 to 200 - each resolves to the page(s) it was found on; a page already re-checked through another id in the same call is only scanned once. Page scan example, an empty companion list accepted alongside the other: ```json { \"type\": \"page\", \"pages\": [501], \"issues\": [] } ``` Answers **202** with the created `site-broken-link-scans` documents (`status: pending`) and `meta.skipped`: the websites the preflight refused (or, for a page scan, left with nothing to re-check), each with `site_id`, `site_name`, `scan_id` (null here), `reason_code` and `message`. Reason codes: `SITE_UNREACHABLE` (not connected, or has not synchronized in the last 48 hours), `UNSUPPORTED` (no Broken Links Checker configuration assigned, or the website's Modular Connector is too old to check links - update it), `CONFLICT` (a scan is already running for this website, including one launched between the preflight check and the launch itself), `NOT_FOUND` (a named page or finding already resolved/fixed, or a website left with nothing to re-check because every page it was named through is gone or ignored), `PERMISSION_DENIED` (a page or finding id outside the token's reach, `site_name` null). A page the caller ignored is never re-checked: naming only ignored pages for a website answers that website `NOT_FOUND` as a whole. `data: []` is still a 202. - **422**: `type` missing or invalid; `sites` sent on a `page` scan or missing/empty/over 200 ids on a `full` one; `pages`/`issues` sent on a `full` scan, or both missing on a `page` one; any list containing an id that resolves to no row. - **403**: a read-only token. - **404**: the organization's plan does not include the Broken Links Checker, or the member lacks the permission. The MCP twin is the `site-broken-link-scans-store` tool; the dashboard API offers the same call at `POST /api/site-broken-link-scans/bulk`. The pre-existing single-website `POST /api/site-broken-link-scans` on the dashboard is a separate, unmigrated endpoint and keeps its own contract.

Authentication

AuthorizationBearer

Personal access token created in the Modular DS dashboard; read-only tokens can only call GET endpoints.

Request

This endpoint expects an object.
siteslist of doublesOptional
typestringOptional

Response

202 Accepted - one scan launched, one website skipped / 202 Accepted - page scan, mixed skips

datalist of objectsOptional
jsonapiobjectOptional
metaobjectOptional

Errors

403
Forbidden Error
404
Not Found Error
422
Unprocessable Entity Error