# info.description
Southwind Whispers turns connected data into structured reports through an
asynchronous API workflow.

## Authentication

Send your organization API key in the `X-API-Key` header:

```bash
curl https://<whispers-host>/api/v1/me   -H "X-API-Key: <your-api-key>"
```

## Core concepts

- **Data Origin:** the upstream connection or uploaded file. An origin can
  contain one or more data sources.
- **Data Source:** a specific queryable dataset derived from an origin. Reports
  reference data source UUIDs, not origin IDs.
- **Report:** an asynchronous analysis task created from ready data sources.

## Quickstart: origin to report

1. Create an origin with `POST /api/v1/origins/file/`,
   `POST /api/v1/origins/data-api/`, or `POST /api/v1/origins/postgres/`.
2. Resolve the data source IDs from the connector-specific receipt described
   below.
3. For asynchronous file and API origins, wait for every required source to
   become `completed`. Prefer
   `GET /api/v1/origins/{origin_id}/ingest/events`; source polling is the
   fallback.
4. If a source reaches `awaiting_confirmation`, inspect
   `metadata.cleaning_plan` and submit the required decisions to
   `POST /api/v1/sources/{source_id}/cleaning/confirm`.
5. If a file or API source reaches `failed`, inspect `ingest_error_code` and
   retry it with `POST /api/v1/sources/{source_id}/ingest/retry`.
6. Create the report with `POST /api/v1/reports/` and the completed source IDs.

A file or API origin creation response is a receipt: its tabular sources are
queued, not immediately ready. Creating a report from a tabular source that is
not `completed` returns `409 Conflict`. Document sources (`.pdf`, `.txt`, and
`.md`) are exempt from this readiness gate.

### Connector receipts

The three origin connectors intentionally return different receipt shapes:

| Connector | Receipt | How to resolve sources |
|---|---|---|
| File | `created_data_origins[].id` | Source discovery is asynchronous by contract. Stream the origin or call `GET /api/v1/sources/?origin_id=<origin-id>`; do not expect source IDs in the receipt. |
| Data API | `data_sources[].id` | Poll each returned source with `GET /api/v1/sources/?source_id=<source-id>`. |
| PostgreSQL | `origin_id` | Call `GET /api/v1/sources/?origin_id=<origin-id>`. Live sources are registered ready for querying. |

## Ingestion lifecycle

```text
Create origin
     |
     v
  queued -> ingesting -> analyzing
                         |
              +----------+----------+
              v                     v
 awaiting_confirmation            failed
              |                     |
              v                     v
          cleaning             ingest/retry
              |                     |
              +----------+----------+
                         v
                     completed
                         |
                         v
                   Create report
```

| Status | Meaning | Usable in a report? |
|---|---|---|
| `queued` | Accepted and waiting for a worker | No |
| `ingesting` | Reading and materializing upstream data | No |
| `analyzing` | Profiling types and cleaning requirements | No |
| `awaiting_confirmation` | Ambiguous conversions require your decision | No |
| `cleaning` | Applying confirmed conversions | No |
| `completed` | Ready for analysis | **Yes** |
| `failed` | Ingestion stopped; inspect `ingest_error_code` | No |

Data source responses also expose `ingest_run_id`, `row_count`, and
`size_bytes`. Nullable fields such as `ingest_error_code` are omitted when
there is no value. `collection_name` is deprecated and no longer identifies a
queryable location.

Live PostgreSQL sources are queried directly through DuckDB rather than
materialized; their `size_bytes` is `0`. Origin-level lifecycle propagation for
PostgreSQL is work in progress, so the origin status is not yet a stable
readiness contract.

## Wait with SSE or polling

The preferred stream emits per-source status snapshots approximately every two
seconds and closes at `completed`, `awaiting_confirmation`, or `failed`:

```text
event: status
data: [{"id":"<source-id>","ingest_status":"analyzing","ingest_error_code":null}]

event: done
data: {}
```

As a polling fallback, call
`GET /api/v1/sources/?origin_id=<origin-id>` every 2–5 seconds. Do not treat a
successful response from source sync, update, or creation as proof that fresh
data is ready; wait for the new ingestion run to finish.

## Create a report

