AI Sources

Get AI sources data for a specific check

Changed on

Get full AI Sources data for a specific historical check: the summary stored on that check under summary, in exactly the dashboard's shape and read the same way — per engine, never pooled; retrieved, never cited; only a missing core host is a page to get onto; actionHint.text and summary.limits.sentences are rendered verbatim. The window it pools over (up to 5 published checks, this one first) is on summary.window. Set includeAnswers=true to also get what the engines actually said: every question sent, the answer text, the companies read out of it in order of first mention, and the pages the engine retrieved with the passage it handed back for each — plus engineStatus, one entry per engine the check asked. That block is large; narrow with engine= (one engine) or promptIndex= (one question). No filter changes any number under summary; ranks are stable under filtering. Counts are counts, never rates: report figures as n of N answers and never as a percentage or a share — the question set is small by design, and a share computed from it is false precision. Questions we could not read are listed separately in unansweredQueries, and questions an engine was read for and showed no answer to in noAnswerShown — three different facts, and none of them is 'not named'. A malformed id answers 400 invalid_check_id; an id that does not belong to this project answers 404 check_not_found; a check that exists but has no published summary — still running, or abandoned (no engine produced a usable answer, or the page stage could not be closed) — answers 404 run_not_summarized, which is a different fact from check_not_found: the check exists, it has nothing to report.

get/v1/projects/{projectId}/ai-sources/history/{checkId}

Request

  • Base URL: https://api.competlab.com
  • URL: https://api.competlab.com/v1/projects/{projectId}/ai-sources/history/{checkId}
  • Auth: API key in header CL-API-Key

Path parameters

checkIdstring required
Example:507f1f77bcf86cd799439012

Check ID

projectIdstring required
Example:507f1f77bcf86cd799439011

Project ID

Query parameters

includeAnswersboolean

Set true to include what the engines actually said — every question sent, the answer text, the companies read out of it in order of first mention, and the pages the engine RETRIEVED to write it, with the passage it handed back for each. Off by default because the block is large: up to 8 answers per engine, each carrying the engine's full retrieved page list, which for a searching engine can run to dozens of pages with a passage each. Narrow with engine= or promptIndex= rather than fetching everything. The answer text is the engine's wording, not CompetLab's assessment; the pages are retrieved, never cited.

engine'perplexity' | 'google_ai_overviews'

The OTHER engines that also retrieved this host this check. Empty means only this engine did. Membership, never a count.

Return only this engine's answers. Requires includeAnswers=true. Narrows answers, unansweredQueries and noAnswerShown; changes nothing under summary and does not narrow engineStatus.

promptIndexnumber

Return only the answers for this question, across every engine. Requires includeAnswers=true. Zero-based: the question's position in the check's question list, matching promptIndex on each answer.

view'compact' | 'full'
Example:compact

