Conversation
A conversation is an ordered sequence of messages exchanged between an end user (or another system) and your agent, identified by aconversation_id string. It is the unit nearly every Moda analysis operates on: summaries, world state, signals, use cases, and problems are all computed per conversation. Conversations appear in the dashboard at Observe → Conversations and through the Data API’s conversation endpoints.
Setting the conversation ID
Any non-empty string works as a conversation ID. Use an identifier your application already has — a session ID, thread ID, run ID, or ticket ID — and set it before the first model call. Set it in one of three ways:- SDKs —
moda.conversation_id = "..."in Python,Moda.withConversationId(...)in Node.js. - Ingestion API — the required
conversation_idfield on every/v1/ingestevent. - OpenTelemetry — the
moda.conversation_idspan attribute on/v1/traces(see OpenTelemetry).
Message
A message is one event inside a conversation: a user turn, an agent response, a system prompt, or a tool interaction. The SDKs create messages automatically from instrumented LLM calls. The field names below are as they appear onPOST /v1/ingest events; each has an OTLP-attribute equivalent on /v1/traces.
User
A user is an end user of your agent, identified by an optionaluser_id string — an opaque identifier from your own system. Set it with moda.user_id = "..." (Python), Moda.withUserId(...) (Node.js), the user_id event field on /v1/ingest, or the moda.user_id OTLP attribute.
Setting user_id powers:
- The Users page (Understand → Users): per-user health and activity, cohorts such as power users and at-risk users, and a per-user detail view with inferred traits, intent distribution, frustration trajectory, tool failures, and an activity feed.
- User filtering: the conversations list in the dashboard and the
user_idparameter onGET /conversations. - User-impact metrics, such as the Users Impacted KPI on tool failures.
user_id are not attributed to any individual user: they are excluded from per-user rows and cohorts, and the Users page rolls them into a single aggregated anonymous row instead.
Environment
Every message belongs to one of three environments:development, staging, or production. Environments keep test traffic out of production analytics: the Conversations page has an environment filter, and the Data API accepts an environment parameter on GET /conversations.
Set the environment with:
- the
environmentfield on the/v1/ingestrequest body, with an optional per-event override - the
environmentoption ofModa.init(...)in Node.js - the
moda.environmentspan attribute ordeployment.environmentresource attribute over OTLP; in Python, passresource_attributes={"deployment.environment": "staging"}tomoda.init(...)
dev and develop become development; stg and stage become staging; prod becomes production. Any unrecognized or missing value is recorded as production.
Prompt attribution fields
Messages can carryprompt_id, prompt_name, prompt_version, and prompt_version_id to link a model call to a managed prompt version. The same link is available as moda.prompt_key / moda.prompt_version (and related) OTLP span attributes, and as telemetry metadata in the Vercel AI SDK integration. Version IDs come from the .moda/prompts.lock.json file written by moda prompts sync.
These fields power per-version usage and comparison in Prompts. See Prompt attribution for the full mechanism.
Next steps
- Analysis — what Moda computes from this data and where each result appears.
- Ingestion overview — pick an ingestion path for your stack.
- Ingestion API reference — exact request schemas, limits, and error envelopes.
- Prompt attribution — wire prompt versions into your telemetry.