```bash
curl https://<whispers-host>/api/v1/reports/   -H "Content-Type: application/json"   -H "X-API-Key: <your-api-key>"   -d '{
    "agent_id": "rover_report",
    "data_sources_ids": ["<completed-source-id>"],
    "title": "Performance investigation",
    "params": {
      "language": "english",
      "currency": "USD",
      "data_provenance": true,
      "target_sections": 7,
      "goal": "Identify the main performance drivers and prioritize actions."
    }
  }'
```

Rover is the recommended starting point for autonomous analysis. The
`POST /api/v1/reports/` reference also includes selectable examples for
prompt-driven Custom reports and incrementally authored Blank reports.

Report status normally progresses from `queued` to `running`, then to
`completed` or `failed`. `waiting_for_data` is also an in-progress state and
precedes `queued`, most commonly when redoing a report while its sources refresh.
Clients should tolerate new in-progress values rather than failing on unknown
status strings.

## Cleaning confirmation

Every column marked `ambiguous` in `metadata.cleaning_plan` needs a decision.
Send the offered temporal format, a numeric interpretation, or `keep_text`:

```json
{
  "decisions": [
    {
      "column": "order_date",
      "kind": "temporal",
      "target_type": "date",
      "format": "%d/%m/%Y"
    }
  ],
  "locale": "eu"
}
```

The source moves to `cleaning`, then `completed`. Decisions are retained for
later refreshes when they still match the incoming data.

## Report translations

Translate a completed report with
`POST /api/v1/reports/{task_id}/translate`, then poll
`GET /api/v1/reports/{task_id}` until the language appears in
`available_languages`. While work is pending, `translation_jobs` exposes the
per-language state (`queued`, `running`, or `failed`). Read a translated version
with:

```text
GET /api/v1/reports/{task_id}?language=italian
```

The same `language` query parameter is available for report save, rename,
export, and public report reads. These writes affect only the selected language.
If the primary report changes afterward, translated views remain available with
`translation_stale: true` until replaced.

Submitting an existing or active translation without `replace: true` returns
`409` with `translation_exists` or `translation_in_progress`. Unsupported
languages return `400 invalid_language`; non-completed reports return
`409 report_not_ready`. Translation is metered separately and appears in
`GET /api/v1/billing/usage`.

## Errors

API errors use this envelope:

```json
{"error":{"detail":"...","code":"...","request_id":"..."}}
```

Branch on the stable machine-readable `code` when present, not on the
human-readable `detail`. `request_id` is normally included for server-side
failures. UUID path parameters such as `task_id`, `origin_id`, and `source_id`
reject malformed values with `422`.

# paths./api/v1/agents/.get.description
List agents available to the current organization.

# paths./api/v1/reports/.post.description
Create a report task from one or more data sources.

Choose the workflow with `agent_id`:

- `rover_report` (recommended): autonomously investigates the data. Use `goal` to orient the analysis, `seeded_question` to set the first investigation question, and `target_sections` to control the approximate report depth.
- `custom_report`: generates a prompt-driven report. Use `prompt`, `dataset_info`, and optionally `improve_prompt`.
- `blank_report`: creates an empty report container immediately in `completed` state. Add content with `POST /api/v1/reports/{task_id}/ai-section`.

Rover and Custom reports are returned in `queued` state and continue asynchronously.

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.rover_report.description
Run an autonomous investigation across the selected data sources.

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.rover_report.value.params.seeded_question
Which regions are driving the decline in gross margin?

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.rover_report.value.params.goal
Identify the main causes of margin decline and prioritize corrective actions.

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.custom_report.description
Generate a report from an explicit prompt and optional dataset context.

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.custom_report.value.params.prompt
Analizza i dati dei pagamenti di oggi e produci un report sintetico.

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.custom_report.value.params.dataset_info
Each row represents one payment transaction.

# paths./api/v1/reports/.post.requestBody.content.application/json.examples.blank_report.description
Create an empty report, then add AI-generated sections incrementally.

# paths./api/v1/reports/.post.responses.201.content.application/json.examples.rover_report.value.params.seeded_question
Which regions are driving the decline in gross margin?

# paths./api/v1/reports/.post.responses.201.content.application/json.examples.rover_report.value.params.goal
Identify the main causes of margin decline and prioritize corrective actions.

