Skip to content
Developers

Pages reference

Site Pages, fixes, the issue catalog and live feeds.

List the live links

GET/feeds

Scope:
read
Rate class:
light
Operation id:
list_feeds

The workspace's live links, newest first, revoked and expired ones included (owners and admins see every link, other members the ones they made). A link's address is never listed: it was shown once, when the link was made. Needs the read scope and a plan with exports; free of credits.

Parameters

NameInTypeDescription
limitqueryintegeroptionalItems per page, 1 to 200.Range: 1 to 200. Default: 50.
cursorquerystringoptionalThe next_cursor of the previous page. Opaque: never build one.

Answer 200

OK. The body is a FeedList.

FieldTypeDescription
dataarray of objectThe items of this page, in the endpoint's fixed order.
data[].idinteger
data[].namestring
data[].datasetstring
data[].dataset_labelstring
data[].site_idinteger
data[].site_urlstring
data[].prefixstringThe first characters of the link's secret (pbf_xxxxxxxx): enough to recognise it.
data[].statusstringactive, revoked or expired.
data[].created_atstring or null
data[].expires_atstring or nullA link stops working after a year.
data[].last_used_atstring or nullWhen a sheet last read it.
data[].use_countintegerHow many times it was read.
has_morebooleanTrue when another page follows.
next_cursorstring or nullPass as cursor to get the next page; null on the last page.
Example 200 answer of List the live links
{
  "data": [
    {
      "id": 9,
      "name": "Broken links: example.com",
      "dataset": "broken-links",
      "dataset_label": "Broken links",
      "site_id": 12,
      "site_url": "https://www.example.com",
      "prefix": "pbf_k3x9a7bq",
      "status": "active",
      "created_at": "2026-10-31T09:12:00Z",
      "expires_at": "2027-10-31T09:12:00Z",
      "use_count": 0
    }
  ],
  "has_more": false
}

Problems this call documents

Make a live link

POST/feeds

Scope:
read
Rate class:
light
Operation id:
create_feed

Makes a live CSV link for one of the workspace's sites and one table: crawl-history (one row per finished crawl), broken-links, all-urls, seo (the newest crawl's tables, followed on every read) or site-pages (the Site Pages list with the filters you give). Paste formula into Google Sheets. The link is in this answer only: it is a secret, anyone who has it can read the data, and it is never shown again (revoke it with DELETE /feeds/{feed_id}). It stops working after a year. Refused: a site with staging access, a table above the size a live link holds, and a workspace at its limit. Needs the read scope and a plan with exports; a viewer's key cannot make one. Free of credits.

Request body

application/json, required.

FieldTypeDescription
datasetstringrequiredWhich table the link serves: crawl-history, broken-links, all-urls, seo, site-pages.One of: crawl-history, broken-links, all-urls, seo, site-pages.
site_idintegerrequiredOne of the workspace's sites (GET /sites).Range: at least 1.
filtersobject or nulloptionalOnly for the site-pages dataset.
filters.changestring or nulloptionalOne of: new, changed.
filters.indexabilitystring or nulloptionalOne of: indexable, non_indexable, unknown.
filters.issuestring or nulloptionalAn issue code from GET /issue-types.Range: at most 40 characters.
filters.orderstringoptionalOne of: asc, desc. Default: asc.
filters.prefixstringoptionalOnly URLs that start with this.Range: at most 2000 characters.
filters.qstringoptionalOnly URLs that contain this.Range: at most 200 characters.
filters.resolvedstringoptionalOne of: show, hide, only. Default: show.
filters.sortstringoptionalOne of: url, status, inlinks, depth, response_time, word_count, last_seen, first_seen. Default: url.
filters.statusstring or nulloptionalOne of: ok, redirect, broken, gone, not_checked, unknown.
filters.typestring or nulloptionalOne of: page, document, other, image, css, js, font, video, iframe, audio, embed.
filters.viewstringoptionalpages, resources, links_out or missing.One of: pages, resources, links_out, missing. Default: pages.
namestring or nulloptionalA name to recognise the link by; the dataset and site by default.Range: at most 100 characters.
Example request body of Make a live link
{
  "dataset": "site-pages",
  "site_id": 12,
  "filters": {
    "status": "broken",
    "view": "pages"
  },
  "name": "Broken pages"
}

Answer 201

Created. The body is a FeedCreated.

