Skip to main content

Introduction

Every pathway call produces an ordered timeline of events: what the caller and assistant said, how the pathway routed between nodes, and every side effect that ran along the way (webhooks, tools, variable extraction, transfers, SMS, and so on). This page documents that timeline — the fields on every event, every event type you can encounter, and what their payloads look like.

Fetching the events

Retrieve the event timeline for a call with the Get Pathway Call Events endpoint, passing ?v=2 for the events format:
The response is a JSON array of event objects, ordered by sequence.

The event envelope

Every event in a call’s log has the same outer shape:

Event catalog

Conversation & routing events

Operation events

Operations are side effects that run during the call. Each one produces an invoke event when it starts, and then some combination of:
  • operation.result — it finished; the payload holds the outcome.
  • operation.error — it failed; payload is { "message": "...", ...context }.
  • operation.warning — something non-fatal happened (e.g. a retry); same shape as error.
The operations:
Pairing invokes with results: the invoke event’s sequence becomes the operation_id on its result / error / warning / mapping events. Two webhooks can be in flight at once and you can still pair each result with the right request.

Conversation & routing payloads

conversation.init

node.transition

node.tag

The payload is the tag itself: { "name": "...", "color": "#...", ... }. name is always present; color and editor metadata may accompany it.

transcript.user

transcript.assistant

interrupt.early / interrupt.late

button.press

llm.action

Operation payloads

webhook.invoke

webhook.result

webhook.mapping

One event per webhook/tool invocation that has response mappings, correlated to the invoke via operation_id. This is the first place to look when a caller asks “why is {{my_var}} empty?” Each entry in mappings:

tool.invoke

You may also see tool, type, and input_vars — legacy aliases of tool_name, tool_type, and input_variables kept for older consumers. Same values.

tool.result

(output and elapsed are legacy aliases of output_variables and duration_ms.)

kb.invoke / kb.result

sms.invoke / sms.result

scheduling.invoke / scheduling.result

loop_condition.invoke / loop_condition.result

var_extraction.invoke / var_extraction.result

custom_code.invoke / custom_code.result

transfer_pathway.invoke / transfer_pathway.result

transfer_call.invoke / transfer_call.result

unit_test.invoke / unit_test.result

operation.error / operation.warning (all operations)

Things to know when reading a log

  • Sort by sequence. created_at timestamps can tie or arrive slightly out of order; sequence is the truth.
  • Sequence gaps are normal. They do not indicate missing data.
  • Large values are truncated. Result-type payloads (webhook/tool/KB/custom-code/scheduling results and mapping previews) cap each top-level value at 64 KiB. A truncated value appears as a string ending in . On some older calls, oversized values were instead replaced with the sentinel string "[EXCEEDS_MAX_LENGTH]"; the log service automatically recovers the full data from an older storage path when it can.
  • Sensitive values are redacted before storage — you may see redaction placeholders in headers or variable values.
  • Synthetic triggers are hidden. Internal markers that drive the conversation engine (call-connected signals, silence timeouts) are stored as user-transcript events but filtered out of the log you see. Events they caused — transitions, webhooks, extractions — remain, so you may see activity without a visible caller utterance right before it.
  • Interrupted speech is visible. When the caller talks over the assistant, the assistant’s text shows what was actually spoken, and generated_response preserves the full intended sentence. Interrupt events mark where it happened.
  • external_id is your escalation handle. It’s an opaque id — it reveals nothing by itself, but Bland can use it internally to pull up the exact model request behind an utterance, routing decision, or extraction. Include it when filing an issue about “why did the agent say/do this.”
  • Very old calls predate this event system entirely. Their logs are converted from the legacy format on the fly, so they contain the same event shapes but fewer event types and sparser payloads.
  • Tags: a call’s pathway tags come from the node.tag events (or a post-call aggregate of them). Each tag is { name, color? }.

Worked example

A short call that routes to an order-lookup node, calls a tool, and reads the result back. Envelope fields abbreviated after the first event.
Reading it: the webhook.result and webhook.mapping events both carry operation_id: 6, tying them to the webhook.invoke at sequence 6. The mapping event confirms both variables populated ("outcome": "set") — if a caller reported {{eta}} coming up empty, that entry would instead read "outcome": "empty" with the path that failed to match.