Broken Links & Crawled URLs
These endpoints return broken links and crawled URL data for a monitor with the broken links check enabled. To configure the broken links check settings (whitelist URLs, link types, etc.), use the monitors endpoint.
You'll need a monitor ID for this endpoint.
Example request:
$ OHDEAR_TOKEN="your API token" $ curl https://ohdear.app/api/broken-links/1 \ -H "Authorization: Bearer $OHDEAR_TOKEN" \ -H 'Accept: application/json' \ -H 'Content-Type: application/json'
All endpoints below follow the same authentication pattern.
Get broken links for a monitor #
GET /api/broken-links/{monitorId}
Returns all broken links from the latest completed crawl run. You can also fetch results from a specific past run by passing run_id (see check history).
Query parameters:
run_id(integer, optional) -- return results from a specific run instead of the latest. Get run IDs from the check history endpoint.
Here's what the response looks like:
{ "data": [ { "status_code": 404, "crawled_url": "https://example.com/broken", "relative_crawled_url": "/broken", "found_on_url": "https://example.com", "relative_found_on_url": "/", "link_text": "Click here", "type": "link", "error_message": null, "internal": true } ], "meta": { "run_id": 98765, "run_started_at": "2026-03-17T00:30:00+00:00", "run_ended_at": "2026-03-17T00:53:58+00:00" } }
status_code: the HTTP status code returned by the broken linkcrawled_url: the full URL of the broken linkrelative_crawled_url: the relative path of the broken linkfound_on_url: the page where the broken link was foundrelative_found_on_url: the relative path of the page containing the broken linklink_text: the anchor text or alt text of the linktype: the kind of resource -- one oflink,image,script,stylesheet, orog:imageerror_message: a description of the error when the request failed entirely (e.g. DNS resolution failure, connection timeout), ornullwhen a status code was receivedinternal: whether the broken link points to the same domain (true) or an external site (false)
The meta object contains information about which run the results come from:
run_id: the ID of the runrun_started_at: when the run started (ISO 8601, UTC), ornullrun_ended_at: when the run completed (ISO 8601, UTC)
Get crawled URLs summary #
GET /api/crawled-urls/{monitorId}/summary
Returns a summary with counts of all URLs found during a crawl run, not just the broken ones. This is useful for understanding the scope of a crawl without fetching every URL.
Query parameters:
run_id(integer, optional) -- return results from a specific run instead of the latest. Get run IDs from the check history endpoint.
{ "data": { "total": 1234, "internal": 800, "external": 434, "by_type": { "image": 250, "link": 900, "og:image": 14, "script": 40, "stylesheet": 30 } }, "meta": { "run_id": 98765, "run_started_at": "2026-03-17T00:30:00+00:00", "run_ended_at": "2026-03-17T00:53:58+00:00" } }
total: the total number of URLs crawledinternal: URLs on the same domain as the monitorexternal: URLs pointing to other domainsby_type: breakdown by resource type (link,image,script,stylesheet,og:image)
Get crawled URLs details #
GET /api/crawled-urls/{monitorId}/details
Returns a paginated list of all URLs found during a crawl run (100 per page). Each entry includes the same fields as the broken links response.
Query parameters:
run_id(integer, optional) -- return results from a specific run instead of the latest. Get run IDs from the check history endpoint.page(integer, optional) -- the page number for pagination (defaults to 1).
{ "data": [ { "status_code": 200, "crawled_url": "https://example.com/page", "relative_crawled_url": "/page", "found_on_url": "https://example.com", "relative_found_on_url": "/", "link_text": "Some page", "type": "link", "error_message": null, "internal": true } ], "meta": { "current_page": 1, "from": 1, "last_page": 53, "per_page": 100, "to": 100, "total": 5230, "run_id": 98765, "run_started_at": "2026-03-17T00:30:00+00:00", "run_ended_at": "2026-03-17T00:53:58+00:00" }, "links": { "first": "/?page=1", "last": "/?page=53", "prev": null, "next": "/?page=2" } }
Feel free to reach out via [email protected] or on X via @OhDearApp if you have any other questions. We'd love to help!