# paths./api/v1/reports/.post.responses.201.content.application/json.examples.custom_report.value.params.prompt
Analizza i dati dei pagamenti di oggi e produci un report sintetico.

# paths./api/v1/reports/.post.responses.201.content.application/json.examples.custom_report.value.params.dataset_info
Each row represents one payment transaction.

# paths./api/v1/reports/.post.responses.402.description
Plan limit reached for reports or prompt improvement.

# paths./api/v1/reports/.get.description
List reports for the current organization.

If `user_filter=true`, only reports created by the current user are returned.

# paths./api/v1/reports/.delete.description
Delete multiple reports by UUID.

Returns the number of deleted reports and any IDs that could not be deleted.

# paths./api/v1/reports/improve-prompt.post.description
Improve a report prompt using AI before creating a report.

# paths./api/v1/reports/improve-prompt.post.responses.402.description
Plan limit reached for prompt improvement.

# paths./api/v1/reports/{task_id}.get.description
Retrieve a report task by ID.

Optional `?language=` returns that language's content when available (primary language is `params.language`).

# paths./api/v1/reports/{task_id}.put.description
Save edited report blocks.

Optional `?language=` writes only that language's content (primary when omitted or equal to `params.language`).

# paths./api/v1/reports/{task_id}/redo.post.description
Create a new report task using the configuration of an existing report.

When `sync_data_sources` is enabled, compatible sources refresh asynchronously. The new report may therefore be returned as `waiting_for_data` before it becomes `queued`; treat both values as in-progress and poll the new task. The response contains the task's real initial status rather than forcing it to `queued`.

# paths./api/v1/reports/{task_id}/redo.post.responses.201.description
New report task created from the original report configuration.

# paths./api/v1/reports/{task_id}/redo.post.responses.400.description
The report could not be redone with the requested options.

# paths./api/v1/reports/{task_id}/ai-section.post.description
Generate a report section within the context of an existing report task.

This endpoint is designed to be used with a report task, not as a standalone assistant. A common flow is:
- create a blank report with `POST /api/v1/reports/` and `agent_id='blank_report'`
- call this endpoint one or more times to append AI-generated sections

Optional `?language=` writes the section in that language (primary `params.language` when omitted).

# paths./api/v1/reports/{task_id}/chat/history.get.description
Return the persisted chat history associated with a report task.

# paths./api/v1/reports/{task_id}/chat/history.get.responses.200.content.application/json.example.messages[].content
Il picco è concentrato tra le 10:00 e le 12:00.

# paths./api/v1/reports/{task_id}/chat/history.get.responses.500.description
The chat history could not be retrieved.

# paths./api/v1/reports/{task_id}/chat/history.delete.description
Delete the persisted chat history associated with a report task.

# paths./api/v1/reports/{task_id}/chat.post.description
Start a report-scoped assistant chat with streaming output.

The assistant uses report content as context and persists user/assistant messages on success.
Response media type is `text/event-stream` with incremental `data:` events, optional `event: error`, and final `event: chatComplete`.

Example stream:
```text
data: Primo chunk

data: Secondo chunk

event: chatComplete
data:

```

# paths./api/v1/reports/{task_id}/translate.post.description
Enqueue translation of the primary report content into another language.

Returns 409 if a translation (or in-progress job) already exists unless `replace: true`.

# paths./api/v1/reports/{task_id}/translate.post.responses.400.description
The target language is unsupported or is the report's primary language.

# paths./api/v1/reports/{task_id}/translate.post.responses.409.description
The report is not ready, or the translation already exists or is in progress.

# paths./api/v1/reports/{task_id}/share.put.responses.403.description
Public sharing is disabled for this organization.

# paths./api/v1/reports/{task_id}/share.get.description
Return the report's current public-sharing state without modifying it.

When the report is public, the response includes a temporary public token; when it is private, `token` is omitted. Use `PUT /api/v1/reports/{task_id}/share` to change the state.

# paths./api/v1/reports/{task_id}/share.get.responses.500.description
The sharing state could not be retrieved.

# paths./api/v1/reports/{task_id}/events.get.description
SSE stream that multiplexes status updates and AI thoughts.

- `event: status` — `data: {status, progress}` on each poll
- `event: thought` — `data: {message, type, icon, ...}` for each new thought
- `event: done` — signals the stream has ended (task completed or failed)

