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

# ask_analyst

> Run one turn of a conversation with the Analyst, Qobra's reporting agent. Its changes are applied directly to the report.

Hand the work on a report to the **Analyst**, Qobra's reporting agent. Each
call runs one turn of a conversation in which the Analyst builds, changes or
explains a report: its metrics and columns, filters, pivot table, chart and
sharing, and the dashboards built on it.

Use it when the user wants a report built or changed from a description in
their own words ("show the attainment per rep by quarter"), or wants to
understand what a report shows ("why is EMEA at zero?").

## Start and continue a conversation

Start a conversation with an `instruction` and the `report_id` to work on.
[`list_reports`](https://docs.qobra.co/mcp_documentation/tools/list_reports) lists the reports, and
[`create_report`](https://docs.qobra.co/mcp_documentation/tools/create_report) returns the id of a
new one.

```json theme={null}
{
  "instruction": "Show the attainment per rep by quarter",
  "report_id": "<report-id>"
}
```

Omit `report_id` to let the Analyst create the report the instruction
describes. `sandbox_id` then picks the sandbox the new report lands in. Without
it, the report is created in the live environment. A `report_id` or a
`conversation_id` already names its own environment.

```json theme={null}
{
  "instruction": "Build a report of closed deals per rep this quarter"
}
```

Every later call of the same work passes back the `conversation_id` the first
call returned, a retry included. Without it, Qobra starts a new conversation
and the Analyst loses what was said. The conversation is the same one the
report's Analyst panel shows in the Qobra web app. A conversation continues on
the report it is attached to, including a report the Analyst created during
it.

## Read the result

`status` says where the turn stands:

* `answered`: the Analyst finished its turn. Relay `answer` to the user.
* `awaiting_user`: the Analyst paused on a question (`pending_question`). The
  client must show it to the user as it is, wait for their reply, and send
  that reply as the next `instruction` with the same `conversation_id`.
* `running`: the turn is still going. Each call waits about 45 seconds before
  answering `running`, and a turn can take several minutes. Call
  [`get_analyst_turn`](https://docs.qobra.co/mcp_documentation/tools/get_analyst_turn) with the
  `conversation_id` to keep waiting. Calling `ask_analyst` on a conversation
  whose turn is still running is refused, and the instruction is not sent.

A turn that ends on an error is raised as a tool error that names the
conversation, so the client can send the instruction again in it.

The result carries the `report` the conversation works on, in the same shape
[`list_reports`](https://docs.qobra.co/mcp_documentation/tools/list_reports) lists it, with the
link to open it. It is the report the call named, or the one the Analyst
created during the conversation. It is `null` while the Analyst has not created
one yet.

## Changes apply directly

The Analyst works without a draft copy. It writes its changes to the
report as it makes them, as the Analyst panel does in the Qobra web app.

## Permissions and availability

What the Analyst does depends on the caller's own rights, as in the web app:

* With write access on every report, the Analyst does everything: metrics,
  columns, filters, pivot table, chart, sharing and dashboards.
* With write access on this report only, the Analyst edits its columns, sorts,
  pivot table and chart.
* On a report the caller may only read, the Analyst explains it.
* Without a `report_id`, the Analyst creates a new report. This needs write
  access on every report. A caller without it is refused and told to pass a
  `report_id`.

In beta: available only to companies enrolled in the Qobra agent tools beta,
and where the Analyst is switched on for the company. Elsewhere, Qobra hides
the tool at discovery. The caller needs read access on reports.

## Parameters

> [accordion] Body
>
> **instruction** `string` *required*
>
> What to ask or tell the Analyst, in the user's words: 'show the attainment
> per rep by quarter', 'why is EMEA at zero?'. Also the user's answer to a
> question it is waiting on.
>
> **report\_id** `string`
>
> Id of the report to work on: the id list\_reports returns, or the one
> create\_report returned. Omit it with no conversation\_id to have the Analyst
> create the report itself; a conversation\_id already names its report.
>
> **conversation\_id** `string`
>
> Id of the conversation to continue: the one an earlier ask\_analyst call
> returned. Omit it only to start a new conversation.
>
> **sandbox\_id** `string`
>
> Id of the sandbox to create this in instead of the live environment — the id
> list\_sandboxes returns. Omit it to create in the live environment, the
> company's real compensation data. Only a sandbox id is accepted here — never
> a sandbox name, and never the live environment's own id.

## Response

> [accordion] Body
>
> **status** `string`
>
> 'answered': the Analyst finished its turn, its reply is in answer.
> 'awaiting\_user': it paused on a question (pending\_question); show it to the
> user and send their reply as the next instruction of this conversation with
> ask\_analyst. 'running': a turn is still going; call get\_analyst\_turn with
> this conversation\_id to keep waiting for it. One of: `answered`,
> `awaiting_user`, `running`.
>
> **conversation\_id** `string`
>
> The conversation this turn belongs to, the same one the web app shows in the
> Analyst panel. Pass it back on every follow-up call.
>
> **answer** `string`
>
> The Analyst's reply when status is 'answered', to relay to the user. Null
> otherwise.
>
> **pending\_question** `object`
>
> The question the Analyst is waiting on, with the options it offers
> (multi\_select: several may be picked; the user may also answer in their own
> words). Set only when status is 'awaiting\_user'.
>
> **object properties**
>
> **question** `string`
>
> **options** `string[]`
>
> **multi\_select** `boolean`
>
> **report** `object`
>
> The report the conversation works on, as list\_reports lists it, with the
> link to open it: the one the call named, or the one the Analyst created
> during this conversation. Null while the Analyst has not created one yet.
>
> **object properties**
>
> **report\_id** `string`
>
> **resource\_url** `string`
>
> Deep link to open this report in the Qobra web app.
>
> **report\_name** `string`
>
> **report\_type** `string`
>
> What the report is built on: statement (payout statements) or record
> (the rows of the tracked\_datatable). One of: `statement`, `record`.
>
> **description** `string`
>
> **tracked\_datatable** `object`
>
> Source data table tracked by a record report, with its id and name; null
> for statement reports.
>
> **object properties**
>
> **id** `string`
>
> **name** `string`
>
> **available\_visualizations** `string[]`
>
> The dashboard tiles this report can render: `chart` when a chart is
> configured on it, `pivot_table` when a pivot table is. Empty when
> neither is — the report then has no tile to show on a dashboard.
>
> **section** `object`
>
> The section the report is filed under (id and name), or null when
> unfiled.
>
> **object properties**
>
> **section\_id** `string`
>
> **section\_name** `string`
>
> **access** `object`
>
> Who can read this report, split into roles and users, each with the
> level they hold — the same roster shape every saved view speaks. Null
> when the roster is not yours to see (no write access on reports) or the
> report was read from a sandbox, sharing being live-only; never an empty
> roster, which a caller who may see it gets as empty `roles` and `users`
> instead.
>
> **object properties**
>
> **roles** `object[]`
>
> **object properties**
>
> **role** `object`
>
> **object properties**
>
> **id** `string`
>
> **name** `string`
>
> **resolved** `boolean`
>
> **default\_access** `string`
>
> The level this role holds on the whole resource category, which
> reaches every view of it without a share — `read` (view it),
> `write` (edit and re-share it) or `delete` (also remove it),
> each level including the ones before it. Null when the role only
> got this view through a share. One of: `read`, `write`,
> `delete`.
>
> **shared\_access** `string`
>
> The level granted to this role on this view specifically —
> `read` (view it), `write` (edit and re-share it) or `delete`
> (also remove it), each level including the ones before it. Null
> when the role reaches the view through its category access
> rather than a share. One of: `read`, `write`, `delete`.
>
> **users** `object[]`
>
> **object properties**
>
> **user** `object`
>
> **object properties**
>
> **id** `string`
>
> **email** `string`
>
> **name** `string`
>
> **shared\_access** `string`
>
> The level this view is shared with the user at, individually, on
> top of whatever their role already grants — `read` (view it),
> `write` (edit and re-share it) or `delete` (also remove it),
> each level including the ones before it. One of: `read`,
> `write`, `delete`.
