Skip to the main content

Explore Carqo

132 results found

Search stays in your browser. Press Escape to close.

API reference

The Carqo analytics API, read from the same document the API serves.

Access

API access is by arrangement.

A key is made in the Carqo workspace by an owner or an administrator.

Words this page uses

Prompts
A prompt is a question put to an AI assistant. A prompt set is a group of them.
Visibility
Visibility is the share of checked answers that name the business.
Citations
A citation is a link to a web page in an AI answer.
Sources
Sources are the websites an AI answer names or links to.
Competitors
Competitors are the businesses chosen for comparison.

Carqo analytics API

Version v1, OpenAPI 3.1.0

Read-only access to what AI systems said about a business, and to the state of collection.

Three rules a consumer has to honour to render these figures correctly.

A rate of null means nothing was observed. It is not zero. Zero means answers came back and named nobody, and the two are opposite facts. Every rate carries its denominator in the field beside it.

An API answer is not what a person is shown by the assistant of the same name. describesConsumerSurface is false for provider_api, and a figure from it may not be presented as what a buyer sees.

liveVerified is always false. It means a real call to that vendor has been made and checked, and nothing in Carqo sets it automatically.

Base path

Every path below starts with this one. /api/v1/analytics

Same origin as the workspace.

Authentication

http bearer

A Carqo analytics key, as Authorization: Bearer or x-carqo-key. The scopes are analytics:read, analytics:evidence. Read-only. No scope here can start a run, change a spending limit or turn a schedule on.

Endpoints

GET /api/v1/analytics/status

Where collection stands

Queue depth, per-channel readiness and spending. failed, blocked and budgetExhausted are three figures with three different owners and are never summed.

Responses

  • 200 The current state.
  • 401 Missing, unknown or revoked key.
  • 403 The key does not carry analytics:read.

GET /api/v1/analytics/channels

What Carqo can ask, and what each channel is not

Implemented, configured and live verified are three separate columns. Consumer surfaces are listed as unsupported rather than omitted, because absence from a list reads as an oversight.

Responses

  • 200 The channel catalogue and coverage matrix.

GET /api/v1/analytics/prompt-sets/{promptSetId}/prompts

The questions, as revisions

Revisions rather than prompts. A reworded question becomes a new revision, and answers already collected stay pointed at the old one. Grouping by prompt id would mix two different questions.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

Responses

  • 200 Current revisions.
  • 404 No such question set.

GET /api/v1/analytics/prompt-sets/{promptSetId}/visibility

Visibility, citations and competitors, with denominators

presence was added on 27/10/2026 and nothing else changed. presence.window gives the whole London days the two figures are over. If the figures cannot be calculated, both are null and presence.unavailable explains why. presence.steadyPresence and presence.namedFirst each carry metric, state, reason, value, numerator, denominator, sampleCount, smallSample, excluded and explanation. A value of null means there was nothing to count, never zero. smallSample is true under 30. steadyPresence counts question and channel pairs named on half or more of their checked days. A checked day is a London day with a counted answer for that pair. An answer cut short that did not name the business is not counted. Only pairs checked on at least pairs.minimumDays separate days are counted. pairs.steady and pairs.occasional split those pairs. pairs.notEnoughDaysCount is how many pairs had fewer days, and they are never classed. pairs.notEnoughDays lists every one of them, each with promptRevisionId, channelId, provider, surface and checkedDays. channelId is null where no schedule collected the answers, and provider and surface then tell the pairs apart. The analytics MCP tool get_visibility lists only the first 10 of them and adds pairs.notEnoughDaysNote. The count is still the whole count. namedFirst counts the ordered lists that named the business at place 1, out of the ordered lists that gave it a place. Ordered lists that named the business with no place are left out and counted under excluded.list_position_unknown.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

  • from query, Optional

    • string
    • date-time

    Start of the window, inclusive. Defaults to thirty days before to.

  • to query, Optional

    • string
    • date-time

    End of the window. Defaults to now. Windows longer than 366 days are refused.

  • captureMode query, Optional

    • string
    • One of provider_api, manual_ui, authorised_browser

    Defaults to provider_api. Cohorts are never mixed, because a figure over API answers and one over records a person typed are different claims.