# paths./api/v1/reports/{task_id}/export.get.description
Download the report as PDF (default), PPTX, or DOCX.

Use `?format=pdf`, `?format=pptx`, or `?format=docx` query parameter.
Optional `?language=` exports that language version when available.

# paths./api/v1/reports/{task_id}/provenance/{provenance_id}.get.responses.500.description
The provenance record could not be retrieved.

# paths./api/v1/billing/portal.get.responses.503.description
Billing not configured or no billing customer.

# paths./api/v1/sources/.get.description
List data sources for the current organization.

Optional filters:
- `source_id`: return a single source by UUID
- `origin_id`: return all sources belonging to a single origin

Do not provide both filters at the same time.

# paths./api/v1/sources/.get.responses.500.description
The data sources could not be retrieved.

# paths./api/v1/sources/.delete.description
Delete multiple data sources by UUID.

The response includes both the number of deleted sources and any requested IDs that could not be deleted.

# paths./api/v1/sources/{source_id}/cleaning/confirm.post.description
Resolve ambiguous conversions for a source in `awaiting_confirmation`.

Submit a decision for every ambiguous column, or a locale when the ambiguity is limited to number formatting. Accepted decisions move the source to `cleaning` and queue Parquet rematerialization; continue waiting until it reaches `completed` or `failed`.

Returns `409` when the source has no cleaning plan, is no longer awaiting confirmation, names a non-ambiguous column, or selects a temporal conversion that was not offered in `metadata.cleaning_plan`.

# paths./api/v1/sources/{source_id}/cleaning/confirm.post.responses.202.description
Cleaning decisions accepted and rematerialization queued.

# paths./api/v1/sources/{source_id}/cleaning/confirm.post.responses.409.description
The cleaning decision is not valid for this source.

# paths./api/v1/sources/{source_id}/cleaning/confirm.post.responses.500.description
The cleaning decision could not be queued.

# paths./api/v1/sources/{source_id}/ingest/retry.post.description
Retry ingestion for a failed file or API source.

A `202` response returns the source with a new ingestion run queued. Continue waiting through the origin SSE stream or source polling. Sources that are not failed return `400` with code `retry_ingest_invalid_source_type`; origin types without retry support return code `unsupported_data_origin_operation`.

# paths./api/v1/sources/{source_id}/ingest/retry.post.responses.202.description
A new ingestion run was queued for the failed source.

# paths./api/v1/sources/{source_id}/ingest/retry.post.responses.400.description
The source is not eligible for ingestion retry.

# paths./api/v1/sources/{source_id}/ingest/retry.post.responses.500.description
The ingestion retry could not be queued.

# paths./api/v1/sources/{source_id}/preview.get.description
Return a paginated preview of the rows contained in a data source.

`page` and `page_size` must be greater than or equal to 1.

# paths./api/v1/sources/{source_id}/preview.get.responses.200.description
Data source preview returned successfully.

# paths./api/v1/sources/{source_id}/preview.get.responses.404.description
The requested data source does not exist.

# paths./api/v1/sources/{source_id}/preview.get.responses.500.description
The data source preview could not be generated.

# paths./api/v1/sources/{data_source_id}/sync.post.description
Queue a refresh of a data source from its upstream origin.

Only syncable data sources can be refreshed. File-based sources are not syncable.

The refresh itself runs in the background: a `200` means the source was queued, not that fresh data is already available. Poll `GET /origins/{id}/ingest/events` or the source's `ingest_status` for the outcome.

A `207` means only some of the sources could be queued; the entries that failed carry an `error` payload instead of a data source.

# paths./api/v1/sources/{data_source_id}/sync.post.responses.207.description
Partial success - some data sources could not be queued.

# paths./api/v1/sources/{data_source_id}/sync.post.responses.404.description
The requested data source does not exist.

# paths./api/v1/sources/{data_source_id}/sync.post.responses.500.description
The data source could not be synchronized.

# paths./api/v1/sources/{source_id}.patch.description
Partially update a data source and resync its data from the upstream origin.

The request body must include a `type` discriminator matching the source's origin type. At least one field besides `type` must be provided. After applying the changes, fresh data is fetched from the upstream endpoint. The response contains the newly queued source; continue polling until its `ingest_status` reaches a terminal state.

