---
title: "Search Console keyword cannibalization (Growth+)"
method: GET
path: "/search_console/cannibalization"
tags: ["Search Console"]
---

# Search Console keyword cannibalization (Growth+)

`GET /search_console/cannibalization`

## Request

- Base URL: `https://api.llmpulse.ai/api/v1`
- URL: `https://api.llmpulse.ai/api/v1/search_console/cannibalization`
- Auth: API key in header `Authorization`

Queries with at least min_impressions impressions for which two or more pages each take at least min_share (default 0.1) of the query's impressions, most impressions first, each with its competing pages (share, impressions, clicks, ctr, position). Use it to find the keywords several of the site's pages fight over, and decide which pages to merge, redirect or differentiate. Google counts page-by-query impressions per page, so a query's impressions here can exceed its property-wide figure. Reads Google's top 25,000 page-query rows per property (truncated: true when reached). With output=flat or csv, each competing page is its own row, with its URL in page_url. Requires a connected Search Console property (Growth+). Live reads only: under stored reads it returns ERR_INVALID_PARAM. Live reads return ERR_SEARCH_CONSOLE_ACCESS_REVOKED (403) for revoked Google access; reconnect the property in Preferences > Project Settings > Data Connections. They return ERR_SEARCH_CONSOLE_UPSTREAM (503) when Google Search Console is unavailable or over quota; wait for the number of seconds in Retry-After before retrying.

## Query parameters

- `project_id` integer, required
- `property` string
- `range` integer
- `from` string, date
- `to` string, date
- `min_impressions` integer
- `min_share` number
- `page` integer
- `per_page` integer
- `output` 'flat' | 'csv'
- `search_type` 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews'
- `filters` string
- `data_state` 'final' | 'all'
- `aggregation_type` 'auto' | 'byPage' | 'byProperty'

## Response `200`

Competing pages per query

- SearchConsoleCannibalizationResponse
  - `project_id` integer
  - `property` SearchConsoleProperty
    - `id` string: Property id, e.g. sc-domain:example.com
    - `name` string
  - `properties` SearchConsoleProperty[]: With a list or all in the property parameter, the properties whose data the response holds (instead of property)
    - `id` string: Property id, e.g. sc-domain:example.com
    - `name` string
  - `excluded_properties` SearchConsoleExcludedProperty[]: With a list or all, selected properties left out because another selected property already counts them
    - `id` string
    - `name` string
    - `covered_by` string: The selected property that already counts this one
  - `property_errors` SearchConsolePropertyError[]: With a list or all, selected properties Google refused, left out of the figures
    - `id` string
    - `name` string
    - `code` 'ERR_SEARCH_CONSOLE_ACCESS_REVOKED' | 'ERR_SEARCH_CONSOLE_UPSTREAM'
    - `message` string
    - `retry_after` integer: Seconds to wait before retrying, for ERR_SEARCH_CONSOLE_UPSTREAM
  - `from` string, date
  - `to` string, date
  - `data_through` string, date, nullable: Latest date Google has published for the property, or for every combined property (it lags 2-3 days). Later days are missing, not zero.
  - `min_impressions` integer
  - `min_share` number
  - `page` integer
  - `per_page` integer
  - `total` integer: Rows in the report before paging
  - `truncated` boolean: Present (true) when Google returned its 25,000-row maximum for a property, so the report covers its top rows only
  - `data` object[]
    - `query` string
    - `impressions` integer
    - `clicks` integer
    - `ctr` number: 0..1 fraction
    - `position` number: Impression-weighted average position
    - `pages` object[]: Pages taking at least min_share of the query's impressions, most impressions first
      - `page` string
      - `share` number: The page's fraction (0..1) of the query's impressions
      - `impressions` integer
      - `clicks` integer
      - `ctr` number: 0..1 fraction
      - `position` number: Impression-weighted average position
  - `request_id` string

## Other responses

- `401`: Authentication failed
- `403`: Plan below Growth (ERR_PLAN_REQUIRED), or Google revoked the project's Search Console access (ERR_SEARCH_CONSOLE_ACCESS_REVOKED): reconnect the property
- `404`: Resource not found
- `422`: Invalid parameters
- `503`: Upstream provider unavailable, retry after the number of seconds in the Retry-After header: Google's own value when it sent one, otherwise 900 after a quota error and 60 after an outage

## Changes

- **2026-11-03** `38a31f123641`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/llmpulse/apis/llm-pulse-api/changes/search_console/cannibalization/get.md)

---

[API](https://skmtc.dev/llmpulse/apis/llm-pulse-api.md) - [All operations](https://skmtc.dev/llmpulse/apis/llm-pulse-api/llms.txt) - [OpenAPI document](https://skmtc.dev/llmpulse/apis/llm-pulse-api/revisions/38a31f123641?raw)