Responses

  • 200 Figures for the window.
  • 400 Unusable window.

GET /api/v1/analytics/prompt-sets/{promptSetId}/trend

The same figures over time, with a denominator on every period

A period with no valid observation carries a null rate, never a zero, and a period with nothing scheduled is absent rather than zeroed. sufficientForDirection is false below three periods, because two points are not a trend. The payload says so rather than leaving a consumer to know the rule.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

  • from query, Optional

    • string
    • date-time

    Start of the window, inclusive. Defaults to thirty days before to.

  • to query, Optional

    • string
    • date-time

    End of the window. Defaults to now. Windows longer than 366 days are refused.

  • captureMode query, Optional

    • string
    • One of provider_api, manual_ui, authorised_browser

    Defaults to provider_api. Cohorts are never mixed, exactly as on the visibility path.

  • dimension query, Optional

    • string
    • One of surface, prompt, entity, market
    • Default surface

    market is the country that was actually SENT to the provider, and it is not the locale. A locale is the language the question was written in. Grouping a location trend by locale would describe something else entirely.

  • buckets query, Optional

    • integer
    • Default 6
    • Lowest 2
    • Highest 24

    The window is divided into this many equal, non-overlapping periods, oldest first. Equal because two periods of different lengths are not comparable, and non-overlapping because an answer counted twice is counted twice.

Responses

  • 200 The series, per period and per key, each with its own denominator.
  • 400 Unusable window, dimension or bucket count.

GET /api/v1/analytics/prompt-sets/{promptSetId}/sources

What the answers cited, by domain

providerMade and proseOnly are separate counts. A URL that merely appeared in prose is not a citation the provider made.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

  • from query, Optional

    • string
    • date-time

    Start of the window, inclusive. Defaults to thirty days before to.

  • to query, Optional

    • string
    • date-time

    End of the window. Defaults to now. Windows longer than 366 days are refused.

Responses

  • 200 Cited domains.

GET /api/v1/analytics/prompt-sets/{promptSetId}/questions

Figures for each question, with its stage

Each row is one wording of one question, with asked, cameBack, settled, named and notNamed. rate is named over settled, and null where no answer settled it, never zero. stage is learning, comparing, buying or other. It comes from the words of the question, or the stage the owner chose for it. It does not measure what people want or how many ask. Rows come in the report's own order, questions doing worst first. Gaps come first, then the lowest rate, then the most answers settled. The order is not a ranking. limit and offset page through the rows, and nextOffset is where the next page starts, or null on the last. Only the first 500 rows can be read. rowsTotal is how many wordings there are, and cut is true when some cannot be read. An offset at or past the last readable row gives no rows, with the total still stated. Where the figures cannot be read, unavailable says why and the list is empty.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

  • from query, Optional

    • string
    • date-time

    Start of the window, inclusive. Defaults to thirty days before to.

  • to query, Optional

    • string
    • date-time

    End of the window. Defaults to now. Windows longer than 366 days are refused.

  • captureMode query, Optional

    • string
    • One of provider_api, manual_ui, authorised_browser

    Defaults to provider_api. Cohorts are never mixed.

  • limit query, Optional

    • integer
    • Default 100
    • Lowest 1
    • Highest 500

    How many question wordings to list. A value over the maximum is held to it. A value that is not a whole number of 1 or more is refused.

  • offset query, Optional

    • integer
    • Default 0
    • Lowest 0

    How many rows to skip, in the order the rows come. A value that is not a whole number of 0 or more is refused.

Responses

  • 200 The questions and their figures.
  • 400 Unusable window. A limit that is not a whole number of 1 or more. An offset that is not a whole number of 0 or more.
  • 404 No such question set.