# paths./api/v1/sources/{source_id}.patch.responses.200.description
Data source updated and queued for synchronization.

# paths./api/v1/sources/{source_id}.patch.responses.404.description
The requested data source does not exist.

# paths./api/v1/sources/{source_id}.patch.responses.409.description
The request body type does not match the source's origin type.

# paths./api/v1/sources/{source_id}/schema.patch.description
Set or clear free-text comments on one or more columns of a data source's schema.

Comments help the AI interpret ambiguous or business-specific columns. Only the `comment` of the listed columns is changed; `name`, `type`, and any other column are left untouched. Pass `comment: null` to clear a column's comment.

# paths./api/v1/sources/{source_id}/schema.patch.responses.404.description
The requested data source does not exist.

# paths./api/v1/sources/{source_id}/tags.put.responses.404.description
The requested data source does not exist.

# paths./api/v1/origins/.get.description
List data origins for the current organization, including nested data sources.

Use `origin_id` to retrieve a single origin by UUID.

# paths./api/v1/origins/.delete.description
Delete multiple data origins by UUID.

The response includes both the number of deleted origins and any requested IDs that could not be deleted.

# paths./api/v1/origins/{origin_id}/sources.get.description
List the data sources that belong to a single data origin.

# paths./api/v1/origins/{origin_id}/sources.get.responses.200.description
Sources for the origin listed successfully.

# paths./api/v1/origins/{origin_id}/sources.get.responses.404.description
The requested data origin does not exist.

# paths./api/v1/origins/{origin_id}/sources.get.responses.500.description
The origin sources could not be retrieved.

# paths./api/v1/origins/{origin_id}/sources.post.description
Create a new data source under an existing origin and immediately sync its data.

The request body must include a `type` discriminator that matches the origin type. File-type origins do not support individual source creation — sources in a file origin represent worksheets inside the uploaded file.

# paths./api/v1/origins/{origin_id}/sources.post.responses.201.description
Data source created and synced successfully.

# paths./api/v1/origins/{origin_id}/sources.post.responses.400.description
The upstream endpoint could not be reached or returned an error.

# paths./api/v1/origins/{origin_id}/sources.post.responses.404.description
The requested data origin does not exist.

# paths./api/v1/origins/{origin_id}/sources.post.responses.409.description
The request body type does not match the origin type, or the origin type does not support source creation.

# paths./api/v1/origins/{origin_id}/ingest/events.get.description
SSE stream of per-source ingest status, polled every ~2s.

- `event: status` — `data: [{id, ingest_status, ingest_error_code}, ...]`
- `event: done` — the origin has reached a terminal status

# paths./api/v1/origins/{origin_id}/ingest/events.get.responses.404.description
The requested data origin does not exist.

# paths./api/v1/origins/file/.post.description
Create a file-based data origin and its derived data sources from one or more remote files.

A `201` response confirms that the origin was created and spreadsheet ingestion was queued; it does not mean tabular data is ready for reports. Source records are created by the worker and can therefore be absent from `created_data_origins[].data_sources` in the initial receipt.

This asynchronous source discovery is the supported contract: use the returned origin ID rather than expecting source IDs in the receipt.

Spreadsheet files are queued for materialization to Parquet via the dlt ELT pipeline (one source per worksheet/table block); document files are ingested as searchable chunks.

Use `created_data_origins[].id` to wait with `GET /api/v1/origins/{origin_id}/ingest/events` or poll `GET /api/v1/sources/?origin_id=<origin-id>`. Create a report only after the required tabular sources reach `completed`; document sources are exempt from that readiness gate.

# paths./api/v1/origins/file/.post.responses.201.description
File origin created; tabular sources queued for ingestion.

# paths./api/v1/origins/file/.post.responses.502.description
The upstream file source is unavailable.

# paths./api/v1/origins/data-api/.post.description
Create a data origin backed by an external data API.

Each declared endpoint is queued for materialization to Parquet via the dlt ELT pipeline and becomes one data source. Supported endpoint formats are JSON and CSV.

Top-level `headers`, `api_key`, and `api_key_header` define the shared upstream request configuration for the origin. Each endpoint can also define its own `query_params` and `headers` to customize the request made to that specific upstream path.

