Run reports

What the SDK reports about every assistant run, which fields each integration fills, and how to configure and enrich the reports.

Every assistant response is a run. When a run finishes, the SDK sends one run report to the project: what happened, how long it took, which model and tools were involved, and how it ended. Reports never carry the user's messages, but they do carry the assistant's output text and the tool arguments and results, each cut at 50,000 characters, the error message, cut at 2,048, and whatever metadata the integration or your beforeReport hook attaches, so they can contain sensitive content; beforeReport can redact or drop a report and telemetry: false turns reporting off, see Enriching or filtering reports. Reports are the source of the Runs, Models, Users and Overview pages in the dashboard.

Reporting is on by default for every integration that persists messages. This page describes the report, the fields each integration can fill, and the telemetry configuration on AssistantCloud.

The run report

A report is one POST /v1/runs with the fields below. The SDK builds it with createRunReport, so every integration sends the same shape.

FieldTypeMeaning
thread_idstringThe cloud thread the run belongs to.
status"completed", "incomplete", "error"How the run ended. incomplete carries an outcome_type.
outcome_typesee OutcomesWhy an incomplete or failed run ended. Omitted for a completed run.
error, error_codestringThe failed run's message and code. The code is the error's code when it has one, else its class name (AI_APICallError).
message_idstringThe stored assistant message the run produced, so the dashboard can open it.
duration_msnumberWall clock time from the first request to the last chunk.
first_token_msnumberTime to the first streamed token.
stepsarrayOne entry per model step: input_tokens, output_tokens, reasoning_tokens, cached_input_tokens, tool_calls, start_ms, end_ms, finish_reason.
total_stepsnumberThe number of steps.
tool_callsarrayEvery tool invocation with tool_name, tool_call_id, tool_args, tool_result, tool_source (frontend or mcp) and any nested sampling_calls.
input_tokens, output_tokens, reasoning_tokens, cached_input_tokensnumberUsage for the whole run.
model_id, providerstringThe model that served the run and the provider that served the model.
output_textstringThe assistant output, truncated at 50,000 characters.
trace_idstringThe W3C trace id of the server spans, when trace correlation is set up. A report with a trace id merges into the run the server spans created.
environment, release, tagsstring, string, string[]The deployment dimensions from the telemetry configuration. They become facets on the Runs page.
metadataobjectAttributes attached through beforeReport, shown on the run's page.

Field limits: error is cut at 2,048 characters and error_code at 64, output_text at 50,000, environment at 64, release at 255, tags at 64 characters each and 20 per report, and duration_ms and first_token_ms are rounded to whole milliseconds. The endpoint is append only: a report may also carry cost_usd or cost_details to override the catalog price, and any key it does not know is kept in the run's attributes rather than rejected, so an older cloud accepts a newer SDK and the other way round.

What each integration reports

The integrations observe runs differently, so they do not all fill every field.

Fieldassistant-ui runtime, aui/v0assistant-ui runtime, ai-sdk/v6useCloudChat
status, error, error_codeyesyesyes
outcome_typelength, content_filter and aborted from the message statussame, plus a finishReason the route puts in message metadataall four, from the AI SDK finish event
first_token_ms, duration_msyesyesyes
steps with start_ms and end_msyesyesyes
Per step finish_reasonno"tool-calls" on a step that called a toolthe finish event's reason
tool_calls with tool_sourcewithout tool_sourceyesyes
Usagefrom message metadatafrom message metadatafrom message metadata
model_id, providerfrom message metadatafrom message metadatafrom message metadata
trace_idfrom message metadatafrom message metadatafrom message metadata

The assistant-ui runtime rows apply to useLocalRuntime and useChatRuntime, whose history adapter persists and reports every run. The LangGraph, LangChain and Google ADK runtimes keep their own transcripts, so with them the cloud provides the thread list, titles and feedback but no run report; see LangGraph.

Route configuration

