---
title: "The open issue queue, worst first"
method: GET
path: "/v1/issues"
tags: ["issues"]
---

# The open issue queue, worst first

`GET /v1/issues`

## Request

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

The open issue queue, worst first: each issue with its severity, state, affected pages, what it costs to fix and the version to pass back when you act on it. Open means not verified_resolved, ignored or no_longer_checked; `state: all` lists every state, any other state only that one. Omit `site` for every site this key can see; pass it for one site. A row is a summary: read the issue's work order with issues_get before you change anything. `staleness: not_seen_in_latest` means the latest crawl did not see the issue; that is not a fix, and only the verifier resolves an issue. `checked` names the sample a count is of; `effort.label` says the fix in its unit (`3 templates + 12 pages`, `1 fix`, `15 groups`). With `site`, `search` gives the clicks Google sent the issue's pages, or why not; `sort: clicks` orders one site's queue by them (search:read and the plan). `total` is exact; pass `page_info.next_cursor` back as `cursor` for the next page. Next: issues_get for the issue you will fix.

## Query parameters

- `site` string: Site ID (site_…), origin (https://example.com), or bare domain, resolved server-side; the response carries the canonical ID. Omit for every site this key can see.
- `state` 'open' | 'acknowledged' | 'ignored' | 'pending_fix' | 'awaiting_merge' | 'awaiting_deployment' | 'verification_queued' | 'verification_running' | 'verified_resolved' | 'verification_failed' | 'regression_detected' | 'needs_human_review' | 'no_longer_checked' | 'all': `open` (default): every issue that is not verified_resolved, ignored or no_longer_checked, so acknowledged, awaiting_deployment, the verification states and the rest are in it. `all`: every state. Any other value: exactly that state. An issue's own `state` field can read `open` too: that is the narrower lifecycle state, a new issue nobody has acknowledged yet.
- `sort` 'priority' | 'clicks': `priority` (default): worst first. `clicks`: one site's queue by the clicks Google gave each issue's pages (needs `site`, search:read and the plan).
- `limit` integer: Items per page (1 to 100).
- `cursor` string: The continuation from a previous page's page_info.next_cursor. Never construct one.

## Response `200`

The open issue queue, worst first

- 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.
  - `items` object[], required: The issues on this page in the `state` asked for (the open queue by default), worst first (by clicks with `sort: clicks`).
    - `id` string, required: The issue's id: issues_get, findings_list, the issue actions and verifications_start take it.
    - `site_id` string, required: The site the issue is on.
    - `rule_id` string, required: The check that fired (`metadata.missing_title`).
    - `severity` 'critical' | 'high' | 'medium' | 'low' | 'info', required: The check's severity, from `critical` to `info`.
    - `priority_score` number, required: The queue's order: the higher, the sooner.
    - `state` 'open' | 'acknowledged' | 'ignored' | 'pending_fix' | 'awaiting_merge' | 'awaiting_deployment' | 'verification_queued' | 'verification_running' | 'verified_resolved' | 'verification_failed' | 'regression_detected' | 'needs_human_review' | 'no_longer_checked', required: Where the issue is in its lifecycle. `open` here is the lifecycle state, a new issue nobody has acknowledged yet. Only a verification run sets `verified_resolved`. `no_longer_checked`: closed, not fixed, because its check cannot run (a setting or service off or not linked, a language spelling checks do not cover); it reopens when a crawl runs the check and finds it.
    - `ignore_reason_code` string, nullable, required: The stated reason while `state` is ignored; null otherwise.
    - `version` integer, required: Pass it back as `expected_version` when you act on the issue.
    - `affected_url_count` integer, required: The pages the check fired on in the crawl that last saw the issue.
    - `checked` object, nullable, required: The sample `affected_url_count` is of: 14 beside `{pages: 94, of: 1964}` is 14 of the 94 pages checked, not of the site. Null: the count is of the whole crawl.
      - `source` 'axe' | 'lighthouse' | 'inspection', required
      - `pages` integer, required
      - `of` integer, required
    - `effort` object, nullable, required: What the issue costs to fix. Null when the crawl carries no URL patterns.
      - `kind` 'site' | 'groups' | 'templates' | 'pages' | 'mixed', required
      - `templates` integer, required
      - `pages` integer, required
      - `units` integer, required
      - `label` string, required: The fix in its own unit: `3 templates + 12 pages`, `1 fix` (a site-wide cause, one per host), `41 pages`, or `15 groups` (a duplicate rule: one fix per set of pages sharing one title, description or heading). A template is a URL pattern: one change fixes every page under it.
      - `leverage` number, nullable, required: The points the check costs the score per unit (templates + pages, hosts, or groups): the higher, the more one fix buys. Null when the score cannot price it.
    - `staleness` 'current' | 'not_seen_in_latest', required: `not_seen_in_latest`: the latest crawl did not see it. That is not a fix; only the verifier resolves an issue.
    - `search` union: On a one-site list only: each site's figures come from its own crawl.
      - object
        - `state` 'ready', required
        - `extent` 'pages' | 'linking' | 'site' | 'not_pages', required
        - `pages` integer, required
        - `listed` integer, required
        - `clicks` object, nullable, required
          - `open` number, required
          - `ignored` number, required
        - `impressions` object, nullable, required
          - `open` number, required
          - `ignored` number, required
        - `window` object, required
          - `start` string, required
          - `end` string, required
        - `crawl_seq` integer, required
        - `label` string, required: What the clicks are of (`Clicks`, or `Clicks on pages linking here` for a broken link).
      - object
        - `state` 'unavailable', required
        - `reason` 'no_crawl' | 'before_store' | 'not_connected' | 'not_ready' | 'not_in_latest', required
        - `sentence` string, required
      - object
        - `state` 'withheld', required
        - `reason` 'scope' | 'gated', required: `scope`: the key lacks search:read; `gated`: the site's plan lacks Search.
      - object
        - `state` 'too_large', required
        - `sentence` string, required
    - `first_seen_crawl_seq` integer, required: The crawl that first saw the issue.
    - `last_seen_crawl_seq` integer, required: The latest crawl that saw the issue.
    - `updated_at` string, required: When the issue last changed (ISO 8601).
    - `dashboard_url` string, required: The issue in Frontshelf, to hand your human (app-relative).
  - `truncated` boolean, required: True when more issues match than this page holds.
  - `total` integer, required: How many issues match the `state` asked for, exactly; not the rows of this page.
  - `truncation` object, required: Whether the list was cut, and the call that reads the rest.
    - `truncated` boolean, required: True when more match than this answer holds.
    - `omitted_count` integer, required: Rows this answer knows it left out; 0 on a keyset page, which cannot count them (read `total`).
    - `reason` string: Why the list was cut (`page_limit`).
    - `continue_with` object: The call that reads the next page, arguments complete.
      - `capability` string, required
      - `arguments` object, required
  - `page_info` object, required: Where this page sits in the whole list.
    - `has_more` boolean, required: True when another page follows.
    - `next_cursor` string, nullable, required: Pass it back as `cursor` for the next page; null at the end.
    - `estimated_total` integer, required: How many match in all, after the filters; not the rows of this page.

## Other responses

- `400`: INVALID_CURSOR, SEARCH_SPEC_INVALID, VALIDATION_FAILED
- `401`: UNAUTHENTICATED
- `402`: BILLING_REQUIRED
- `403`: SCOPE_DENIED
- `404`: SITE_NOT_FOUND
- `409`: AMBIGUOUS_SITE, SEARCH_VIEW_EXPIRED, 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)
