> Source: https://builder.ema.ai/v2/testing-operations/chat-metrics
> Title: Chat Metrics

# Chat Metrics

Chat metrics let you pull the raw conversational data behind a chat AI Employee (AIE) into your own data warehouse or BI tool. Where the in-app [metrics dashboard](/builder/v2/testing-operations/launching-and-monitoring) gives you charts inside Ema, the chat metrics export gives you the underlying rows — one per message — so you can join, aggregate, and analyze them however you need.

The export is served by the chat service over two endpoints: a modern, streaming **messages** export (32 columns) and a legacy, wire-compatible **conversations** export (22 columns). Both support CSV; the messages export also supports NDJSON and paginated JSON.

> [INFO]
> **Admin-only, and enabled per environment.** Both export endpoints require the `system_admin` role, and they are gated behind a feature flag (`EMU_CHAT_METRICS_API_ENABLED`): the routes are not registered until your environment is configured for the export. If the endpoints return a not-found, the export isn't enabled for your tenant yet.

## Messages export (32 columns)

`GET /metrics/messages` returns row-level conversational data — **one row per chat message** — with the message joined to the workflow run that produced it, retrieval sources, user feedback, conversation review state, and non-PII user context. This is the export to use for new BI integrations.

### Formats

Choose the format with the `format` query parameter (CSV is the default; the `Accept` header is honored as a fallback when `format` is omitted):

`format`

Behavior

`csv` (default)

RFC 4180 CSV, streamed via chunked transfer with `Content-Disposition: attachment`. One header row, then one row per message. Streams the full filtered range.

`ndjson`

One JSON record per line, no envelope, streamed. Streams the full filtered range.

`json`

One paginated page: `{ items, next_cursor, page_info }`. You walk `next_cursor` until it's null.

Repeated or unbounded structures (citations, model breakdown, user attributes) are JSON-encoded into single columns (`sources_json`, `model_breakdown_json`, `user_attributes_json`) so a warehouse `PARSE_JSON()` works without exploding the row count.

### Filters

Parameter

Meaning

`since`

Inclusive lower bound on the message `created_at` (RFC 3339).

`until`

Exclusive upper bound on `created_at` (RFC 3339). Defaults to now.

`updated_since`

Switches the time filter to a 30-day look-back over message, feedback, and review update times — returns rows whose message, feedback, or review state changed at or after this timestamp (RFC 3339).

`workflow_id`

Restrict to one AI Employee (UUID).

`cursor`

Opaque keyset cursor from the previous page's `next_cursor`. **Only valid with `format=json`.**

`limit`

Page size for `format=json` (1–500, default 200). CSV and NDJSON ignore this and stream the full range.

Supplying `cursor` or `limit` with a streaming format returns a validation error (`422`) — the streaming formats always walk the entire filtered range.

### Columns

The CSV header is fixed and ordered — 32 columns. Each row carries these columns:

Column

Notes

`message_id`

`role`

Message author role.

`content`

Message text (PII rendered per tenant policy — see below).

`created_at`

`session_id`

`session_title`

`session_started_at`

`session_deleted`

`session_deleted_at`

`channel_type`

The channel the conversation came through.

`channel_display_name`

`workflow_id`

The AI Employee.

`run_id`

The workflow run that produced the message; empty when there is none.

`run_status`

`run_latency_ms`

`run_total_tokens`

`feedback_sentiment`

Empty when no feedback.

`feedback_category`

`feedback_text`

`feedback_submitted_at`

`feedback_updated_at`

`review_resolution_status`

Conversation review state; empty when not reviewed.

`review_comment_count`

`review_updated_at`

`user_actor_type`

`user_external_id`

`user_display_name`

`user_department`

`user_attributes_json`

JSON object; `{}` when empty.

`sources_json`

JSON array of retrieval sources; `[]` when empty.

`model_breakdown_json`

JSON array of per-model token usage; `[]` when empty.

`schema_version`

The export schema version. Adding a column at the end is non-breaking; reordering or removing is announced via a `Sunset` header and a `schema_version` bump.

```bash
curl -G 'https://<your-tenant>/api/v1/chat/metrics/messages' \
  -H 'Authorization: Bearer <token>' \
  --data-urlencode 'format=csv' \
  --data-urlencode 'since=2026-05-01T00:00:00Z' \
  --data-urlencode 'until=2026-06-01T00:00:00Z' \
  --data-urlencode 'workflow_id=8f3c....'
```

### Streaming, limits, and errors

-   **One streaming export per tenant.** CSV and NDJSON are subject to a per-tenant concurrent-stream cap — only one streaming export runs at a time, and the cap is shared across both endpoints so you can't open `/metrics/messages` and `/metrics/conversations` in parallel to dodge it. A second concurrent request gets `429` with a `Retry-After`. Paginated JSON is not subject to the cap.
-   **Mid-stream truncation.** Because streaming sends `200 OK` and the header row before all rows are known, an error after streaming has begun can't change the status code. Detect truncation by row count, not by HTTP status.
-   **Slow queries.** A query that exceeds the database statement timeout returns `503` with a `Retry-After`; narrow the time window and retry.
-   **Auditing.** Every export is recorded as an audit event (with format, row count, and the filters used), because content may be returned in cleartext depending on tenant PII policy.

## Conversations export (legacy, 22 columns)

`GET /metrics/conversations` is a wire-compatible replacement for the legacy `chatbot/conversations` export. It returns **one row per chat message** in the window, denormalized with conversation, external-user, feedback, and workflow-run-error context, in a fixed **22-column** order that matches the legacy exporter exactly — so existing downstream warehouses keep working without a contract change.

### Parameters

Parameter

Meaning

`persona_id` (required)

The AI Employee (UUID) — the chat session's `workflow_id`.

`start_date` (required)

Inclusive lower bound, UTC `YYYY-MM-DD`.

`end_date` (required)

Inclusive upper bound, UTC `YYYY-MM-DD`. The total range must be ≤ 31 days.

`format`

`csv` (default) or `json`. `json` returns an array with the same field names as the CSV header.

An empty range returns `200` with a header-only CSV. An invalid `persona_id`, malformed dates, or a range over 31 days returns `422`.

### Columns

The 22 columns, in order:

`conversation_id`, `conversation_source`, `conversation_created_at`, `conversation_updated_at`, `encrypted_user_email`, `message_id`, `is_user_message`, `message_created_at`, `message_updated_at`, `workflow_run_error`, `external_tool_called`, `external_tool_call_success`, `external_tool_name`, `user_feedback_type`, `user_feedback_comment`, `feedback_message_sent`, `content_payload_json`, `user_context`, `unique_source_ids`, `country`, `band`, `events_per_message`.

> [TIP]
> **Which export to use.** Use the **messages** export for new integrations — it streams, supports NDJSON and JSON, has richer columns, and carries a `schema_version`. Use the **conversations** export only when you must match the legacy 22-column contract a downstream warehouse already depends on.

## A note on PII and content

Message content and user context may contain personal data. What's returned depends on your tenant's PII policy: content can be rendered in cleartext for tenants that have opted in, which is exactly why every export is audited. The export never silently falls back to raw cleartext when the PII service is unavailable — it returns `503` instead. Treat exported files as sensitive data and handle them under your organization's data-governance rules.

## What's next

-   [Launching and monitoring](/builder/v2/testing-operations/launching-and-monitoring) — the in-app dashboard view of the same data.
-   [Debug logs](/builder/v2/testing-operations/debug-logs) — drill into the individual run behind a `run_id` in the export.
-   [API reference](/builder/v2/api-reference) — full request and response schemas.
