> ## Documentation Index
> Fetch the complete documentation index at: https://docs.querying.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitor Evidence: Cited Sources, Answers and Result Exports

> See which pages the engines cite, open the exact answer behind any number, and export a monitor's scored answers as JSON or CSV.

Every number in a [monitor report](/monitors/reports.md) comes from scored answers you can open. This page
covers the read endpoints that show them: which sources are cited, how citations move over time, the
answer behind one score, one prompt in detail, answers per location, and the full export. They read
stored results only, so they cost nothing.

| Endpoint | Answers |
| - | - |
| [`GET /v1/monitors/{id}/sources`](#which-sources-are-cited) | Which domains or pages are cited, with every row reachable by cursor. |
| [`GET /v1/monitors/{id}/citations`](#citations-over-time) | Citation totals and daily series for the top domains and pages. |
| [`GET /v1/monitors/{id}/answers/{taskId}`](#read-one-answer) | The stored answer behind one score. |
| [`GET /v1/monitors/{id}/prompt`](#one-prompt-in-detail) | One prompt's daily series, sources and recent answers. |
| [`GET /v1/monitors/{id}/grid`](#answers-by-location) | Answers per point of a monitor's location or grid. |
| [`GET /v1/monitors/{id}/results`](#export-scored-answers) | The scored answers themselves, as JSON or CSV. |

## Which sources are cited

`GET /v1/monitors/{id}/sources` ([reference](/api-reference/monitors/list-sources.md)) ranks the domains or
pages the engines cited, using the same window and filters as the report. It counts **distinct answers**,
not raw citations: a page cited three times in one answer counts once.

```bash theme={"theme":"css-variables"}
curl "https://api.querying.ai/v1/monitors/$MONITOR_ID/sources?days=30&groupBy=domain&limit=2" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

| Parameter | Description |
| - | - |
| `groupBy` | `domain` (default): the host without `www.`, port or credentials. `page`: the full URL. |
| `limit` | 1–100, default 20. |
| `cursor` | The previous response's `nextCursor`, unchanged. |
| `days`, `since`, `until`, `engine`, `prompt` | As on the [report](/monitors/reports.md#query-parameters). |

For example:

```json theme={"theme":"css-variables"}
{
  "success": true,
  "data": {
    "results": [
      {
        "key": "reviews.example",
        "domain": "reviews.example",
        "url": null,
        "label": "Best wireless earbuds of 2026",
        "citations": 11,
        "prompts": 2,
        "own": false,
        "evidenceTaskId": "6f1c2a9e-3b4d-4e5f-8a7b-1c2d3e4f5a61"
      },
      {
        "key": "rtings.example",
        "domain": "rtings.example",
        "url": null,
        "label": "Earbuds reviews",
        "citations": 7,
        "prompts": 1,
        "own": false,
        "evidenceTaskId": "6f1c2a9e-3b4d-4e5f-8a7b-1c2d3e4f5a62"
      }
    ],
    "nextCursor": "eyJrZXkiOiJydGluZ3MuZXhhbXBsZSIsImNpdGF0aW9ucyI6N30",
    "groupBy": "domain",
    "window": { "since": "2026-09-19T07:00:00.000Z", "until": "2026-10-19T07:00:00.000Z" },
    "filters": { "engine": null, "prompt": null },
    "counting": "distinct_answers",
    "ownership": "current_monitor_domains"
  }
}
```

| Field | Meaning |
| - | - |
| `citations` | Answers that cited this domain or page. |
| `prompts` | Distinct prompts whose answers cited it. |
| `own` | Whether it is one of the monitor's current `domains` or a subdomain of one (`ownership: "current_monitor_domains"`). |
| `url` | The page URL with `groupBy=page`; `null` for domains. |
| `label` | The citation's label as the engine gave it, if any. |
| `evidenceTaskId` | One answer that cited it. Open it with the [answers endpoint](#read-one-answer). |

Rows are ordered by `citations`, then `key`. `nextCursor` is `null` on the last page; there is no top-N
cut, so every cited domain or page in the window is reachable. Treat the cursor as opaque.

## Citations over time

`GET /v1/monitors/{id}/citations` ([reference](/api-reference/monitors/get-citations.md)) returns the data
behind the dashboard's citation charts: totals for the window, a daily series, and the top 20 domains and
pages, each with its own daily series.

```bash theme={"theme":"css-variables"}
curl "https://api.querying.ai/v1/monitors/$MONITOR_ID/citations?days=30&kind=owned" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

| Parameter | Description |
| - | - |
| `days` | `7`, `30` (default) or `90`. |
| `since`, `until` | A fixed window, as on the report. When set, `days` is only echoed back as `windowDays`. |
| `engine` | One engine, or `all` (default). |
| `prompt` | One prompt, by exact text. |
| `kind` | `all` (default), `owned`, `editorial`, `review_media`, `pr_wire`, `institution`, `reviews`, `commerce`, `social`, `blog`, `community`, `video`, `brand`, `content` or `other`. |
| `q` | Keeps domains whose name, or pages whose URL, contains this text. Up to 200 characters. |
| `offset` | 0–10,000, for paging the domain and page lists 20 at a time. |

Here a citation is one page in one answer, so `citations` counts cited pages, not answers. `/sources`
counts distinct answers, so its numbers can differ.

| Field | Contents |
| - | - |
| `totals` | `answers` (scored answers), `citedAnswers`, `citations` and `ownedCitations` for the window. |
| `days` | One entry per UTC day with answers: `day`, `answers`, `citations`, `ownedCitations`. A day with answers and no citations has `citations: 0`; a day with no answers is absent. |
| `domains`, `pages` | Up to 20 rows from `offset`: `key`, `domain`, `label`, `kind`, `owned`, `citations`, `answers`, `prompts`, and `daily`, a list of `{ day, citations }` for days with citations. |
| `types` | Per `kind`: `citations` and distinct `domains`. |
| `pagination` | `offset`, `limit` (20), `totalDomains`, `totalPages`. |
| `windowDays`, `engine`, `prompt`, `since`, `until` | The scope that was read. |

`kind` is `owned` for your domains; other kinds come from a fixed list of known publishers, and anything
unknown is `other`. A source's share is its `citations` divided by `totals.citations`. `kind`, `q` and
`offset` narrow only `domains`, `pages` and `pagination`; `totals`, `days` and `types` always cover every
source in the window.

## Read one answer

`GET /v1/monitors/{id}/answers/{taskId}` ([reference](/api-reference/monitors/get-answer.md)) returns the
stored answer behind one score, with what it was matched against, so a mention can be checked rather than
trusted. Task ids come from `evidenceTaskId`, `mentionTaskId` and `latestTaskId` in a report, from
`/sources`, and from exported rows.

```bash theme={"theme":"css-variables"}
curl "https://api.querying.ai/v1/monitors/$MONITOR_ID/answers/6f1c2a9e-3b4d-4e5f-8a7b-1c2d3e4f5a61" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

For example:

```json theme={"theme":"css-variables"}
{
  "success": true,
  "data": {
    "answer": {
      "taskId": "6f1c2a9e-3b4d-4e5f-8a7b-1c2d3e4f5a61",
      "engine": "CHATGPT",
      "prompt": "best wireless earbuds for commuting",
      "mentioned": true,
      "cited": true,
      "position": 81,
      "ranAt": "2026-10-17T09:01:48.311Z",
      "answerText": "For commuting, look at the **Northwind Audio Pro** for noise cancelling or the **Acme Audio Air** for battery life.",
      "sources": [
        { "url": "https://reviews.example/best-earbuds", "label": "Best wireless earbuds of 2026", "position": 1 },
        { "url": "https://acme-audio.example/air", "label": "Acme Audio Air", "position": 2 }
      ],
      "competitorHits": ["Northwind Audio"],
      "scoringContext": {
        "aliases": ["Acme Audio", "Acme"],
        "domains": ["acme-audio.example"],
        "competitors": [
          { "name": "Northwind Audio", "aliases": ["Northwind Audio"], "source": "user" },
          { "name": "Contoso Sound", "aliases": ["Contoso Sound", "Contoso"], "source": "user" }
        ],
        "country": "US",
        "version": "3f9a6c1e8b2d4f7a9c0e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a",
        "scoredAt": "2026-10-17T09:01:48.305Z",
        "answerPresent": true,
        "evidenceTruncated": false
      },
      "analysis": null
    },
    "display": {
      "markdown": "For commuting, look at the **Northwind Audio Pro** for noise cancelling or the **Acme Audio Air** for battery life.",
      "text": "For commuting, look at the Northwind Audio Pro for noise cancelling or the Acme Audio Air for battery life."
    },
    "mode": "BRAND",
    "aliases": ["Acme Audio", "Acme"],
    "competitors": [
      { "name": "Northwind Audio", "aliases": ["Northwind Audio"], "source": "user" },
      { "name": "Contoso Sound", "aliases": ["Contoso Sound", "Contoso"], "source": "user" }
    ],
    "scoringKnown": true,
    "evidenceTruncated": false
  }
}
```

| Field | Meaning |
| - | - |
| `answer` | The scored answer, as stored. |
| `answer.answerText` | The answer, as markdown when the engine gave it, cut at 8,000 characters with a trailing `…`. `null` when the engine returned no text. |
| `answer.sources` | The cited pages in the engine's order, deduplicated by URL, each with its `label` and 1-based `position`. |
| `answer.competitorHits` | The competitors named in the answer. |
| `answer.position` | Character offset of the first match of your brand, or `null`. |
| `answer.scoringContext` | The definition the answer was scored with: `aliases`, `domains`, `competitors`, `country`, its `version` hash, `scoredAt`, `answerPresent` and `evidenceTruncated`. `null` for answers scored before it was stored. |
| `answer.analysis` | The [answer analysis](/engines/answer-analysis.md) result when the monitor has `analysis: true`, otherwise `null`. |
| `display` | Display fields of the original task response, such as `markdown`, `text`, `sources`, `searchQueries`, layout, places and products, depending on the engine. `null` when the original task is no longer stored. |
| `mode` | The monitor's mode. On a category monitor `aliases` is empty and `competitors` is the list of tracked brands. |
| `aliases`, `competitors` | What this answer was matched against: from `scoringContext`, or the monitor's current values when it is `null`. |
| `scoringKnown` | `false` when the answer predates stored scoring context; `aliases` and `competitors` are then the monitor's current values. |
| `evidenceTruncated` | Whether `answerText` was cut. `null` when `scoringKnown` is `false`. |

A task id that is not a scored answer of this monitor returns `404 NOT_FOUND`.

## One prompt in detail

`GET /v1/monitors/{id}/prompt` ([reference](/api-reference/monitors/get-prompt.md)) returns one prompt's
data. `prompt` (exact text) is required, and works for prompts you have since removed from the monitor;
`days` is `7`, `30` (default) or `90`.

```bash theme={"theme":"css-variables"}
curl -G "https://api.querying.ai/v1/monitors/$MONITOR_ID/prompt" \
  --data-urlencode "prompt=best wireless earbuds for commuting" \
  --data-urlencode "days=30" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

| Field | Contents |
| - | - |
| `monitor` | `id`, `name`, `engines` and `aliases`. |
| `prompt`, `windowDays` | What was read. |
| `series` | Per UTC day and engine: `day`, `engine`, `runs`, `mentioned`, `cited`. |
| `topDomains` | Up to 12 cited domains: `domain`, `citations`, `prompts`, `own`. |
| `topPages` | Up to 20 cited pages: `url`, `domain`, `label`, `citations`, `prompts`, `own`. |
| `results` | Up to 100 latest scored answers: `taskId`, `engine`, `prompt`, `mentioned`, `cited`, `position`, `ranAt`, `competitorHits`. |

Here `citations` counts cited pages across answers, not distinct answers. For a full, paginated source
list for one prompt, use `/sources?prompt=...`.

## Answers by location

`GET /v1/monitors/{id}/grid` ([reference](/api-reference/monitors/get-grid.md)) returns a monitor's answers per
point of its current [location or grid](/monitors.md#location-and-grids). Optional `engine` (one of the
monitor's engines) and `prompt` narrow it; `days` is `7`, `30` (default) or `90`.

The response has `location`, `grid`, `engine`, `prompt`, `windowDays` and `points`. Each point has `row`,
`col`, `location`, `runs`, `mentioned`, `cited`, `topCompetitor` (`{ name, mentions }` or `null`) and
`latest` (`{ taskId, engine, mentioned, ranAt }` of the newest answer, or `null`). Answers are matched to
points by their exact coordinates, so answers from an earlier location or grid of the same monitor are
left out. A monitor without a location or grid returns no points.

## Export scored answers

`GET /v1/monitors/{id}/results` ([reference](/api-reference/monitors/export-results.md)) returns the scored
answers themselves, for a warehouse load, a spreadsheet or a deck. To deliver every new answer to cloud
storage on a schedule instead, see [Result exports](/exports.md).

```bash theme={"theme":"css-variables"}
curl "https://api.querying.ai/v1/monitors/$MONITOR_ID/results?since=2026-10-01T00:00:00Z&until=2026-10-18T00:00:00Z&mentioned=false" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

| Parameter | Description |
| - | - |
| `since`, `until` | Half-open window. Default: the 30 days ending now. ISO instants with a timezone; a bare `YYYY-MM-DD` is also accepted here and read as midnight UTC. There is no maximum span. |
| `engine`, `prompt` | As on the report. |
| `mentioned`, `cited` | `true` or `false`. `mentioned=false` is the gap view. |
| `competitor` | Keeps answers whose stored competitor hits include this exact name, 1–80 characters. It matches the name as it was stored when each answer was scored and is not checked against the monitor's current competitors: a name the monitor never tracked returns no rows, not an error. |
| `includeEvidence` | `true` adds `answerText`, `sources` and `scoringContext` to every row. |
| `limit` | 1–10,000, default 10,000. With `includeEvidence=true`: 1–100, default 100. |
| `format` | `json` (default) or `csv`. |
| `cursor` | The previous page's `nextCursor`. |

The JSON response, for example:

```json theme={"theme":"css-variables"}
{
  "success": true,
  "data": {
    "monitor": { "id": "d39b8de0-b159-4229-bf58-7064e5369db1", "name": "Earbud brand tracking" },
    "since": "2026-10-01T00:00:00.000Z",
    "until": "2026-10-18T00:00:00.000Z",
    "filters": { "engine": null, "prompt": null, "mentioned": false, "cited": null, "competitor": null },
    "truncated": false,
    "nextCursor": null,
    "results": [
      {
        "id": "0b6e4a52-7c1d-4f8e-9a3b-2d5c6e7f8a91",
        "taskId": "6f1c2a9e-3b4d-4e5f-8a7b-1c2d3e4f5a63",
        "engine": "CHATGPT",
        "prompt": "are cheap earbuds worth it",
        "mentioned": false,
        "cited": false,
        "position": null,
        "ranAt": "2026-10-17T09:02:57.204118Z",
        "competitorHits": ["Northwind Audio"]
      }
    ]
  }
}
```

Rows are newest first. Pagination is a keyset over `ranAt` (microsecond precision) and row `id`, so rows
that share a timestamp are never skipped or repeated. For a repeatable extraction, send an explicit
`since` and `until`, keep them fixed, and follow `nextCursor` until it is `null`. Changing the window
between pages can skip or repeat rows. Treat the cursor as opaque.

### CSV

With `format=csv` the response is `text/csv`, UTF-8 with a byte order mark so spreadsheet apps open it
correctly. A CSV body cannot carry pagination, so it moves to headers:

| Header | Meaning |
| - | - |
| `x-next-cursor` | The cursor for the next page; empty on the last page. |
| `x-result-truncated` | `true` when more rows matched than this page returned. |
| `x-result-since`, `x-result-until` | The resolved window, so a resumed export can pin it. |

Columns are `ran_at, monitor, engine, prompt, mentioned, cited, position, competitors, task_id`, plus
`answer_text, sources, scoring_context` with `includeEvidence=true`. `competitors` joins names with
`|`; `sources` and `scoring_context` hold JSON text. A cell that starts with `=`, `+`, `-`, `@`, a tab
or a carriage return is prefixed with `'`, so engine text cannot become a spreadsheet formula.

```bash theme={"theme":"css-variables"}
curl -D headers.txt -o page1.csv \
  "https://api.querying.ai/v1/monitors/$MONITOR_ID/results?since=2026-10-01T00:00:00Z&until=2026-10-18T00:00:00Z&format=csv&includeEvidence=true" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

## Errors and limits

| Limit | Value |
| - | - |
| Report and source window | 90 days |
| `/sources` page | 1–100 rows, default 20 |
| `/citations` lists | 20 rows per page; `offset` up to 10,000 |
| `/results` page | 10,000 rows; 100 with `includeEvidence=true` |
| Stored answer text | 8,000 characters |
| `/prompt` | 12 domains, 20 pages, 100 answers |

Invalid parameters return `400 VALIDATION_ERROR` naming the problem, including a cursor that was not
returned by the previous page. A monitor of another account, or an unknown task id, returns
`404 NOT_FOUND`. See [Monitors](/monitors.md#errors) for the shared codes.

## Next steps

> **[Events and alerts](/monitors/events-and-alerts.md)**
>
> Get a webhook when a prompt's answers change.

> **[Result exports](/exports.md)**
>
> Deliver scored answers to your own storage on a schedule.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.