GET /api/v1/analytics/prompt-sets/{promptSetId}/source-types

Cited websites by type, and cited pages by kind

The type lines count only websites an answer cited. A type comes from the address of the website, and a kind of page from words in its address. No page is opened. websitesTotal counts every website found, including websites that were only linked in the text or not cited. It can be more than the websites in the type lines. typeLines.own is the business's own website, kept apart from the other types. answersCitingOthersOnly counts answers that cited a website and never the business's own, and is null while the website is not verified. While nothing is measured, that figure, answersWithCitation, websitesShown and websitesTotal are null. typeLines and pageKinds are null while nothing is measured. When the list of websites or the list of pages was cut, cut is true and cutNote says what is counted.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

  • from query, Optional

    • string
    • date-time

    Start of the window, inclusive. Defaults to thirty days before to.

  • to query, Optional

    • string
    • date-time

    End of the window. Defaults to now. Windows longer than 366 days are refused.

  • captureMode query, Optional

    • string
    • One of provider_api, manual_ui, authorised_browser

    Defaults to provider_api. Cohorts are never mixed.

Responses

  • 200 The type lines and the page kinds.
  • 400 Unusable window.
  • 404 No such question set.

GET /api/v1/analytics/prompt-sets/{promptSetId}/league

Businesses named in two or more answers

This path takes no window. It reads two periods of seven London days, the one ending on the day of the newest stored answer and the seven days before it. current and previous give the first and last day of each and the answers read in it. Another business named in fewer than two answers in the current period has no row. namedTotal still counts the names left out, so the shares can add up to less than 100. Your own business's row, where there is one, can show 0 or 1, because the two-answer rule applies to other businesses. In each row, answersNaming is a count of answers, and mentionRate and shareOfVoice are percentages. averagePosition and namedFirst are null where the name was never in a list. namedFirst is a fraction from 0 to 1, not a percentage. changePoints is null where the earlier period held too few answers. capped is true when the read stopped at 6,000 answers, so older answers may be missing. changePoints is then null. more is how many businesses were left out because the list holds at most 50 rows. The business itself has you set. Rows follow the mention rate. No row has a place or a rank. A name may be a directory or a supplier. notes holds the workspace page's own words on what the list is and is not. emptyNote is set only when the list has no row at all. Where no answer was read, answersRead is 0, more is 0 and capped is false. The other figures are null. A key may call this path 10 times a minute.

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

Responses

  • 200 The league.
  • 404 No such question set.
  • 429 More than 10 league requests on this key in a minute.

GET /api/v1/analytics/prompt-sets/{promptSetId}/runs

Collection runs, paged

Parameters

  • promptSetId path, Required

    • string
    • uuid

    A question set in the workspace the key belongs to. A set in another workspace answers 404, the same as one that does not exist.

  • limit query, Optional

    • integer
    • Default 50
    • Highest 200
  • cursor query, Optional

    • string

    Opaque. Read from the previous nextCursor, never built by hand. It carries the last row's requestedAt and id together, at the microsecond precision the column holds, not the millisecond a Date can round-trip. A keyset cursor rather than an offset, so a concurrent insert cannot make a consumer skip a row. It carries no tenant and no filter, and a cursor that does not parse is ignored rather than erroring. The response says so in cursorRejected.

Responses

  • 200 A page of runs, with nextCursor (null once there is no next page) and cursorRejected (true only when a supplied cursor could not be read).

Errors

An error answers with the status listed for the endpoint and this body.

Shared shapes

Meta

  • apiVersion string, Required
  • metricVersion string, Required. The calculation layer that produced these figures. A change makes older figures readable rather than wrong.
  • generatedAt string date-time, Required
  • orgId string uuid, Required

Error

Every refusal carries a status and a sentence. An error is never a 200 with an empty list.

  • error string, Required
Back to help