FieldTypeDescription
idinteger
namestring
datasetstring
dataset_labelstring
site_idinteger
site_urlstring
prefixstringThe first characters of the link's secret (pbf_xxxxxxxx): enough to recognise it.
statusstringactive, revoked or expired.
created_atstring or null
expires_atstring or nullA link stops working after a year.
last_used_atstring or nullWhen a sheet last read it.
use_countintegerHow many times it was read.
urlstringThe link: anyone who has it can read the data until it is revoked.
formulastringThe same link as a Google Sheets formula.
Example 201 answer of Make a live link
{
  "id": 9,
  "name": "Broken links: example.com",
  "dataset": "broken-links",
  "dataset_label": "Broken links",
  "site_id": 12,
  "site_url": "https://www.example.com",
  "prefix": "pbf_k3x9a7bq",
  "status": "active",
  "created_at": "2026-10-31T09:12:00Z",
  "expires_at": "2027-10-31T09:12:00Z",
  "use_count": 0,
  "url": "https://dashboard.perfbee.com/feeds/pbf_k3x9a7bq_QmZ0a9xVn2pYf3Lr8sTq1uWb4cXd6eHg7iJ.csv",
  "formula": "=IMPORTDATA(\"https://dashboard.perfbee.com/feeds/pbf_k3x9a7bq_QmZ0a9xVn2pYf3Lr8sTq1uWb4cXd6eHg7iJ.csv\")"
}

Problems this call documents

Revoke a live link

DELETE/feeds/{feed_id}

Scope:
read
Rate class:
light
Operation id:
revoke_feed

Revokes a live link: the address stops working at once and cannot be brought back (make a new link). Revoking twice answers the same. Returns the feed as it is now. Needs the read scope and a plan with exports; free of credits.

Parameters

NameInTypeDescription
feed_idpathintegerrequiredThe live link's id (GET /feeds).Range: 1 to 9223372036854776000.

Answer 200

OK. The body is a Feed.

FieldTypeDescription
idinteger
namestring
datasetstring
dataset_labelstring
site_idinteger
site_urlstring
prefixstringThe first characters of the link's secret (pbf_xxxxxxxx): enough to recognise it.
statusstringactive, revoked or expired.
created_atstring or null
expires_atstring or nullA link stops working after a year.
last_used_atstring or nullWhen a sheet last read it.
use_countintegerHow many times it was read.
Example 200 answer of Revoke a live link
{
  "id": 9,
  "name": "Broken links: example.com",
  "dataset": "broken-links",
  "dataset_label": "Broken links",
  "site_id": 12,
  "site_url": "https://www.example.com",
  "prefix": "pbf_k3x9a7bq",
  "status": "active",
  "created_at": "2026-10-31T09:12:00Z",
  "expires_at": "2027-10-31T09:12:00Z",
  "use_count": 0
}

Problems this call documents

List the issue catalog

GET/issue-types

Scope:
read
Rate class:
light
Operation id:
list_issue_types

Every issue code a page can carry (issues of a page, the issue filter, fixes) with its label, severity, category, what it looks at, why it matters and how to fix it. The catalog grows: codes are never renumbered or reused, so ignore codes you do not know. It is one page: no limit or cursor. Needs the read scope; free of credits.

Answer 200

OK. A page of IssueType objects, with next_cursor and has_more.

FieldTypeDescription
dataarray of objectThe items of this page, in the endpoint's fixed order.
data[].codestringThe stable code. Codes are never renumbered or reused; new ones appear, so ignore codes you do not know.
data[].labelstringThe issue in words.
data[].severitystringerror, warning or info.
data[].categorystringindexing, content, social, asset, security or links.
data[].helpstringWhat the check looks at.
data[].whystringWhy it matters.
data[].fixstringHow to fix it.
has_morebooleanTrue when another page follows.
next_cursorstring or nullPass as cursor to get the next page; null on the last page.
Example 200 answer of List the issue catalog
{
  "data": [
    {
      "code": "missing_title",
      "label": "Missing title",
      "severity": "error",
      "category": "content",
      "help": "The page has no <title> element.",
      "why": "Search results show the title; without one they guess.",
      "fix": "Give every page a short, unique title."
    }
  ],
  "has_more": true,
  "next_cursor": "eyJ2IjoxfQ.opaque"
}

List a site's fixes

GET/sites/{site_id}/fixes

Scope:
read
Rate class:
light
Operation id:
list_site_fixes

The site's fix list, the Fixes view of the dashboard: each issue grouped by page template (one change fixes every page built from it), the whole site or separate pages, and every broken link, best score first. status picks open fixes (the default), those the team set aside, resolved ones or all. The score and rank only order the list: the weights are still being tuned. It is a keyset: pass next_cursor back as cursor. include=count adds the counts per status and severity. The view is behind a switch in the dashboard and these routes are 404 wherever it is hidden. Needs the read scope; free of credits.

Parameters