Usage, model and provider only exist on the server, so the route has to put them into the message metadata the SDK reads. With the AI SDK, add a messageMetadata callback to the stream response:

app/api/chat/route.ts
import { convertToModelMessages, streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const model = openai("gpt-5.6-luna");
  const result = streamText({
    model,
    messages: await convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse({
    messageMetadata: ({ part }) => {
      if (part.type === "finish") {
        return { usage: part.totalUsage, finishReason: part.finishReason };
      }
      if (part.type === "finish-step") {
        return { modelId: part.response.modelId, provider: model.provider };
      }
      return undefined;
    },
  });
}

The SDK reads these metadata keys:

KeyBecomes
usageThe run's token counts. inputTokens, outputTokens, reasoningTokens and cachedInputTokens are read, and the AI SDK's older promptTokens and completionTokens names still work. Without usage, per step steps[].usage entries are summed.
modelIdmodel_id. A per step response.modelId is read when the run level id is absent.
providerprovider. Server spans carry the provider as well when trace correlation is on.
finishReasonoutcome_type for length and content-filter, and the error status for error.
traceIdtrace_id. withAssistantCloudTraceMetadata sets it for you.
samplingCallsNested model calls made by tools, attached to the matching tool call. See Traces.

Without this configuration the report still arrives, without model, provider and usage. The dashboard shows such runs under "No model reported" and cannot price them.

Outcomes

The browser reports four outcomes. Runs the cloud executes itself, through assistants, add the server side ones.

outcome_typestatusMeaningReported by
abortedincompleteThe user stopped the run.the browser, and the assistant run endpoint on an aborted request
disconnectedincompleteThe stream disconnected before completion.useCloudChat
lengthincompleteThe model reached its output length limit.the browser and server spans
content_filterincompleteThe provider filtered the response.the browser and server spans
timeouterrorThe run exceeded the assistant's timeout.the assistant run endpoint
rate_limitederrorThe provider answered 429.the assistant run endpoint
provider_errorerrorThe provider answered another HTTP error.the assistant run endpoint
server_errorerrorThe run failed inside the cloud.the assistant run endpoint

A failed run has status: "error" and, when the cause is known, an outcome from the second group. The Overview and the Runs page turn these into the completion rate and the outcome facets.

Deployment dimensions

environment, release and tags on the telemetry configuration are stamped onto every report the client sends. They become facets on the Runs page, so a regression can be narrowed to one release or one environment.

const cloud = new AssistantCloud({
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
  anonymous: true,
  telemetry: {
    environment: "production",
    release: "2026.09.1",
    tags: ["web", "eu"],
  },
});

release is your application's version, not the SDK's. The SDK identifies itself separately: every request carries an Aui-Sdk header naming the assistant-cloud version and the integration packages on it, and Settings › Telemetry lists the versions a project has seen.

Enriching or filtering reports

beforeReport runs last, with the assembled report. Return a modified report to add attributes, or null to drop it.

const cloud = new AssistantCloud({
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
  authToken: getToken,
  telemetry: {
    beforeReport: (report) => {
      if (report.thread_id === internalTestThread) return null;
      return { ...report, metadata: { ...report.metadata, plan: "pro" } };
    },
  },
});

metadata is stored as the run's attributes and shown on the run's page; keep it to a few short keys.

Turning telemetry off

SettingEffect
telemetry: falseNo run reports and no engagement events. Threads and messages are still persisted.
telemetry: { events: false }Run reports stay on, engagement events stop.
telemetry: true or omittedEverything on.

Where reports appear

  • Runs lists every report with facets for status, outcome, model, provider, environment, release, tags and user, and an Analysis view over the same range.
  • A run's page shows its steps, tool calls and usage as a timeline, and the server spans when a trace was correlated.
  • Models aggregates runs and cost per model and provider, Users per end user, and the Overview carries the completion rate, latency percentiles and daily volume.

The demo project shows each of them on synthetic data.