Retell → ElevenLabs

Two export shapes, and how to tell them apart

Dispatch on response_engine.type. It is always present.

Do not dispatch on starting_state; it is frequently absent.

The two shapes need different work. A retell-llm source is usually one prompt plus tools, so an EL agent with a prompt and maybe procedures is the right target. A conversation-flow source has real states and usually wants an EL workflow.

Construct mapping

Retell ElevenLabs Notes
Agent Agent Same concept.
Conversation node override_agent node The editor calls it an Agent node; the wire type is override_agent.
Node instruction node additional_prompt Append, not replace. See the prompt-field trap in reference/traps.md.
Function node tool node referencing a webhook tool The target is a Tool node, not a bare tool.
Function node with speak_during_execution one override_agent node with forced_tool_name + additional_tool_ids The node speaks, and is forced to make the call. Cleaner than a say-node-then-tool-node pair. pre_tool_speech is an enum (auto/force/off), not filler text, so it cannot carry the line.
Node instruction as {static_text} or {prompt} say node message, a union of literal text or an LLM prompt A clean 1:1 — do not flatten a static line into a generated one.
Transfer call node phone_number node Give it an outgoing result edge.
Branch node edge conditions on the preceding node The branch node itself disappears.
else_edge the node's single unconditional edge At most one unconditional out-edge per node.
transition_condition type prompt LLM edge condition The common case.
transition_condition type equation expression edge condition Type-guard it — see reference/expressions.md.
End node end node The only genuinely terminal node type.
begin_message first_message Present on most retell-llm sources; absent from every conversation-flow source.
global_node_setting + its condition a Procedure with a trigger The trigger is the analogue of the node's condition. Read the reachability trap first.
extract_dynamic_variables node update_state node Not data collection — that is post-call and cannot feed routing.
Node-scoped knowledge_base_ids additional_knowledge_base on an override_agent node Must be override_agent; a say node accepts the write and ignores it.
Flow-level knowledge_base_ids the agent's knowledge base
skip_response_edge unconditional edge plus entry_behavior: "wait_for_user" on the target The edge alone only routes; it does not suppress speech.
Cold transfer blind transfer Unless it ran over SIP REFER — then sip_refer, which is also the only type accepting a SIP URI destination.
Warm transfer conference transfer The agent can address both parties.
Warm-transfer briefing message no equivalent — see gaps The field does not exist on either transfer surface.
agent_swap (cross-agent) standalone_agent node, or the transfer_to_agent system tool Plain edges only cover the within-agent case.
agent_swap keep_same_voice preserve_client_tts_overrides
Shared/library component standalone_agent node with a node_id entry, push/pop return Referenced by id, so one edit still propagates to every caller.
press_digit tool play_keypad_touch_tone system tool Also post_dial_digits for digits sent on connect.
send_sms tool native SMS channel, or a webhook tool See the SMS note below.
mcp node / tool native MCP server on the agent Do not re-author MCP tools as webhook tools.
data_storage_setting PrivacyConfig everything_except_pii maps to transcript/PII redaction. Retention is per agent. Set the two together — see the deletion-flag trap in reference/traps.md, because a deletion flag sent without a retention window is silently switched off.
data_storage_retention_days retention_days -1 means no limit, and it also disables the deletion flags.
ambient_sound / ambient_sound_volume conversation.background_sound Volume range is 0.01–1.0. Presets do not map 1:1 — see below.
voice_model holding an ElevenLabs model id the voice/TTS model directly Most sources that set this already name an EL model.
Batch testing the agent testing API Tests are first-class resources attached to the agent.

Retell constructs that are not what a mapping table might suggest

Where the real gaps are

Treat any "Retell has X and ElevenLabs does not" claim as wrong until you have searched and failed to find the feature. The overwhelming majority of them are, including several that circulate widely. Before telling a customer to build a workaround, look for the construct — a workaround they do not need is worse than an unanswered question. These are the ones that hold up:

These were commonly claimed as gaps and are not: DTMF, SMS, reusable components, node-scoped knowledge, guardrails, ASR keyword boosting, A/B testing, version pinning, human detection before bridging, whisper messages, MCP, mid-call variable capture, and QA scoring. Each has a real EL construct — see the mapping table above, or ask the relevant sibling skill.

go_back_conditions is on that list, and the reason is worth knowing, because it looks like the scariest thing about lowering a global node and it is not a gap at all. Retell needs those conditions because its global is a node — entering it means leaving the node you were on, so something has to decide when to come back. ElevenLabs has no equivalent need, in either direction:

So do not spend effort porting these, and do not tell a customer they lose the behaviour. What you should tell them is the reachability consequence in traps.md: the trigger is offered on every turn and the model chooses, so nothing guarantees your authored order. That is the real cost. Note also that the closest thing to scoping is per-conversation rather than per-node: the procedure set can be narrowed in conversation-initiation client data, where the workspace allows it.

Two more are narrower than usually stated rather than absent: hold music during a transfer exists but is not configurable, and automated QA scoring exists per conversation and per turn, with latency, interruption and hallucination scoring genuinely missing.

SMS

Retell's SMS is a tool. ElevenLabs has a native two-way SMS channel, so an SMS-first agent needs no external API — inbound SMS routing is on by default for an imported SMS-capable number. The one case that still needs a webhook tool is sending a single SMS from inside a voice call.

Sequencing a conversation-flow migration

  1. Identify the shape and read the graph. Count nodes by type before deciding anything.
  2. Handle credentials in every tool definition first (SKILL.md, step 2).
  3. Decide what to collapse — see the folding trap in reference/traps.md before committing to it, and expect a faithful conversion to be roughly node-count-neutral. Semantic merging of duplicate nodes is a later, test-backed pass.
  4. Create the agent shell directly, then port the base prompt and derive the first message.
  5. Create the tools and record the id each returns, keyed by the Retell tool_id — a workflow node references a tool by id, and two Retell tools can share a name. See step 4 in SKILL.md.
  6. Build nodes, then edges. Order only the conditional edges — unconditional ones are moved last for you.
  7. Convert each equation transition with a type guard; convert each numeric comparison only after the variable is guaranteed numeric. Compose the guards from reference/expressions.md — most of a real flow's equations need one, and an unguarded neq fires on absent data.
  8. Give every transfer node its failure edge.
  9. Run the mocked smoke test (SKILL.md step 5) before reporting anything as done, then route the remaining config and rollout to the sibling skills.