How much of the response to return. compact: summary.pages and summary.brands are one page of rows each, with summary.pagesPage and summary.brandsPage saying where it sits (the customer's own brand row is always included); each summary.coreHosts[] lists its pages as pageUrls, every one a row of summary.pages reachable with pagesHost. Every other field is unchanged. full: every row of every list, as stored — large, and meant for export rather than for reading. Omitted, the API's default view applies: compact on /v1.

pagesHoststring
Example:g2.com

Return only the rows of summary.pages on this host, matched exactly and case-insensitively; a leading www. is ignored on both sides, so www.g2.com and g2.com are the same host. Use a summary.coreHosts[].host to read that host's pages. summary.pagesPage.total counts the rows after this filter. Pages the compact view: sent without view it selects the compact view, and beside view=full it is refused with paging_requires_compact_view.

pagesOffsetnumber

Rows of summary.pages to skip, in the order the list is stored. Default 0. Pages the compact view: sent without view it selects the compact view, and beside view=full it is refused with paging_requires_compact_view.

pagesLimitnumber
Example:10

Rows of summary.pages to return, 1 to 100. Default 10. Pages the compact view: sent without view it selects the compact view, and beside view=full it is refused with paging_requires_compact_view.

brandsOffsetnumber

Rows of summary.brands to skip, in the order the list is stored. Default 0. Pages the compact view: sent without view it selects the compact view, and beside view=full it is refused with paging_requires_compact_view.

brandsLimitnumber
Example:10

Rows of summary.brands to return, 1 to 200. Default 10. Pages the compact view: sent without view it selects the compact view, and beside view=full it is refused with paging_requires_compact_view.

includeSummaryboolean
Example:true

Whether to return summary. Omitted, /v1 returns it unless includeAnswers=true — a read for the answers rarely needs the summary again, and the summary is most of the response — and a param that pages a summary list returns it too. Set it explicitly to override; false beside a paging param is refused with paging_requires_summary.

Response

Example response

{
  "item": {
    "readingGuide": {
      "summary.pages": "Pages the engines RETRIEVED while answering, never pages they cited."
    },
    "checkId": "507f1f77bcf86cd799439012",
    "completedAt": "2026-09-04T10:00:00.000Z",
    "summary": {
      "customerDomain": "mycompany.com",
      "window": {
        "checkIds": [
          "507f1f77bcf86cd799439012",
          "507f1f77bcf86cd799439011"
        ],
        "since": "2026-08-01T10:00:00.000Z",
        "perEngine": {
          "perplexity": {
            "checkIds": [
              "507f1f77bcf86cd799439012"
            ]
          },
          "google_ai_overviews": {
            "checkIds": [
              "507f1f77bcf86cd799439012"
            ]
          }
        }
      },
      "perEngine": {
        "perplexity": {
          "engineDataAvailable": {
            "reason": "no_usable_answer"
          },
          "answersAsked": 8,
          "answersReceived": 7,
          "answersAbsent": 1,
          "answersWithoutRetrieval": 1,
          "answersNamingCustomer": 3,
          "answersRetrievingOwnPage": 4,
          "pagesRetrieved": 131,
          "hostsRetrieved": 58,
          "hostsOnlyThisEngine": 33,
          "engineCoreSize": 35,
          "pagesRead": 118,
          "pagesUnreadable": 9,
          "pagesNotFetched": 4,
          "ownPagesRetrieved": 6,
          "independentPagesNamingCustomer": {
            "floor": 4,
            "ceiling": 6
          },
          "topHosts": [
            {
              "host": "g2.com",
              "pages": 3,
              "alsoRetrievedBy": [
                "google_ai_overviews"
              ]
            }
          ]
        },
        "google_ai_overviews": {
          "engineDataAvailable": {
            "reason": "no_usable_answer"
          },
          "answersAsked": 8,
          "answersReceived": 7,
          "answersAbsent": 1,
          "answersWithoutRetrieval": 1,
          "answersNamingCustomer": 3,
          "answersRetrievingOwnPage": 4,
          "pagesRetrieved": 131,
          "hostsRetrieved": 58,
          "hostsOnlyThisEngine": 33,
          "engineCoreSize": 35,
          "pagesRead": 118,
          "pagesUnreadable": 9,
          "pagesNotFetched": 4,
          "ownPagesRetrieved": 6,
          "independentPagesNamingCustomer": {
            "floor": 4,
            "ceiling": 6
          },
          "topHosts": [
            {
              "host": "g2.com",
              "pages": 3,
              "alsoRetrievedBy": [
                "google_ai_overviews"
              ]
            }
          ]
        }
      },
      "matrix": [
        {
          "promptId": "7f3c1a2e-9d44-4c8b-9f0e-2b6a5c9d7e10",
          "promptText": "Which email warm-up tools are safe to use with a Google Workspace domain?",
          "cells": {
            "perplexity": {
              "companiesNamed": 6,
              "webSearch": {
                "performed": true,
                "completedSearchCount": 3,
                "reason": "NO_SEARCH_ATTEMPTED"
              },
              "pagesRetrieved": 14,
              "pagesRead": 12,
              "pagesUnreadable": 1,
              "pagesNotFetched": 1,
              "pagesNamingCustomer": {
                "floor": 4,
                "ceiling": 6
              },
              "ownPagesRetrieved": 1
            },
            "google_ai_overviews": {
              "companiesNamed": 6,
              "webSearch": {
                "performed": true,
                "completedSearchCount": 3,
                "reason": "NO_SEARCH_ATTEMPTED"
              },
              "pagesRetrieved": 14,
              "pagesRead": 12,
              "pagesUnreadable": 1,
              "pagesNotFetched": 1,
              "pagesNamingCustomer": {
                "floor": 4,
                "ceiling": 6
              },
              "ownPagesRetrieved": 1
            }
          }
        }
      ],
      "brands": [
        {
          "domain": "competitor.com",
          "name": "Competitor Inc",
          "rankByPresence": 2,
          "answers": {
            "answersNaming": 5,
            "answersReceived": 16,
            "presence": 31,
            "presenceLow": 14,
            "presenceHigh": 56
          },
          "answersRetrievingOwnSite": {
            "answersNaming": 5,
            "answersReceived": 16,
            "presence": 31,
            "presenceLow": 14,
            "presenceHigh": 56
          },
          "enginesNaming": [
            "perplexity"
          ],
          "perEngine": {
            "perplexity": {
              "answers": {
                "answersNaming": 5,
                "answersReceived": 16,
                "presence": 31,
                "presenceLow": 14,
                "presenceHigh": 56
              },
              "independentPagesNaming": {
                "floor": 4,
                "ceiling": 6
              },
              "pagesRead": 118,
              "ownPagesRetrieved": 2
            },
            "google_ai_overviews": {
              "answers": {
                "answersNaming": 5,
                "answersReceived": 16,
                "presence": 31,
                "presenceLow": 14,
                "presenceHigh": 56
              },
              "independentPagesNaming": {
                "floor": 4,
                "ceiling": 6
              },
              "pagesRead": 118,
              "ownPagesRetrieved": 2
            }
          }
        }
      ],
      "brandsPage": {
        "limit": 10,
        "total": 96,
        "hasMore": true
      },
      "overlap": {
        "hostsInCore": 25,
        "perEngine": {
          "perplexity": {
            "hostsRetrieved": 58,
            "hostsOnlyThisEngine": 33
          },
          "google_ai_overviews": {
            "hostsRetrieved": 58,
            "hostsOnlyThisEngine": 33
          }
        }
      },
      "funnel": {
        "coreHosts": 25,
        "alreadyNamingCustomer": 19,
        "unreadable": 2,
        "missing": 4,
        "missingPublishers": 3,
        "missingCompetitorOwned": 1
      },
      "coreHosts": [
        {
          "host": "g2.com",
          "ownedBy": "competitor.com",
          "kindCheckedAt": "2026-09-04",
          "actionHint": {
            "code": "sources_retrieved_not_cited",
            "text": "Retrieved, never cited: these are the pages the engine pulled back while answering; which of them it leaned on is not something the engines disclose."
          },
          "engines": [
            "perplexity",
            "google_ai_overviews"
          ],
          "seenInChecks": {
            "perplexity": {
              "checkIds": [
                "507f1f77bcf86cd799439012"
              ]
            },
            "google_ai_overviews": {
              "checkIds": [
                "507f1f77bcf86cd799439012"
              ]
            }
          },
          "brandsNamed": [
            "competitor.com"
          ],
          "pages": [
            {
              "key": "g2.com/categories/email-warm-up",
              "url": "https://www.g2.com/categories/email-warm-up",
              "host": "g2.com",
              "title": "Best Email Warm-Up Software",
              "engines": [
                "perplexity",
                "google_ai_overviews"
              ],
              "ownedBy": "competitor.com",
              "fetchedAt": "2026-09-04T10:00:00.000Z",
              "brandsNamed": [
                "competitor.com",
                "rival.io"
              ],
              "excerpt": "…the most reliable options this year are Competitor Inc and Rival…"
            }
          ],
          "pageUrls": [
            "https://www.g2.com/categories/email-warm-up"
          ]
        }
      ],
      "ownPageRetrievals": [
        {
          "promptId": "7f3c1a2e-9d44-4c8b-9f0e-2b6a5c9d7e10",
          "pages": [
            {
              "key": "mycompany.com/pricing",
              "url": "https://mycompany.com/pricing",
              "title": "Pricing — My Company"
            }
          ],
          "companiesNamed": [
            "competitor.com",
            "rival.io"
          ]
        }
      ],
      "pages": [
        {
          "key": "g2.com/categories/email-warm-up",
          "url": "https://www.g2.com/categories/email-warm-up",
          "host": "g2.com",
          "title": "Best Email Warm-Up Software",
          "engines": [
            "perplexity",
            "google_ai_overviews"
          ],
          "ownedBy": "competitor.com",
          "fetchedAt": "2026-09-04T10:00:00.000Z",
          "brandsNamed": [
            "competitor.com",
            "rival.io"
          ],
          "excerpt": "…the most reliable options this year are Competitor Inc and Rival…"
        }
      ],
      "pagesPage": {
        "limit": 10,
        "total": 96,
        "hasMore": true,
        "host": "g2.com"
      },
      "limits": {
        "pagesRetrieved": 153,
        "pagesRead": 140,
        "pagesUnreadable": 9,
        "pagesNotFetched": 4,
        "pagesTruncated": 3,
        "unreadableByReason": {
          "bot_protection": 5,
          "host_blocked_recently": 2,
          "text_too_short": 1,
          "timeout": 1
        },
        "textSourceMix": {
          "body": 140,
          "snippet_only": 9,
          "none": 4
        },
        "sentences": [
          {
            "code": "sources_retrieved_not_cited",
            "text": "Retrieved, never cited: these are the pages the engine pulled back while answering; which of them it leaned on is not something the engines disclose."
          }
        ]
      }
    },
    "answers": [
      {
        "promptId": "7f3c1a2e-9d44-4c8b-9f0e-2b6a5c9d7e10",
        "promptText": "Which email warm-up tools are safe to use with a Google Workspace domain?",
        "askedIn": {
          "locationName": "United States",
          "languageName": "English"
        },
        "answerText": "For a Google Workspace domain, the safest warm-up tools are Competitor Inc and Rival, both of which…",
        "companiesNamed": [
          {
            "rank": 1,
            "name": "Competitor Inc",
            "domain": "competitor.com"
          }
        ],
        "sources": [
          {
            "url": "https://www.g2.com/categories/email-warm-up",
            "domain": "g2.com",
            "title": "Best Email Warm-Up Software",
            "snippet": "Warm-up tools gradually increase sending volume so that mailbox providers…",
            "publishedAt": "2026-05-12",
            "resolvedFrom": "https://www.google.com/goto?url=…"
          }
        ],
        "searchQueries": [
          "email warm-up tools Google Workspace safe"
        ],
        "webSearch": {
          "performed": true,
          "completedSearchCount": 3,
          "reason": "NO_SEARCH_ATTEMPTED"
        }
      }
    ],
    "unansweredQueries": [
      {
        "promptIndex": 5,
        "promptId": "7f3c1a2e-9d44-4c8b-9f0e-2b6a5c9d7e10",
        "promptText": "Which email warm-up tools have a free plan?",
        "reason": "no_usable_answer"
      }
    ],
    "noAnswerShown": [
      {
        "promptIndex": 3,
        "promptId": "7f3c1a2e-9d44-4c8b-9f0e-2b6a5c9d7e10",
        "promptText": "Which email warm-up tools have a free plan?",
        "reason": "no_ai_overview_shown"
      }
    ],
    "engineStatus": {
      "perplexity": {
        "reported": true,
        "completedAt": "2026-09-04T10:00:00.000Z",
        "questionsAsked": 8,
        "answersReceived": 7,
        "answersAbsent": 1
      },
      "google_ai_overviews": {
        "reported": true,
        "completedAt": "2026-09-04T10:00:00.000Z",
        "questionsAsked": 8,
        "answersReceived": 7,
        "answersAbsent": 1
      }
    }
  }
}

Changes

    • breaking

      the response property //////// became nullable for the status

    • breaking

      the response property / became optional for the status

    • breaking

      the response property //////// became optional for the status

    • warning

      added the new nothing_to_return enum value to the / response property for the response status

    • warning

      added the new paging_requires_compact_view enum value to the / response property for the response status

    • warning

      added the new paging_requires_summary enum value to the / response property for the response status

    • info

      added the new optional query request parameter brandsLimit

    • info

      added the new optional query request parameter brandsOffset

    • info

      added the new optional query request parameter includeSummary

    • info

      added the new optional query request parameter pagesHost

    • info

      added the new optional query request parameter pagesLimit

    • info

      added the new optional query request parameter pagesOffset

    • info

      added the new optional query request parameter view

    • info

      added the optional property / to the response with the status

    • info

      added the optional property ////// to the response with the status

    • info

      added the optional property //////// to the response with the status

    • info

      added the optional property ////// to the response with the status

    • warning

      added the new bad_request enum value to the / response property for the response status

    • warning

      added the new not_found enum value to the / response property for the response status