NameInTypeDescription
site_idpathintegerrequiredThe site's id (GET /sites).Range: 1 to 9223372036854776000.
statusquerystringoptionalopen, set_aside (accepted, won't fix or snoozed), resolved or all.One of: open, set_aside, resolved, all. Default: open.
severityqueryarray of stringoptionalOnly these severities; repeat the parameter.
kindquerystringoptionalOnly fixes of this kind.One of: site, template, pages, link.
codequerystringoptionalOnly fixes of this issue code.Range: at most 64 characters.
qquerystringoptionalOnly fixes whose issue, template or URL contains this.Range: at most 200 characters.
includequeryanyoptionalcount adds counts.
limitqueryintegeroptionalItems per page, 1 to 200.Range: 1 to 200. Default: 50.
cursorquerystringoptionalThe next_cursor of the previous page. Opaque: never build one.

Answer 200

OK. The body is a FixList.

FieldTypeDescription
dataarray of objectThe items of this page, in the endpoint's fixed order.
data[].idinteger
data[].codestringThe issue code. Page issue codes are in GET /issue-types; link fixes use broken_link, broken_external_link and broken_sitemap_url. Ignore codes you do not know.
data[].labelstringThe issue in words.
data[].severitystringerror, warning or info.
data[].kindstringsite (the whole site), template, pages (separate pages) or link (one broken URL).
data[].statusstringopen, regressed (it came back), checking, looks_fixed, resolved or stale.
data[].pagesintegerPages the fix touches (for a link fix: pages that link to the broken URL).
data[].template_pagesinteger or nullPages of the template, when the fix is a template's.
data[].scorenumberRanks the fix against the site's others; for ordering only.
data[].rankinteger or nullIts place in the site's open list; null for a fix that is not open or is set aside.
data[].scopestringWhere the fix is, in one line.
data[].templateobject or null
data[].template.idinteger
data[].template.labelstringThe URL pattern most of the template's pages share.
data[].template.example_urlstring or nullOne page built from the template.
data[].template.pagesintegerPages built from the template.
data[].template.sourcestringHow the pages were grouped: skeleton (page structure) or url (URL pattern).
data[].targetstring or nullFor a link fix, the broken URL.
data[].target_page_idinteger or nullThat URL's id for GET /sites/{site_id}/pages/{page_id}; null when it left the inventory.
data[].first_seen_atstring or null
data[].resolved_atstring or null
data[].resolved_bystring or nullscan, check or marked.
data[].decisionstring or nullWhat the team decided in the dashboard: accepted, wont_fix or snoozed (until the next crawl); null = nothing.
data[].decided_atstring or null
data[].decision_notestring or null
data[].last_checkobject or nullThe latest "Check if fixed" (started in the dashboard).
data[].last_check.scopestring or nullsample or all.
data[].last_check.pagesinteger or nullPages the check reads.
data[].last_check.started_atstring or null
data[].last_check.checkedinteger or nullPages it could read; null while it runs.
data[].last_check.fixedinteger or nullOf those, pages where the issue is gone.
data[].last_check.finished_atstring or null
has_morebooleanTrue when another page follows.
countsobject or nullOnly with include=count.
counts.statusobjectFixes per status tab.
counts.status.openinteger
counts.status.set_asideintegerAccepted, won't-fix or snoozed.
counts.status.resolvedinteger
counts.severityobjectFixes of the chosen status per severity.
counts.severity.errorinteger
counts.severity.warninginteger
counts.severity.infointeger
next_cursorstring or nullPass as cursor to get the next page; null on the last page.
Example 200 answer of List a site's fixes
{
  "data": [
    {
      "id": 311,
      "code": "missing_meta_description",
      "label": "Missing meta description",
      "severity": "warning",
      "kind": "template",
      "status": "open",
      "pages": 1840,
      "template_pages": 2010,
      "score": 21.4,
      "rank": 1,
      "scope": "Template /shoes/{slug} · 1,840 of 2,010 pages",
      "template": {
        "id": 17,
        "label": "/shoes/{slug}",
        "example_url": "https://www.example.com/shoes/trail-runner",
        "pages": 2010,
        "source": "skeleton"
      },
      "first_seen_at": "2026-09-02T04:11:09Z"
    }
  ],
  "has_more": true,
  "next_cursor": "eyJ2IjoxfQ.opaque"
}

Problems this call documents

Get one fix

GET/sites/{site_id}/fixes/{fix_id}

Scope:
read
Rate class:
light
Operation id:
get_site_fix

One fix with the issue in words (what is wrong, why it matters, how to fix it, naming an example page) and its history, the latest 50 events newest first. People behind decisions are not named. Needs the read scope; free of credits.

Parameters

NameInTypeDescription
site_idpathintegerrequiredThe site's id (GET /sites).Range: 1 to 9223372036854776000.
fix_idpathintegerrequiredThe fix's id (GET /sites/{site_id}/fixes).Range: 1 to 9223372036854776000.

Answer 200

OK. The body is a FixDetail.

FieldTypeDescription
fixobjectOne thing to fix: an issue on a template, on the whole site, on separate pages, or one broken URL.
fix.idinteger
fix.codestringThe issue code. Page issue codes are in GET /issue-types; link fixes use broken_link, broken_external_link and broken_sitemap_url. Ignore codes you do not know.
fix.labelstringThe issue in words.
fix.severitystringerror, warning or info.
fix.kindstringsite (the whole site), template, pages (separate pages) or link (one broken URL).
fix.statusstringopen, regressed (it came back), checking, looks_fixed, resolved or stale.
fix.pagesintegerPages the fix touches (for a link fix: pages that link to the broken URL).
fix.template_pagesinteger or nullPages of the template, when the fix is a template's.
fix.scorenumberRanks the fix against the site's others; for ordering only.
fix.rankinteger or nullIts place in the site's open list; null for a fix that is not open or is set aside.
fix.scopestringWhere the fix is, in one line.
fix.templateobject or null
fix.template.idinteger
fix.template.labelstringThe URL pattern most of the template's pages share.
fix.template.example_urlstring or nullOne page built from the template.
fix.template.pagesintegerPages built from the template.
fix.template.sourcestringHow the pages were grouped: skeleton (page structure) or url (URL pattern).
fix.targetstring or nullFor a link fix, the broken URL.
fix.target_page_idinteger or nullThat URL's id for GET /sites/{site_id}/pages/{page_id}; null when it left the inventory.
fix.first_seen_atstring or null
fix.resolved_atstring or null
fix.resolved_bystring or nullscan, check or marked.
fix.decisionstring or nullWhat the team decided in the dashboard: accepted, wont_fix or snoozed (until the next crawl); null = nothing.
fix.decided_atstring or null
fix.decision_notestring or null
fix.last_checkobject or nullThe latest "Check if fixed" (started in the dashboard).
fix.last_check.scopestring or nullsample or all.
fix.last_check.pagesinteger or nullPages the check reads.
fix.last_check.started_atstring or null
fix.last_check.checkedinteger or nullPages it could read; null while it runs.
fix.last_check.fixedinteger or nullOf those, pages where the issue is gone.
fix.last_check.finished_atstring or null
issueobject
issue.codestring
issue.labelstring
issue.severitystring
issue.categorystring
issue.helpstringWhat is wrong.
issue.whystringWhy it matters.
issue.fixstringHow to fix it, with the example page named where the text refers to it.
example_urlstring or nullA page to look at first: the template's example or the broken URL.
historyarray of objectThe latest 50 events, newest first.
history[].kindstringWhat happened: opened, grew, shrank, resolved, regressed, checked, accepted, wont_fix, snoozed, reopened...
history[].pagesintegerPages affected at that moment.
history[].atstring or null
history[].crawl_idstring or nullThe crawl that found it, when a crawl did.
history[].notestring or null
Example 200 answer of Get one fix
{
  "fix": {
    "id": 311,
    "code": "missing_meta_description",
    "label": "Missing meta description",
    "severity": "warning",
    "kind": "template",
    "status": "open",
    "pages": 1840,
    "template_pages": 2010,
    "score": 21.4,
    "rank": 1,
    "scope": "Template /shoes/{slug} · 1,840 of 2,010 pages",
    "template": {
      "id": 17,
      "label": "/shoes/{slug}",
      "example_url": "https://www.example.com/shoes/trail-runner",
      "pages": 2010,
      "source": "skeleton"
    },
    "first_seen_at": "2026-09-02T04:11:09Z"
  },
  "issue": {
    "code": "missing_meta_description",
    "label": "Missing meta description",
    "severity": "warning",
    "category": "content",
    "help": "The page has no meta description.",
    "why": "Search results then show whatever text they pick.",
    "fix": "Write a meta description of about 150 characters for https://www.example.com/shoes/trail-runner."
  },
  "example_url": "https://www.example.com/shoes/trail-runner",
  "history": [
    {
      "kind": "opened",
      "pages": 1840,
      "at": "2026-09-02T04:30:00Z",
      "crawl_id": "7d1c0f94-2b8e-4a73-9a10-5f3d8e6c1b02"
    }
  ]
}

Problems this call documents

List the pages of a fix

GET/sites/{site_id}/fixes/{fix_id}/pages

Scope:
read
Rate class:
heavy
Operation id:
list_site_fix_pages

The pages a fix is about. For a fix of pages, templates or the whole site these are the affected pages, most linked first, as a keyset: pass next_cursor back as cursor (a sort over the whole set, so a very large fix can answer 503 query_too_slow: narrow it with q). For a link fix they are the pages that link to the broken URL with the anchor text and the HTML element: a crawl stores at most 200 of them, so that list is short and sorted by URL. kind says which. q keeps URLs containing it. Needs the read scope; free of credits.

Parameters

NameInTypeDescription
site_idpathintegerrequiredThe site's id (GET /sites).Range: 1 to 9223372036854776000.
fix_idpathintegerrequiredThe fix's id (GET /sites/{site_id}/fixes).Range: 1 to 9223372036854776000.
qquerystringoptionalOnly URLs that contain this.Range: at most 200 characters.
limitqueryintegeroptionalItems per page, 1 to 200.Range: 1 to 200. Default: 50.
cursorquerystringoptionalThe next_cursor of the previous page. Opaque: never build one.

Answer 200

OK. The body is a FixPageList.

FieldTypeDescription
dataarray of objectThe items of this page, in the endpoint's fixed order.
data[].urlstring
data[].page_idinteger or nullThe page's id in the site's inventory; null when it is not in it.
data[].inbound_linksinteger or nullPages linking to an affected page (null for a linking page).
data[].anchor_textstring or nullLink fixes: the broken link's anchor text.
data[].element_xpathstring or nullLink fixes: the HTML element holding the broken link.
has_morebooleanTrue when another page follows.
kindstringpages: the URLs are affected pages, most linked first. links: the URLs are pages linking to the broken URL (at most 200 are stored, sorted by URL).
next_cursorstring or nullPass as cursor to get the next page; null on the last page.
Example 200 answer of List the pages of a fix
{
  "data": [
    {
      "url": "https://www.example.com/shoes/trail-runner",
      "page_id": 48120,
      "inbound_links": 37
    }
  ],
  "has_more": false,
  "kind": "pages"
}

Problems this call documents

List a site's pages

GET/sites/{site_id}/pages

Scope:
read
Rate class:
heavy
Operation id:
list_site_pages

The site's page inventory, the list behind Site Pages in the dashboard: one row per URL the crawls found, with its status, its SEO data (from the newest detailed crawl) and the issue codes it carries. Choose a view and narrow it with the filters of the dashboard. The order is always by URL, and the list is a keyset: pass next_cursor back as cursor. inventory says which crawl the list shows and whether it covered the whole site. A filter that matches few rows can take long; past 15 seconds the answer is 503 query_too_slow, so narrow it with prefix or a view. include=count adds the counts behind the dashboard's chips (one more, heavier query). For other sort orders download an export. Needs the read scope; free of credits.

Parameters

NameInTypeDescription
site_idpathintegerrequiredThe site's id (GET /sites).Range: 1 to 9223372036854776000.
includequeryanyoptionalcount adds counts.
viewquerystringoptionalpages: HTML pages. resources: images, scripts, styles, fonts, media and the site's own files. links_out: pages and files outside the site or its folder that the site links to. missing: URLs a later complete crawl no longer found.One of: pages, resources, links_out, missing. Default: pages.
statusquerystringoptionalOnly URLs with this status class.One of: ok, redirect, broken, gone, not_checked, unknown.
typequerystringoptionalOnly URLs of this type.One of: page, document, other, image, css, js, font, video, iframe, audio, embed.
indexabilityquerystringoptionalOnly pages with this indexability.One of: indexable, non_indexable, unknown.
issuequerystringoptionalOnly URLs carrying this issue code (GET /issue-types).Range: at most 40 characters.
changequerystringoptionalOnly URLs new or changed in the newest crawl.One of: new, changed.
resolvedquerystringoptionalshow, hide or list only the URLs someone marked resolved.One of: show, hide, only. Default: show.
prefixquerystringoptionalOnly URLs that start with this text.Range: at most 2000 characters.
qquerystringoptionalOnly URLs that contain this text.Range: at most 200 characters.
sortqueryanyoptionalURL order is the only one the list offers: for other orders download an export.Default: url.
limitqueryintegeroptionalItems per page, 1 to 200.Range: 1 to 200. Default: 50.
cursorquerystringoptionalThe next_cursor of the previous page. Opaque: never build one.

Answer 200

OK. The body is a SitePageList.

FieldTypeDescription
dataarray of objectThe items of this page, in the endpoint's fixed order.
data[].idintegerThe page's id inside the site (a 64-bit integer: store it as one).
data[].urlstringThe URL exactly as the crawl stored it.
data[].url_typestringpage, document, other, image, css, js, font, video, iframe, audio or embed.
data[].link_scopestring or nullinternal, outside_folder (same host, outside the folder of a sub-path site) or external.
data[].status_classstring or nullok, redirect, broken, gone (HTTP 410), not_checked (the crawler was refused, see block_reason) or unknown.
data[].status_codeinteger or nullThe HTTP status the crawl got; null when there was none.
data[].block_reasonstring or nullWhy a URL was not checked (bot wall, robots.txt...); set only with status_class not_checked.
data[].error_messagestring or nullThe connection error, when the request failed before an HTTP status.
data[].redirect_targetstring or nullWhere a redirect points.
data[].content_typestring or nullThe response's Content-Type.
data[].response_time_msinteger or nullHow long the response took, in milliseconds.
data[].found_on_pagestring or nullA page that links here (the first one the crawl met).
data[].found_viastring or nulllink, sitemap or list: how the crawl first reached it.
data[].inbound_linksinteger or nullHow many pages link here; null when the crawl did not cover the whole site.
data[].in_sitemapboolean or nullListed in the sitemap; null when the sitemap was not read in full.
data[].crawl_depthinteger or nullClicks from the start page.
data[].titlestring or nullThe page title; the SEO columns are filled only by a detailed crawl.
data[].meta_descriptionstring or nullThe meta description.
data[].h1string or nullThe first H1.
data[].word_countinteger or nullWords in the main text.
data[].title_pixel_widthinteger or nullEstimated width of the title in a search result, in pixels.
data[].meta_description_pixel_widthinteger or nullEstimated width of the meta description, in pixels.
data[].canonical_urlstring or nullThe canonical URL the page names.
data[].meta_robotsstring or nullThe robots meta directives.
data[].indexabilitystring or nullindexable, non_indexable or unknown; null for anything but a page.
data[].indexability_reasonstring or nullWhy: noindex, canonicalised, a status class, robots_txt, not_checked or needs_detailed_scan.
data[].issuesarray of stringThe issue codes the page carries, most severe first. Look them up in GET /issue-types; ignore codes you do not know.
data[].seo_crawl_idstring or nullThe detailed crawl the SEO columns and issues come from.
data[].marked_resolved_atstring or nullWhen someone marked the URL resolved in the dashboard.
data[].marked_resolved_notestring or nullThe note left with that mark.
data[].rechecked_atstring or nullWhen the URL was last rechecked on its own.
data[].first_seen_atstring or nullWhen a crawl first saw the URL (ISO 8601 UTC).
data[].last_seen_atstring or nullWhen a crawl last saw it.
data[].missing_sincestring or nullSet when a later complete crawl no longer found the URL.
data[].previous_status_codeinteger or nullThe status before the latest change.
data[].status_changed_atstring or nullWhen the status last changed.
data[].content_inlinksinteger or nullInlinks from the main content, not menus or footers. Present only while the link graph is switched on for the platform; null = not measured.
data[].external_outlinksinteger or nullLinks to other sites. Present only while the link graph is switched on for the platform; null = not measured.
data[].link_scoreinteger or nullPerfBee Link Score, 1 to 100. Present only while the link graph is switched on for the platform; null = not measured.
data[].nofollow_inlinksinteger or nullInlinks that carry rel=nofollow. Present only while the link graph is switched on for the platform; null = not measured.
data[].outlinksinteger or nullLinks on the page. Present only while the link graph is switched on for the platform; null = not measured.
data[].unique_outlinksinteger or nullDistinct link targets on the page. Present only while the link graph is switched on for the platform; null = not measured.
has_morebooleanTrue when another page follows.
inventoryobjectWhich crawl the inventory shows and how much of the site it covers: read it before trusting a list.
inventory.crawlobject or nullThe newest crawl written into the inventory; null before the first crawl.
inventory.crawl.idstringThe crawl's id (a UUID).
inventory.crawl.completed_atstring or nullWhen the crawl finished.
inventory.crawl.modestring or nullfast or full.
inventory.crawl.close_reasonstring or nullWhy it ended, when not because it finished its work.
inventory.coveragestring or nullcomplete: the crawl covered the site and marked URLs it no longer found as missing. update: it only refreshed what it saw.
inventory.coverage_reasonstring or nullWhy the newest crawl only updated, in words; null when it was complete.
inventory.seo_crawlobject or nullThe newest detailed crawl the SEO columns come from.
inventory.seo_crawl.idstringThe crawl's id (a UUID).
inventory.seo_crawl.completed_atstring or nullWhen the crawl finished.
inventory.seo_crawl.modestring or nullfast or full.
inventory.seo_crawl.close_reasonstring or nullWhy it ended, when not because it finished its work.
inventory.syncobject
inventory.sync.statusstring or nullok, running or failed: whether the inventory is being written or the write failed.
inventory.sync.errorstring or nullA short reason when status is failed.
inventory.sync.synced_atstring or nullWhen the inventory was last written.
inventory.url_countintegerURLs in the inventory, every view together.
countsobject or nullOnly with include=count.
counts.viewsobjectEvery view over the whole site, whatever the filters.
counts.views.pagesintegerHTML pages of the site.
counts.views.resourcesintegerImages, scripts, stylesheets, fonts, media and the site's own files.
counts.views.links_outintegerPages and files outside the site or its folder that the site links to.
counts.views.missingintegerURLs a later complete crawl no longer found.
counts.in_viewintegerRows in the chosen view after prefix and q, before the other filters.
counts.matchedintegerRows the list holds: the view with every filter applied.
counts.statusobjectin_view split by status class.
counts.status.okinteger
counts.status.redirectinteger
counts.status.brokeninteger
counts.status.goneinteger
counts.status.not_checkedinteger
counts.status.unknowninteger
counts.indexabilityobjectin_view split by indexability.
counts.indexability.indexableinteger
counts.indexability.non_indexableinteger
counts.indexability.unknowninteger
counts.issuesobjectin_view rows carrying each issue code (codes with none are left out).
counts.changeobject
counts.change.newintegerSeen for the first time by the newest crawl.
counts.change.changedintegerWhose status changed in the newest crawl.
counts.resolvedintegerRows in in_view that someone marked resolved.
next_cursorstring or nullPass as cursor to get the next page; null on the last page.
Example 200 answer of List a site's pages
{
  "data": [
    {
      "id": 48120,
      "url": "https://www.example.com/shoes/trail-runner",
      "url_type": "page",
      "link_scope": "internal",
      "status_class": "ok",
      "status_code": 200,
      "content_type": "text/html; charset=utf-8",
      "response_time_ms": 412,
      "found_on_page": "https://www.example.com/shoes",
      "found_via": "link",
      "inbound_links": 37,
      "in_sitemap": true,
      "crawl_depth": 2,
      "title": "Trail Runner | Example Shoes",
      "h1": "Trail Runner",
      "word_count": 214,
      "title_pixel_width": 392,
      "canonical_url": "https://www.example.com/shoes/trail-runner",
      "indexability": "indexable",
      "issues": [
        "missing_meta_description"
      ],
      "seo_crawl_id": "0b6f1d52-8a41-4f0e-9d7b-3c5e21a7f9aa",
      "first_seen_at": "2026-09-02T04:11:09Z",
      "last_seen_at": "2026-10-30T03:52:41Z"
    }
  ],
  "has_more": true,
  "inventory": {
    "crawl": {
      "id": "7d1c0f94-2b8e-4a73-9a10-5f3d8e6c1b02",
      "completed_at": "2026-10-30T03:52:41Z",
      "mode": "full"
    },
    "coverage": "complete",
    "seo_crawl": {
      "id": "7d1c0f94-2b8e-4a73-9a10-5f3d8e6c1b02",
      "completed_at": "2026-10-30T03:52:41Z",
      "mode": "full"
    },
    "sync": {
      "status": "ok",
      "synced_at": "2026-10-30T03:58:12Z"
    },
    "url_count": 5120
  },
  "next_cursor": "eyJ2IjoxfQ.opaque"
}

Problems this call documents

Get one page of a site

GET/sites/{site_id}/pages/{page_id}

Scope:
read
Rate class:
light
Operation id:
get_site_page

One row of the site's inventory with the issues on it in words (labels from GET /issue-types) and the pages that link to it in the newest crawl that saw it. The crawl stores at most 200 linking pages per URL and this answer lists the first 50 by URL; linking_pages says the cap, how many are listed and how many pages link here in all. Needs the read scope; free of credits.

Parameters

NameInTypeDescription
site_idpathintegerrequiredThe site's id (GET /sites).Range: 1 to 9223372036854776000.
page_idpathintegerrequiredThe page's id (GET /sites/{site_id}/pages).Range: 1 to 9223372036854776000.

Answer 200

OK. The body is a SitePageDetail.

FieldTypeDescription
pageobjectOne row of the site's page inventory (Site Pages in the dashboard): a URL, what the newest crawl saw there, and what it found wrong.
page.idintegerThe page's id inside the site (a 64-bit integer: store it as one).
page.urlstringThe URL exactly as the crawl stored it.
page.url_typestringpage, document, other, image, css, js, font, video, iframe, audio or embed.
page.link_scopestring or nullinternal, outside_folder (same host, outside the folder of a sub-path site) or external.
page.status_classstring or nullok, redirect, broken, gone (HTTP 410), not_checked (the crawler was refused, see block_reason) or unknown.
page.status_codeinteger or nullThe HTTP status the crawl got; null when there was none.
page.block_reasonstring or nullWhy a URL was not checked (bot wall, robots.txt...); set only with status_class not_checked.
page.error_messagestring or nullThe connection error, when the request failed before an HTTP status.
page.redirect_targetstring or nullWhere a redirect points.
page.content_typestring or nullThe response's Content-Type.
page.response_time_msinteger or nullHow long the response took, in milliseconds.
page.found_on_pagestring or nullA page that links here (the first one the crawl met).
page.found_viastring or nulllink, sitemap or list: how the crawl first reached it.
page.inbound_linksinteger or nullHow many pages link here; null when the crawl did not cover the whole site.
page.in_sitemapboolean or nullListed in the sitemap; null when the sitemap was not read in full.
page.crawl_depthinteger or nullClicks from the start page.
page.titlestring or nullThe page title; the SEO columns are filled only by a detailed crawl.
page.meta_descriptionstring or nullThe meta description.
page.h1string or nullThe first H1.
page.word_countinteger or nullWords in the main text.
page.title_pixel_widthinteger or nullEstimated width of the title in a search result, in pixels.
page.meta_description_pixel_widthinteger or nullEstimated width of the meta description, in pixels.
page.canonical_urlstring or nullThe canonical URL the page names.
page.meta_robotsstring or nullThe robots meta directives.
page.indexabilitystring or nullindexable, non_indexable or unknown; null for anything but a page.
page.indexability_reasonstring or nullWhy: noindex, canonicalised, a status class, robots_txt, not_checked or needs_detailed_scan.
page.issuesarray of stringThe issue codes the page carries, most severe first. Look them up in GET /issue-types; ignore codes you do not know.
page.seo_crawl_idstring or nullThe detailed crawl the SEO columns and issues come from.
page.marked_resolved_atstring or nullWhen someone marked the URL resolved in the dashboard.
page.marked_resolved_notestring or nullThe note left with that mark.
page.rechecked_atstring or nullWhen the URL was last rechecked on its own.
page.first_seen_atstring or nullWhen a crawl first saw the URL (ISO 8601 UTC).
page.last_seen_atstring or nullWhen a crawl last saw it.
page.missing_sincestring or nullSet when a later complete crawl no longer found the URL.
page.previous_status_codeinteger or nullThe status before the latest change.
page.status_changed_atstring or nullWhen the status last changed.
page.content_inlinksinteger or nullInlinks from the main content, not menus or footers. Present only while the link graph is switched on for the platform; null = not measured.
page.external_outlinksinteger or nullLinks to other sites. Present only while the link graph is switched on for the platform; null = not measured.
page.link_scoreinteger or nullPerfBee Link Score, 1 to 100. Present only while the link graph is switched on for the platform; null = not measured.
page.nofollow_inlinksinteger or nullInlinks that carry rel=nofollow. Present only while the link graph is switched on for the platform; null = not measured.
page.outlinksinteger or nullLinks on the page. Present only while the link graph is switched on for the platform; null = not measured.
page.unique_outlinksinteger or nullDistinct link targets on the page. Present only while the link graph is switched on for the platform; null = not measured.
crawl_idstring or nullThe newest crawl that saw this URL.
issue_detailsarray of objectpage.issues decoded with the catalog, same order.
issue_details[].codestring
issue_details[].labelstringThe issue in words.
issue_details[].severitystringerror, warning or info.
issue_details[].categorystringindexing, content, social, asset, security or links.
linking_pagesobject
linking_pages.totalintegerPages that link here, as the newest crawl counted them (can exceed what is stored).
linking_pages.stored_maxintegerThe most linking pages a crawl stores per URL, whatever the list shows.
linking_pages.limitintegerThe most this answer lists. The list is capped; it has no cursor.
linking_pages.itemsarray of objectSorted by the linking page's URL.
linking_pages.items[].source_urlstring or nullThe page that links to this URL.
linking_pages.items[].anchor_textstring or nullThe link's anchor text (an image's alt text).
linking_pages.items[].element_xpathstring or nullWhere in the page the link sits: the HTML element to edit.
linking_pages.items[].linkobject or nullWhat the first link from that page is. Present only while the link graph is switched on for the platform; null = not measured.
Example 200 answer of Get one page of a site
{
  "page": {
    "id": 48120,
    "url": "https://www.example.com/shoes/trail-runner",
    "url_type": "page",
    "link_scope": "internal",
    "status_class": "ok",
    "status_code": 200,
    "content_type": "text/html; charset=utf-8",
    "response_time_ms": 412,
    "found_on_page": "https://www.example.com/shoes",
    "found_via": "link",
    "inbound_links": 37,
    "in_sitemap": true,
    "crawl_depth": 2,
    "title": "Trail Runner | Example Shoes",
    "h1": "Trail Runner",
    "word_count": 214,
    "title_pixel_width": 392,
    "canonical_url": "https://www.example.com/shoes/trail-runner",
    "indexability": "indexable",
    "issues": [
      "missing_meta_description"
    ],
    "seo_crawl_id": "0b6f1d52-8a41-4f0e-9d7b-3c5e21a7f9aa",
    "first_seen_at": "2026-09-02T04:11:09Z",
    "last_seen_at": "2026-10-30T03:52:41Z"
  },
  "crawl_id": "7d1c0f94-2b8e-4a73-9a10-5f3d8e6c1b02",
  "issue_details": [
    {
      "code": "missing_meta_description",
      "label": "Missing meta description",
      "severity": "warning",
      "category": "content"
    }
  ],
  "linking_pages": {
    "total": 37,
    "stored_max": 200,
    "limit": 50,
    "items": [
      {
        "source_url": "https://www.example.com/shoes",
        "anchor_text": "Trail Runner",
        "element_xpath": "/html/body/main/ul/li[3]/a"
      }
    ]
  }
}

Problems this call documents

List the webhook events

GET/webhook-events

Scope:
read
Rate class:
light
Operation id:
list_webhook_events

Every event a webhook endpoint can subscribe to, with the part of the product it belongs to and when it fires. It is one page: no limit or cursor. Needs the read scope; free of credits.

Answer 200

OK. A page of WebhookEventType objects, with next_cursor and has_more.

FieldTypeDescription
dataarray of objectThe items of this page, in the endpoint's fixed order.
data[].eventstringThe event name a webhook endpoint subscribes to.
data[].groupstringThe part of the product it belongs to.
data[].labelstringThe event in words.
data[].descriptionstringWhen it fires.
has_morebooleanTrue when another page follows.
next_cursorstring or nullPass as cursor to get the next page; null on the last page.
Example 200 answer of List the webhook events
{
  "data": [
    {
      "event": "scan_completed",
      "group": "Site Crawler",
      "label": "Scan completed",
      "description": "Every finished crawl, with or without broken links."
    }
  ],
  "has_more": true,
  "next_cursor": "eyJ2IjoxfQ.opaque"
}