A `201` response confirms that the source ingestion was queued, not completed. The receipt returns the queued sources directly; poll each `data_sources[].id` with `GET /api/v1/sources/?source_id=<source-id>` before using it in a report.

# paths./api/v1/origins/data-api/.post.responses.201.description
API origin created; sources queued for ingestion.

# paths./api/v1/origins/data-api/.post.responses.400.description
The upstream API is unavailable or returned an error.

# paths./api/v1/origins/postgres/.post.description
Register a live external Postgres origin queried directly by DuckDB (no data materialized; `size_bytes` is always 0).

The receipt returns `origin_id`. Resolve the registered live sources with `GET /api/v1/sources/?origin_id=<origin-id>`. Origin-level lifecycle propagation is work in progress, so origin status is not yet a stable readiness contract for PostgreSQL.

# paths./api/v1/origins/postgres/.post.responses.500.description
The Postgres origin could not be registered.

# paths./api/v1/public/reports/{token}.get.description
Retrieve a publicly shared report by its signed share token.

No authentication required. Returns 400 if the token is invalid or expired, 404 if the report does not exist or sharing has been disabled.

Optional `?language=` returns that language's content when available.

# components.schemas.APIErrorPayload.properties.code.description
Optional machine-readable error code for specific API flows.

# components.schemas.APIErrorPayload.properties.request_id.description
Server-side request identifier for troubleshooting internal errors.

# components.schemas.BlankReportCreateRequest.properties.data_sources_ids.description
UUIDs of the data sources used as context for the report.

# components.schemas.BlankReportParamsAPI.properties.language.description
Report language (english, italian, german, dutch, french, spanish, portuguese, romanian, chinese, japanese)

# components.schemas.BlankReportParamsAPI.properties.currency.description
Currency code (USD, EUR, JPY, GBP, CNY, AUD, CAD, CHF, etc.)

