Build and edit a flow
Build a flow by choosing the conversation steps, connecting their outcomes, and checking the path that each caller or browser user can take. Start with an existing app from Create your first application. This chapter covers authoring; Save, test and publish an application owns the draft, test and publication lifecycle.
Availability: Use an app in a team you can edit. Reading a flow, saving a draft and publishing it are separate permissions; resolve missing actions through team access and permissions. The optional AI builder has its own deployment availability, described in application creation. Manual editing does not establish that every node in the palette can run on every channel. Check the node execution paths before adding a step.
1. Establish the flow's starting context
Open the app's Flow Designer at /apps/{appId}/flows. Check the app, selected flow and version before editing. A diagram from version history is not proof that it is the version serving customer traffic.
Review these three things first:
- Entry points: which phone, browser voice or browser chat interaction should reach this flow? Configure them in Application entry points.
- Provider: what processes the conversation, transcription and speech? Review Choose a provider and channel, including credentials and node overrides.
- Initial step: where should execution start? A visible node that is not connected to the start or a reachable branch will not become part of the main conversation just because it is on the canvas.
The canvas combines executable conversation nodes with settings projections. Start, entry-point, default-provider, surface and capability objects describe configuration around the graph. They are not extra steps to insert into nodes.
2. Add and configure steps
Use Add node, choose a type and select the new node to edit it. New nodes receive a generated ID and are added to the definition; they still need the appropriate connections. The palette separates standard and advanced choices. Advanced is an editing category, not a permission grant or a guarantee of channel support.
For a normal agent conversation, keep the first graph small: a supported agent, its deliberate exit route and an End node. Add branching, webhooks or other actions only when the behavior requires them. The following is a design sketch, not importable FlowDefinition JSON:
Use the node reference for the meaning of each step and the output you must check. A successful request to advance the graph is not necessarily a successful external action.
| Selected area | What to edit or check |
|---|---|
| Conversation node | Instructions or input, provider override when offered, tools, node-specific settings and outgoing transitions. Fields differ by type. |
| Transition | Event, destination, optional condition and context updates. Read data and transitions before relying on ordering. |
| Entry point | Channel and addressing configuration; follow the dedicated entry-point task. |
| Flow settings / provider | Shared configuration rather than one step's prompt. Review the provider, language and applicable app/session settings. |
| Variables panel | Available variable names and their use sites. This is an authoring aid; it does not manufacture values missing at runtime. |
| Version history | Check stored status and choose restore/publish deliberately; the drawer is not a read-only comparison viewer. Use the version-history reference. |
Changing an ID or removing a step requires checking incoming transitions and the initial node. Moving a node visually does not reorder execution: transitions control that order. From 0.9.18, the editor fits a loaded graph without overwriting its saved node positions; automatic alignment can still apply after structural edits.
3. Make every intended outcome explicit
For each step, identify its event and what should happen next. Use a specific condition before a general fallback for the same event. Agent steps commonly leave through a named tool-call transition; they are not single-turn prompts that necessarily emit complete after every response.
Check both the normal path and the failure path. In particular, webhook and LLM-query runners can emit complete after recording an error. A branch that assumes every complete means business success can route incorrectly. Give every intended terminal branch an End node, and review validation messages for unreachable nodes, missing targets and circular-only paths.
A continuous transcription/interpretation pipeline uses specialized processing. Do not copy ordinary complete transitions onto its stream connections and expect one execution per transcript chunk. Its boundary is described in the node reference.
4. Edit or move a definition through Source view
Use the JSON exported by the editor as the starting point for source changes. The editor displays an authoring representation, produced from the runtime definition. It accepts recognized authoring/runtime input through normalization; these representations need not have the same field layout. In particular, do not wrap the export inside a made-up flow, providers or variables object.
- Copy or download the existing applied definition before a substantial edit. Treat it as configuration that may contain sensitive inline values; it is not a credentials-free backup.
- Open Source view and change the smallest relevant section. JSON syntax feedback checks parsing while you type.
- Apply parses and normalizes the input and replaces the editor's flow state. Resolve errors before proceeding. If the source
namechanges, Apply also requests an app rename immediately; it is not purely an unsaved local preview of the name. - Review the resulting canvas, entry points, providers and transitions. Run the normal save and validation process before testing.
- Copy or download again only after applying the intended text. When a flow is loaded, these controls export the applied flow state, not un-applied text remaining in the JSON editor.
Importing a JSON file normalizes it into the editor state. It does not by itself publish the flow, provision provider accounts or recreate all resources from another environment. Review environment-specific references and credentials before saving or publishing.
Parsing, normalization, semantic flow validation and a runtime test answer different questions. Validation checks include graph structure, tool resolution, selected provider/failover/routing rules and variable usage, but do not prove external services or all channel combinations work. For node-local tools, see Tools and result mappings.
5. Verify and recover
Follow Save, test and publish to save the intended draft and exercise it through the intended channel. Cover a normal conversation, an exit, a condition fallback and any external action you added. Then review the resulting conversation to compare node activity and available logs with your expected path. A test on a different channel does not validate a phone transfer or a browser-only action.
| Symptom | Check and recovery |
|---|---|
| New node never runs | Check the initial node, reachable incoming transitions and event/condition matching. Canvas position has no routing meaning. |
| Flow stops after a step | Inspect its emitted event and the ordered transitions. No matching transition completes the main engine; it need not produce a missing-edge exception. |
| Missing runner error | Compare the selected type with the runtime path in the node reference. Change to a supported design or ask the operator about the required service path. |
| Apply succeeds but saving fails | Read the save validation error; normalization is not the final semantic check. Repair the named field/tool/target rather than bypassing validation. |
| Imported flow runs against the wrong resources | Recheck app/team, entry points, provider references and environment-specific values before publication. |
| Edited JSON absent from download | Apply the text first, then export and inspect the result. |
| External action appears to finish but nothing changes | Inspect the action result/error and host capability. Graph completion alone does not confirm an effect. |
Keep a known working version available through version history. Do not assume re-importing a flow also reverses changes already made by a webhook, external action or app rename.
Flow settings reference
Change the flow's Settings
Open Settings for the application flow. These controls update the flow editor's draft definition. Changing Accept incoming calls, recording preferences, reporting visibility or QA settings here does not immediately update the application record. Save the draft to preserve the edit; publishing applies its application settings and synchronizes the published configuration. Reopen the saved version to check the stored values, then follow the publication procedure before testing a new conversation. This describes the flow editor, not every application edit form elsewhere in the product.
Availability: editing and publication follow the current team's flow permissions and publication policy. Accept incoming calls additionally requires the editor's administrator permission; a visible flow does not establish write permission. Use Access and teams when controls are disabled or the expected team is missing.
| App Settings control | What it changes and how to use it |
|---|---|
| Accept incoming calls | Sets the application's requested active state in this draft. The display falls back to the application's existing active state when no draft override is stored. |
| Recording artefacts | Chooses the conversation outputs. Use Choose recording outputs for output meanings, storage and access prerequisites. |
| Record every N calls | Sets the recording sampling frequency. See Choose recording outputs for its range and meaning. |
| Hide from reporting | Requests exclusion from report queries which filter out excluded applications. Default display is off. This does not delete conversations or make their records private. |
Set application QA scoring
Availability: the section is shown when the UI QA feature is enabled and the team has not disabled QA. Actual scoring also requires the worker's QA feature, an eligible subscription plan, team and application permission to score, transcript data and a usable scoring LLM configuration. An application override cannot grant a missing plan capability. Ask the team administrator about team settings and the platform operator about feature configuration when this section is absent.
| Control | Meaning |
|---|---|
| QA scoring — Inherit team/platform setting | Removes the application's explicit enable/disable, provider, model and prompt overrides. It does not force scoring on. |
| Disabled for this app | Stores application scoring disabled and clears its provider/model/prompt overrides. |
| Override for this app | Enables scoring at application level and exposes Scoring provider, Scoring model and Scoring prompt. Empty inputs inherit the corresponding downstream configuration. |
| Scoring provider / Scoring model | Select the scoring LLM identity and model, separate from the conversational provider. Worker resolution uses application, then team, then its resolved scoring credentials/configuration. |
| Scoring prompt | Instructions for the scorer. The worker uses application, team, platform default, then its built-in prompt. This is not the bot's conversation instruction. |
After publishing, inspect a newly completed eligible conversation's QA status and results. A skipped result needs eligibility/transcript checks before prompt tuning; publishing does not prove a scoring request succeeded.
Limit call duration
In the flow's Settings › App Settings › Call duration, Max call duration (seconds) bounds the lifetime of each call to this flow. Warning message is read aloud 10 seconds before the forced hangup. For example, 600 with "This call will end shortly." ends calls after ten minutes and speaks the warning at 9 minutes 50 seconds.
| Control | Range and behavior |
|---|---|
| Max call duration (seconds) | Whole seconds from 10 to 7200. Outside that range the form shows "Must be between 10 and 7200 seconds." Empty inherits the deployment default. |
| Warning message | Up to 100 characters. Empty uses the deployment's warning; the hangup is silent when neither sets one. |
Availability: from 0.9.18, an empty Max call duration (seconds) always inherits the deployment default, even when a warning or another session setting is configured. The deployment default is 7200 seconds unless your operator changes it. A flow value may be above or below the deployment value; the deployment value is a fallback, not a cap.
At the limit, the platform stops voice input where the provider supports it, plays the warning and ends the call without waiting for the announcement to finish. The conversation record shows the end reason max_call_duration. Save and publish the flow to apply a change to new calls; saving a draft does not update the live flow.
Flows saved before 0.9.18: earlier validation could save 5400
seconds when the duration was blank but another session setting was present.
Existing numeric values remain explicit overrides after upgrading. If such a flow
should inherit, clear its duration and save/publish it after the operator has
updated all services that save, synchronize and run flows. Leave intentional
limits in place; an existing 5400 alone does not show how it was set.
Verify on a new test call: confirm the effective duration in the timer-installation
log, then the warning timing and termination classified as max_call_duration.
With an inherited deployment limit of 120 seconds and a warning configured, the
expected warning is around 110 seconds and termination around 120 seconds. Existing
calls retain their installed timers. A text-only conversation does not verify this
telephony behavior.
Give up when the bot stays silent
The same Call duration block ends or transfers a call when the bot does not answer a request in time. The timer starts with each request to the bot and stops when the bot responds. It runs even when final runtime error actions are disabled.
| Control | Range and behavior |
|---|---|
| Bot no-input give-up (ms) | 1000–120000 in steps of 1000. Empty uses the deployment default, 15000 unless your operator changes it. |
| Give-up warning message | Up to 100 characters, read before the hangup or transfer. Empty uses the deployment's warning; with neither, the call ends silently. |
| Give-up audio URL | Played in full instead of the warning message. If it cannot be played, the warning message is read instead. Empty uses the deployment default. |
| Transfer instead of hangup | Reveals Transfer target and Egress route. The call is transferred instead of ended; a failed transfer ends the call. See Transfer a call. |
Availability: from 0.9.18. During a call, the bot can change only the give-up timeout, within the same range. The warning, audio URL and transfer stay as published.
A sets the bot response timeout. B sets the warning read before the give-up action.
A call that gives up ends with reason bot_no_input_give_up.
Customize the media connection warning
In the flow's Settings, find Media connection warning. Use this when callers need an application-specific message while the gateway waits for incoming audio to recover. This is separate from maximum call duration, speech recognition and a silent caller who is still sending RTP packets.
The Using platform default or Custom message chip shows the source of the warning. The displayed warning/disconnect timings are platform-owned and read-only here. To change those timings, ask the platform administrator to use Audio connection settings.
- Enter the warning text and its Message language together. Use nonempty text of at most 500 characters and a valid language tag, such as
en-USorde-DE. - Save the draft, then test and publish. Publishing applies these application settings to new calls across the application's flows; merely typing in the inspector does not update the live application.
- Reopen the saved settings and verify the intended source and values. To stop customizing, choose Reset to platform default, then save and publish that change. Reset clears both the message and its language; it does not copy the current platform text into a permanent custom override.
A custom warning replaces only the platform message/language pair. Calls retain their own settings snapshot once monitoring begins. The runtime prepares the announcement for the call language; a saved message is not evidence that synthesis, translation or caller playback succeeded. When audio does not recover, the call ends with reason no_media if no audio ever arrived, or media_connection_broken if audio stopped during the call. Use media diagnostics for a missing warning or unexpected disconnect.
Choose TTS caching
Expand Advanced TTS caching. Caching reuses generated speech; it does not select which conversation recordings are retained.
| TTS cache backend | Meaning |
|---|---|
| Inherit | Removes the flow backend override and uses the platform backend. |
| Off | Disables the selected cache path. |
| Shared media cache | Requests the shared media backend. Availability depends on the media-cache feature; a stored media selection can remain visible but disabled when that feature is off. Runtime platform disablement also prevents this backend from being used. |
| Local in-memory cache | Requests local caching and reveals Local retention seconds. The UI accepts positive whole seconds up to 315360000. Local cache is not durable shared storage. |
Switching away from Local removes the flow's local-retention override. Effective local retention falls back from flow seconds to enabled application retention hours converted to seconds, then platform retention. Platform maximum item/cache sizes still apply, and the session-level disableTtsCache setting can override the requested backend. Reopen the saved draft to check whether an override remains; runtime cache verification needs the selected deployment and audio path.
Set language defaults
Primary Language supplies the language used to normalize provider defaults. A missing primary language normalizes to en-US. Select an offered language option: although the control accepts typing, the control does not commit arbitrary free-text strings.
Allow language switching switches the stored mode between strict and flexible. Flexible mode exposes Allowed Languages, excluding the primary language from its choices. Turning switching off hides the list but retains its stored entries. These are flow-level preferences, not proof that every selected speech/LLM provider implements language detection or enforces an allowlist. The flow retains the mode and allowed-language preferences, but support for automatic switching depends on the selected provider. Check the selected provider's language controls and verify recognition and generated speech in the intended languages.
Add or remove the Shared Voice Flow
Add creates an initial voice-agent node and an End node when there is no non-End main-flow node. It selects and lays out the new voice node, supplies a basic instruction, and wires its hangup tool to End. It does not by itself provision a telephone number or browser voice endpoint. Continue with Application entry points to make the flow reachable.
Remove is a destructive draft rewrite, not a visibility toggle. It replaces the main graph with End, clears telephone entries and both browser voice and browser chat entries, removes action tools and the gateway profile, and removes realtime/STT parts of the inline default provider. It enables the browser surface and its actions channel, retains existing browser actions, and keeps only the context entries detected in those actions' input-text, continuation and transform-prompt templates (excluding the trigger context); it may derive a browser TTS default from the previous realtime configuration. The button's handler has no additional confirmation.
Before removing, preserve a recoverable saved version and inspect the source/graph. After removing, review the remaining actions, context, provider and entry points before saving or publishing. Do not use Remove merely to stop accepting calls; inspect the application's Accept incoming calls control under App availability or the relevant entry point instead. The Shared Voice Flow presence test includes non-End main nodes, so this control can be shown even when the graph is not exclusively a voice graph.
Related
- Flow node reference — to check what each node does and where it runs
- Connect data, events and transitions — to set up conditions, context and result mappings
- Save, test and publish an application — to publish the flow and verify the result
