Skip to main content
GET /v1/monitors/{id}/analytics (reference) returns every number in a monitor’s report from one set of answers: one window, one set of filters, and the same window before it for comparison. Build every panel of your own report from this endpoint, and read quality before the numbers. Reading a report costs nothing.

Query parameters

The window is half-open and in UTC: since is included, until is not. The previous window has exactly the same length, ends at since and uses the same filters, so every comparison is like for like. Send each parameter once.

Example

For example, a brand monitor that asks ChatGPT two prompts once a day with samples: 5 (ten answers a day), filtered to ChatGPT over two days, returns:
Reading it: the brand was named in 9 of 20 ChatGPT answers (45%), down 15 points from the two days before. Northwind Audio was named in more answers, and “are cheap earbuds worth it” is the weakest prompt, with 4 answers that named a competitor and not the brand. quality.lowSample is true, so treat the change as a signal to check, not a trend.

Response sections

Rate objects

stats, previous, each engineRates and series entry, each prompt and each cell carry the same fields:

Cells

A cell is one prompt on one engine. Besides the rate object and previous, it carries: Each id is null when no answer qualifies. Open one with GET /v1/monitors/{id}/answers/{taskId}.

Brands and share of voice

Each entry in brands has name, mentions, sampleSize, mentionRate, shareOfVoice, previousMentionRate, previousShareOfVoice and configured (false for a brand named in the window that is no longer on the monitor).

What the numbers mean

GET /v1/monitors/capabilities returns these definitions as metrics, so a client can show them next to the numbers.
  • mentionRate is 100 × mentioned / scored answers, for the window, each engine, each day and each cell. It is weighted by answers, not averaged across engines, so a busy engine is not outvoted by a quiet one.
  • citationRate has the same shape for answers that cited one of your domains. With no domains it is always 0, because citation tracking is off.
  • A brand’s rate divides by its own sampleSize. For your brand that is every scored answer. For a competitor it is only the answers scored while it was on the monitor, so a competitor added today is measured from today. A competitor’s mentionRate is null when some answers in the window were scored before scoring context was stored, because what they were matched against is unknown.
  • shareOfVoice is 100 × that brand's mentions / all tracked brand mentions in the window, so the shares of one window add up to 100 (quality.trackedBrandMentions is the denominator). It compares brands inside the answers you collected for these prompts. It is not market share and not a ranking of visibility.
  • competitorOnly and opportunities count answers that named a competitor while your brand was absent: the gap you can act on.
  • null is not 0. A rate is null when there were no answers to divide by. 0 means there were answers and none matched.
  • An answer with no text counts as not mentioned. A completed task that returned no answer stays in the denominator; quality.noAnswerObservations counts them. A failed task is excluded from every rate and appears only in health. A broken engine shrinks the sample rather than showing up as absence.
  • position on a scored answer is the character offset of the first match of your brand: a proxy for prominence, not a rank. It is null when the brand is absent.

When changes are withheld

changes, each cell’s mentionRateChangePp, and each brand’s previousMentionRate and previousShareOfVoice are null, and quality.comparable is false, when the two windows cannot be compared. quality.comparisonReason says why: Every answer keeps the definition it was scored with, and quality.scoringVersions lists the distinct definitions across both windows (legacy for answers without one). Changing your aliases or competitors never rewrites past answers. The one exception is the weekly competitor read: when the competitors it finds change, the monitor’s stored answers are scored again against the new list.

Quality

Health

health has completed, failed, pending and topError (the most common error code among failed tasks) for the monitor’s tasks that are in flight or finished in the last 24 hours. healthScope is always recent_visible_tasks. It is a diagnostic for runs, independent of the window, and never part of a rate’s denominator.

Poll while a run is in flight

Every call returns the full report for the window and filters. While a run is in flight, health.pending counts its tasks that are still running. Read the report again once it reaches 0.

Category reports

A category monitor returns a different body from the same endpoint, with the same window, filters, quality, pauses and health:
  • stats and previous hold runs, named (answers that named at least one tracked brand) and namedRate. changes.namedRatePp is the change in points.
  • category holds the ranking:
For example, one category.brands entry:
  • rank orders brands by the number of answers that name them. A brand no answer named has rank: null.
  • mentionRate divides by the brand’s own sampleSize: the answers scored while it was on the list.
  • shareOfVoice is 100 × that brand's mentions / all brand mentions in the window, so the shares add up to 100.

Errors and limits

  • The window is at most 90 days.
  • Invalid parameters return 400 VALIDATION_ERROR with a message naming the problem: days with since or until, only one of since and until, a timestamp without a timezone, a span over 90 days, an until in the future, an engine that cannot be monitored, a prompt over 2,000 characters, or a repeated parameter.
  • A report too large to aggregate returns 400 VALIDATION_ERROR with “This report is too large”. Narrow the window, engine or prompt.
See Monitors for the codes every monitor endpoint shares.

Next steps

Sources and answers

The cited pages and the answers behind each number.

Events and alerts

Get notified when answers change.