---
title: "List the report catalogue, with a site's row counts"
method: GET
path: "/v1/reports"
tags: ["reports"]
---

# List the report catalogue, with a site's row counts

`GET /v1/reports`

## Request

- Base URL: `https://frontshelf.io/api`
- URL: `https://frontshelf.io/api/v1/reports`
- Auth: HTTP bearer

Every report Frontshelf exports from a committed crawl (links, images, security, canonicals, hreflang, JavaScript, sitemaps, structured data, Lighthouse, accessibility, chains, URL Inspection, the crawl and issues overviews) plus the branded PDF, each with its id and the exact header row it writes. Without `site` it is free and reads no crawl. With `site` (and `crawl_seq`) each report carries `rows` for that crawl, as the Reports screen shows: `rows: null` is not counted yet, never zero, and `counts` says whether counting is done. A report whose source the crawl did not join is `rows: null` with `unavailable`; one with parts missing carries `note`. Filter with `group`. Next: reports_export with a report id for a download link.

## Query parameters

- `site` string: Site ID (site_…), origin (https://example.com), or bare domain, resolved server-side; the response carries the canonical ID. Pass it for each report's row count on one committed crawl; omit for the catalogue alone (free, reads no crawl).
- `crawl_seq` integer: Which committed crawl to count; omit for the site's current accepted crawl. Read only with `site`.
- `group` string: Only reports in this group (links, images, security, ...).

## Response `200`

List the report catalogue, with a site's row counts

- object
  - `summary` string, required: The answer in one or two sentences, with the numbers it rests on.
  - `warnings` string[], required: What limits this answer (a cap, a read that was cut short). Empty when nothing does.
  - `next_actions` object[], required: What to call next, best first. Follow them.
    - `capability` string, required: What to call next: a capability.
    - `arguments` object, required: Its arguments, complete; pass them as they are.
    - `instruction` string, required: What to do, written to you.
  - `provenance` object: With a site: the crawl the counts are for.
    - `crawl_seq` integer, nullable, required: The crawl the answer was read from; null when the site has none yet.
    - `data_freshness` string, required: When that crawl finished (ISO 8601) or `no completed crawl`; for a read of one committed crawl, `committed crawl (immutable snapshot)`, or `not committed (<reason>)` when nothing committed answered.
  - `crawl_seq` integer: With a site: the crawl counted.
  - `crawl_run_id` string: With a site: that crawl's run id.
  - `counts` union: Whether every row count is current, still being counted (read again in a moment), or stopped.
    - object
      - `status` 'counted', required
      - `counted_at` string, required
    - object
      - `status` 'counting', required
      - `done` integer, required
      - `total` integer, required
      - `since` string, required
      - `waiting_for` string, nullable, required: The heavy read the count is queued behind, or null while it runs.
    - object
      - `status` 'failed', required
      - `done` integer, required
      - `total` integer, required
      - `reason` string, required
      - `at` string, required
  - `items` object[], required: The reports, in catalogue order.
    - `id` string, required: The report's current id, the one reports_export takes.
    - `name` string, required
    - `group` string, required: The report's group (links, images, security, ...).
    - `format` 'rows' | 'chains' | 'summary' | 'sitemap', required: The report's shape: `rows` one row per item, `chains` redirect and canonical chains, `summary` a crawl-wide table, `sitemap` the sitemap's selection as rows.
    - `headers` string[], required: The exact header row the export writes.
    - `description` string, required
    - `rows` integer, nullable: With a site: the rows this export would stream for the crawl. Null means not counted yet, or unavailable; never zero.
    - `counted_at` string, nullable: With a site: when the count was taken (ISO 8601); null until it is.
    - `unavailable` object, nullable: With a site: why this crawl cannot answer the report (a source it needs did not join); reports_export refuses it with the same sentence.
      - `short` string, required: The reason in a few words.
      - `reason` string, required: The crawl's own sentence.
    - `note` string, nullable: With a site: what a report with some parts missing does not contain.
  - `pdf` object, required: The branded PDF: reports_export with report_id `pdf`.
    - `id` 'pdf', required
    - `name` string, required
    - `description` string, required
  - `groups` string[], required: Every group, for `group`.

## Other responses

- `400`: VALIDATION_FAILED
- `401`: UNAUTHENTICATED
- `403`: SCOPE_DENIED
- `404`: SITE_NOT_FOUND, NOT_FOUND
- `409`: AMBIGUOUS_SITE, AGENT_STOPPED
- `503`: DEPENDENCY_UNAVAILABLE

---

[API](https://skmtc.dev/frontshelf/apis/frontshelf-api.md) · [All operations](https://skmtc.dev/frontshelf/apis/frontshelf-api/llms.txt) · [OpenAPI document](https://skmtc.dev/frontshelf/apis/frontshelf-api/revisions/ce3602d26c7c?raw)
