The Observability system automatically collects execution traces for analysis and debugging, and provides aDocumentation Index
Fetch the complete documentation index at: https://docs.runflow.ai/llms.txt
Use this file to discover all available pages before exploring further.
track() API for emitting custom business events that power real-time dashboards.
Automatic Tracing (Agent)
Automatic Tracing (Workflow)
Workflows automatically trace every step with full hierarchy:function, agent, connector, condition, switch, foreach, parallel) is traced with its own color and label in the portal.
Verbose Tracing Mode
Control how much data is saved in traces. Works identically for Agent and Workflow. Modes:full: Complete data including prompts and responses (default)standard: Balanced metadata with truncationminimal: Disables tracing entirely (no traces sent)
Trace Interceptor (onTrace)
Intercept, modify, or cancel traces before they are sent. Available in Agent, Workflow, and standalone logging.- Return the trace (modified or not) to send it
- Return
nullto cancel (trace is not sent) - Return
voidto send unchanged
Trace Hierarchy (startSpan)
Create parent-child relationships between custom logs for structured traces:Custom Executions (Non-Agent Flows)
For scenarios withoutagent.process() (document analysis, batch processing, etc.):
Custom Logging
Log custom events within any execution:Conversation Messages
Available since
@runflow-ai/sdk@1.1.10.message() to record a turn of a conversation. Each call emits a conversation_message trace that the Runflow portal renders as a chat bubble: user inbound on the left, assistant outbound on the right.
The portal switches automatically to chat view when an execution has at least one conversation_message trace — no flag, no channel hint. The thread sidebar preview also updates to show the latest user/assistant text instead of raw envelope JSON.
When to use
- Custom workflows (WhatsApp handlers, webhook routers) where you control the message flow without
agent.process(). - LLM agents when you want to also expose the conversation as chat (wrap
agent.process()calls). - Anywhere you want the execution to render as a conversation in the portal.
message(), nothing changes — your existing traces and rendering keep working exactly as before.
Wrapping an agent call (LLM)
Custom workflow (no LLM)
startSpan call is optional but recommended — it groups the technical traces under the turn so the drill-down drawer in the portal stays organized.
Multiple assistant messages per turn
A turn can emit any number of assistant messages — they render as consecutive bubbles in chronological order, exactly like WhatsApp:Structured content (buttons, audio, image)
content accepts a string OR an object with a type field. The portal renders text natively and falls back to a JSON view for structured content (buttons / media renderers are on the roadmap):
Hierarchy and grouping
Messages follow the same parenting rules aslog() and startSpan():
| You write | Where the message goes |
|---|---|
message({...}) inside a startSpan() block | Child of the active span |
message({..., parentId: span.traceId }) | Child of that span explicitly |
message({...}) with no active span | Root (no grouping) |
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
data.role | string | Yes | 'user', 'assistant', 'system', 'tool', or any custom string |
data.content | string | object | Yes | Text (renders natively) or structured object with a type field |
data.metadata | Record<string, any> | No | Extra fields (citations, confidence, custom flags) |
data.parentId | string | No | Explicit parent span’s traceId |
options.parentId | string | No | Same as data.parentId (positional override) |
Business Event Tracking
Usetrack() to emit custom business events from your agent. These events power the Metrics dashboard in the portal, where you can build KPI cards, charts, and real-time feeds without writing any backend code.
Events are buffered and sent in batches automatically (up to 50 events or every 2 seconds). No manual flushing needed during normal execution.
How It Works
- Call
track(eventName, properties)anywhere in your agent code - The SDK buffers events and sends them in batches to the Runflow API
- Open the Metrics tab in the portal to create dashboard cards
- Cards auto-discover your event names and properties — no configuration needed
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
eventName | string | Yes | Name of the event (e.g. 'alert_received', 'order_placed') |
properties | Record<string, any> | No | Key-value pairs with event data |
options | TrackOptions | No | Override threadId, executionId, or timestamp |
Options
Flushing Before Exit
For short-lived scripts or CLI tools, callflushTrackEvents() before exiting to ensure all events are sent:
Dashboard Cards
In the portal, navigate to your agent’s Metrics tab to create cards:- Number — KPI with a single aggregated value (count, sum, avg)
- Rate — Percentage based on a filtered property value
- Line / Bar — Time-series charts grouped by hour, day, week, or month
- Pie — Distribution chart over time periods
| Aggregation | Description | Example |
|---|---|---|
count | Total events | Total alerts received |
rate | Percentage where property matches a value | % of alerts answered |
sum | Sum of a numeric property | Total revenue |
avg | Average of a numeric property | Average response time |
distinct_count | Count of unique property values | Unique companies served |
Best Practices
Use descriptive event names
Use descriptive event names
Use
snake_case names that describe what happened: alert_received, ticket_resolved, payment_processed. Avoid generic names like event or action.Keep properties flat
Keep properties flat
Properties are stored as JSON and queried via keys. Flat key-value pairs work best for dashboard aggregations:
Use consistent property types
Use consistent property types
Keep the same property as the same type across events. If
duration is a number in one event, don’t send it as a string in another — aggregations like sum and avg rely on numeric values.Observability Comparison
| Feature | Agent | Workflow | Standalone (log) |
|---|---|---|---|
| Automatic tracing | Yes | Yes | Manual |
Mode (full/standard/minimal) | Yes | Yes | — |
onTrace interceptor | Yes | Yes | configureLogging() |
| Truncation control | Yes | Yes | — |
| Trace hierarchy | Automatic | Automatic (steps) | startSpan + parentId |
| Chat rendering in portal | Via message() wrapper | Via message() wrapper | Via message() |
| Default mode | full | full | — |
Next Steps
Workflows
Workflow tracing and step types
Configuration
Configure observability