# components.schemas.BlankReportParamsAPI.properties.color.description
Hex color code (e.g., #2871CC) or empty for AI to choose

# components.schemas.CleaningDecision.description
A user's resolution of a single cleaning candidate column.

``keep_text`` retains the column as-is. ``temporal``/``numeric`` cast it with
the supplied interpretation. The same shape is reused internally to carry
automatic casts (no user review needed).

# components.schemas.ColumnCommentUpdate.properties.name.description
Column name as it appears in the source's schema.

# components.schemas.ColumnCommentUpdate.properties.comment.description
Free-text note to help the AI understand the column. Set to null to clear it.

# components.schemas.CreateApiSourceParams.properties.path.description
Endpoint path relative to the origin base URL.

# components.schemas.CreateApiSourceParams.properties.query_params.description
Query parameters sent to the upstream endpoint.

# components.schemas.CreateApiSourceParams.properties.headers.description
Per-endpoint headers (merged with origin-level headers; these win on collision).

# components.schemas.CreateApiSourceParams.description
Parameters for creating a new source under an API-type origin.

# components.schemas.CustomCreateReportRequest.properties.data_sources_ids.description
UUIDs of the data sources used as context for the report.

# components.schemas.CustomCreateReportRequest.properties.improve_prompt.description
If true, the backend may improve the prompt before running the report.

# components.schemas.CustomReportParamsAPI.properties.language.description
Report language (english, italian, german, dutch, french, spanish, portuguese, romanian, chinese, japanese)

# components.schemas.CustomReportParamsAPI.properties.currency.description
Currency code (USD, EUR, JPY, GBP, CNY, AUD, CAD, CHF, etc.)

# components.schemas.CustomReportParamsAPI.properties.color.description
Hex color code (e.g., #2871CC) or empty for AI to choose

# components.schemas.CustomReportParamsAPI.properties.prompt.description
Natural language description of the report to generate

# components.schemas.CustomReportParamsAPI.properties.dataset_info.description
Additional context about the dataset structure

# components.schemas.CustomReportParamsAPI.properties.data_provenance.description
Include data source citations in the report

# components.schemas.CustomReportParamsAPI.description
Parameters for custom report generation.

# components.schemas.DataSourceColumn.properties.comment.description
User-provided note explaining the column's meaning, to help the AI interpret it.

# components.schemas.Endpoint.properties.display_name.description
Display name for the data source created from this upstream endpoint.

# components.schemas.Endpoint.properties.path.description
Path appended to `base_url` when requesting the upstream endpoint.

# components.schemas.Endpoint.properties.format.description
Expected response format returned by the upstream endpoint.

# components.schemas.Endpoint.properties.query_params.description
Optional query string parameters to send to this specific upstream endpoint. Use these to filter the upstream data before ingestion.

# components.schemas.Endpoint.properties.headers.description
Optional headers to send only for this specific upstream endpoint. If the same header is also defined at origin level, this endpoint value wins.

# components.schemas.GenerateAISectionRequest.properties.prompt.description
Instruction for the AI-generated section to add within the report context.

# components.schemas.GenerateAISectionRequest.example.prompt
Analizza i pagamenti di oggi e crea una breve sezione con gli insight principali.

# components.schemas.ImprovePromptRequest.properties.data_sources_ids.description
UUIDs of the data sources used as context for improvement.

# components.schemas.IngestFromDataAPIRequest.properties.headers.description
Additional headers to send to the upstream API.

# components.schemas.IngestFromDataAPIRequest.properties.api_key.description
API key used to access the upstream data API.

# components.schemas.IngestFromDataAPIRequest.properties.api_key_header.description
Header name used to send the upstream API key.

# components.schemas.IngestFromDataAPIRequest.properties.endpoints.description
Endpoints to ingest from the upstream API. Supported formats are `json` and `csv`.

# components.schemas.IngestStatus.description
Granular ELT lifecycle of a DataSource.

Only ``completed`` sources are query-ready/selectable. ``awaiting_confirmation``
is attention-terminal but unselectable (raw Parquet exists, cleaning needs a
user decision). Backend type is derived from the origin type, not from here.

# components.schemas.ProcessFilesRequest.properties.files.description
Files to ingest. The `name` should reflect the real file type, such as `.csv` or `.xlsx`. Use `FileInput` with a `url` for remote files, or `S3FileInput` with a `key` for files already uploaded to the app S3 bucket.

# components.schemas.RegisterPostgresOriginRequest.properties.connection_string.description
libpq connection string of the external Postgres.

# components.schemas.ReportChatRequest.properties.message.description
User message to the report-scoped AI assistant.

# components.schemas.ReportChatRequest.example.message
Spiegami i punti principali del report e quali insight ritieni più importanti.

# components.schemas.RoverCreateReportRequest.properties.data_sources_ids.description
UUIDs of the data sources used as context for the report.

# components.schemas.RoverCreateReportRequest.properties.improve_prompt.description
If true, the backend may improve the prompt before running the report.

# components.schemas.RoverParamsAPI.properties.language.description
Report language (english, italian, german, dutch, french, spanish, portuguese, romanian, chinese, japanese)

# components.schemas.RoverParamsAPI.properties.currency.description
Currency code (USD, EUR, JPY, GBP, CNY, AUD, CAD, CHF, etc.)

# components.schemas.RoverParamsAPI.properties.color.description
Hex color code (e.g., #2871CC) or empty for AI to choose

# components.schemas.RoverParamsAPI.properties.data_provenance.description
Include data source citations in the report

# components.schemas.RoverParamsAPI.properties.seeded_question.description
If set, skip candidate generation for the first step and use this question as the seeded winner.

# components.schemas.RoverParamsAPI.properties.goal.description
Optional high-level objective that orients the entire investigation (e.g. 'reduce churn below 5% by Q3').

# components.schemas.TranslateReportRequest.properties.replace.description
If true, overwrite an existing translation for this language.

# components.schemas.UpdateApiSourceParams.properties.path.description
New endpoint path relative to the origin base URL.

# tags[].description
Create asynchronous reports from ready data sources, inspect status and content, translate and export reports, generate AI sections, redo reports, and interact with report-scoped chat.

# tags[].description
Manage data origins, which are the top-level containers for one or more data sources. File and API origins ingest asynchronously; PostgreSQL origins are queried live through DuckDB.

# tags[].description
Manage the queryable datasets derived from origins. Inspect ingestion state, confirm ambiguous cleaning, retry failures, preview data, and synchronize compatible sources.