---
title: "SEO opportunities"
method: GET
path: "/sites/{site}/seo-opportunities"
tags: ["Analytics"]
---

# SEO opportunities

`GET /sites/{site}/seo-opportunities`

## Request

- Base URL: `https://api.onelence.com/v1`
- URL: `https://api.onelence.com/v1/sites/{site}/seo-opportunities`
- Auth: one of:
  - OAuth 2 (authorization code, authorization URL `https://api.onelence.com/oauth/authorize`, token URL `https://api.onelence.com/oauth/token`, scopes: `analytics:read`)
  - HTTP bearer

SEO candidates from the canonical workspace projection, with disposition, reason, Work action state, and suggested next step. The summary includes evidence readiness, search metrics, and connection state. Without dates, the window is the latest 28 days Search Console reports (it lags about 2 days).

## Path parameters

- `site` string, required

## Query parameters

- `start` string
- `end` string
- `lane` 'grow_proven_pages' | 'recover_visibility' | 'fix_search_leakage' | 'create_new_coverage' | 'needs_evidence'
- `limit` integer
- `cursor` string

## Response `200`

Success.

- object
  - `object` 'list', required
  - `data` object[], required
    - `object` 'seo_opportunity', required
    - `id` string, required
    - `kind` string, required
    - `page` string, nullable, required
    - `query` string, nullable, required
    - `topic` string, nullable, required
    - `lane` 'grow_proven_pages' | 'recover_visibility' | 'fix_search_leakage' | 'create_new_coverage' | 'needs_evidence', required
    - `search_potential` 'high' | 'medium' | 'low' | 'missing', required
    - `page_value` 'high' | 'medium' | 'low' | 'missing', required
    - `confidence` 'high' | 'medium' | 'low' | 'missing', required
    - `urgency` 'high' | 'medium' | 'low' | 'missing', required
    - `effort` string, nullable, required
    - `page_visitors` number, nullable, required
    - `page_conversions` number, nullable, required
    - `title` string, required
    - `why` string, nullable, required
    - `next_step` string, nullable, required
    - `focus_queries` string[], required
    - `conflicts` string[], required
    - `disposition` 'ready_to_plan' | 'check_first' | 'explore_only' | 'in_work' | 'excluded', required
    - `primary_reason` string, required
    - `candidate_fingerprint` string, required
    - `action_state` 'opportunity' | 'evaluation' | 'work' | 'none' | 'unavailable', required
  - `has_more` boolean, required
  - `next_cursor` string, nullable, required
  - `summary` object, required
    - `state` string, required
    - `reason` string, nullable, required
    - `data_through` string, nullable, required
    - `google_connected` boolean, required
    - `bing_connected` boolean, required
    - `clicks` number, nullable, required
    - `impressions` number, nullable, required
    - `ctr` number, nullable, required
    - `average_position` number, nullable, required
    - `lanes` object, required
    - `candidate_readiness` string, required
    - `candidate_empty_state` string, nullable, required

## Other responses

- `400`: Invalid input; `error.param` names the field.
- `401`: Missing, expired or revoked token. WWW-Authenticate points to the resource metadata.
- `402`: subscription_required or upgrade_required; the error carries billing_url.
- `403`: insufficient_scope or admin_required.
- `404`: Unknown endpoint, site, source or record.
- `429`: Rate limited. Retry after Retry-After seconds.
- `500`: OneLence could not complete the request.

---

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