---
title: "Import agents from another platform"
description: "Bring agents, tools, and knowledge bases over from Vapi, Retell, ElevenLabs Agents, or Bland with an API key or a JSON export, review the mapping, and import."
---

If your agents live on Vapi, Retell, ElevenLabs Agents, or Bland, the
importer fetches them, maps every field onto ThunderPhone, and shows you the
result before anything is created.

<Note>
  Your API key is used only for the import. It is encrypted while the
  inventory is fetched and deleted as soon as the fetch completes — and on
  any failure or discard. Admin role is required to start or commit an
  import.
</Note>

## Start an import

1. Open **Agents** and choose **Import** (or **Import from Vapi, Retell,
   ElevenLabs, or Bland** on an empty agents page).
2. Pick the platform.
3. Follow the numbered steps in the dialog to create a key on that platform
   (they open the right settings page for you), paste it, or switch to
   **Paste exported JSON** and paste one or more agent objects from that
   platform's dashboard or API.
4. Choose **Fetch my agents**. Fetching and mapping usually takes under a
   minute; you can leave the page and come back through the task tray.

## Review the plan

Each agent shows the name, matched voice (with how confident the match is),
intelligence tier, the tools and knowledge bases it brings, and notes about
anything that changed in translation. Expand a row to read the prompt:

- **Rewritten** — one coherent prompt in the style of the
  [prompting guide](/guides/prompting), with every phone number, URL, tool
  name, and placeholder from the source preserved.
- **Structured** — the source config laid out under headings, exactly as
  extracted. Used automatically when the rewrite cannot be verified, or when
  the rewrite came out much shorter than the source.

An agent imported from a flow shows **Shared instructions** instead of the
prompt, followed by its steps: each step's name, what it tells the agent to
do, and where it goes next. **Show as one prompt** shows the same agent as a
single prompt, which is what it runs wherever steps are not available.
Agents with handoffs list the agents they hand the caller to; if you untick
one of those, the review says that handoff will not be set up.

Every agent starts selected except empty ones and default starter agents
the platform created for you. Untick agents you do not want, edit names,
voices, tiers, or the prompt choice, then **Import**. Created agents open in
the builder with their API connections and knowledge attached.

## Flows, Squads and agent transfers

Multi-step agents keep their structure. See [Agent steps](/guides/agent-steps)
for how steps and handoffs run on a call.

- **Flows become steps.** Retell multi-prompt states and conversation flows,
  Bland pathways and ElevenLabs workflows import as the agent's steps. The
  source's global prompt becomes the shared instructions.
  - Each node's instructions, fixed line, values to collect and tools carry
    over.
  - Edge conditions written in words become transitions the agent decides.
    A single comparison on a collected value or a webhook response
    (`age >= 18`) becomes a transition that is checked exactly.
  - Webhook and function nodes run their tool as the step starts. Global
    nodes can be reached from any step; one with no ways forward of its own
    hands the call back to the step it interrupted.
  - Transfer and end nodes become last steps that transfer or end the call.
    A Retell transfer node keeps its way out for when the transfer does not
    go through.
  - A branch node that only picks the next step is merged into the step
    before it when it can be. Otherwise it stays a step of its own, with a
    note.
  - A flow that is too large for steps, or that ThunderPhone cannot represent
    as steps, is imported as one prompt that lists every step, with a note.
- **Squads, agent transfers and agent swaps become handoffs.** Each member
  of a Vapi Squad is imported as its own agent, named after the member and the
  Squad. The first member answers the Squad's calls and the others are reached
  by handoff. ElevenLabs transfers to another agent and Retell agent swaps
  become handoffs too. The caller stays on the line and the conversation so far
  carries over.
  - A call reached by handoff keeps the call settings of the agent that
    answered it: voicemail, call limits, languages and recording. The agent
    it hands off to brings its own prompt, steps, tools and voice.
  - A handoff can only point at an agent imported in the same run. If the
    other agent is not in the import, or you untick it, the note says so and
    you can add the handoff later in the agent's settings.

## What is imported

<Tabs>
  <Tab title="Vapi">
    **Getting a key**

    1. Open [dashboard.vapi.ai/org/api-keys](https://dashboard.vapi.ai/org/api-keys)
       (Organization settings → API Keys).
    2. Create a key and choose **Private** — public keys cannot list
       assistants.
    3. Copy it into the dialog. Vapi keys are not scoped; delete the key in
       Vapi after the import if you created it only for this.

    | Vapi field | ThunderPhone |
    |---|---|
    | `model.messages[system]` | Prompt |
    | `firstMessage`, `firstMessageMode` | Opening line in the prompt; who speaks first |
    | `voice.provider` + `voiceId` | Closest catalog voice, with best-effort Vapi library lookup (match confidence shown) |
    | `transcriber.language`, `languages`, keywords/keyterms | Languages and speech-recognition vocabulary |
    | `model.model` | Intelligence tier |
    | `model.tools`, `toolIds`, `toolRefs` (function, apiRequest) | API connections; Vapi request envelopes and assistant-level server fallbacks are preserved |
    | `transferCall` destinations | Phone transfers in the prompt; SIP, assistant, and dynamic destinations are reported for review |
    | `handoff` tools | Handoffs to the named assistants imported in the same run |
    | `endCall`, `dtmf` | Built-ins |
    | Google Calendar, Google Sheets, Slack, `sms` | Reported with the ThunderPhone integration or SMS setup needed |
    | `query` and `knowledgeBase` tools, plus legacy `knowledgeBaseId` | Knowledge base with accessible uploaded files as documents |
    | `endCallMessage`, `endCallPhrases`, `voicemailMessage`, idle-message plans and timeout hooks | Prompt sections; voicemail and silence settings |
    | `maxDurationSeconds`, recording opt-outs | Maximum call length (Vapi's 600-second default is kept); a recording opt-out is reported on the review page |
    | Squads | One agent per member, with its own prompt, overrides, voice, tools, and knowledge. `assistantDestinations` become handoffs between them; the first member keeps the Squad's numbers |
    | Custom knowledge/model servers, compliance plans, other hooks, workflows and unsupported hosted tools | Reported with a specific review or rebuild action; raw plans and credentials are not stored |
  </Tab>
  <Tab title="Retell">
    **Getting a key**

    1. Open [dashboard.retellai.com/apiKeys](https://dashboard.retellai.com/apiKeys)
       (System settings → API Keys) and choose **Create key**.
    2. Turn on **Restrict permissions** and set **Agent**, **Knowledge base**,
       and **Phone** to **Read**. Leave every other group unchecked; the
       importer never writes to Retell.
    3. Copy the key into the dialog.

    | Retell field | ThunderPhone |
    |---|---|
    | Latest published agent + its exact Retell LLM / flow version | Published prompt and behavior; newer drafts are reported for review |
    | Retell LLM `general_prompt`, `begin_message`, `start_speaker`, states | Shared instructions; opening behavior; one step per state, with its tools and transitions and the values each transition collected |
    | Conversation flow `global_prompt`, nodes, components, global nodes, and edges | Shared instructions and steps; equation conditions on collected values are checked exactly; exact opening text and transfer steps |
    | `agent_swap` tools and nodes | Handoffs to the Retell agents imported in the same run |
    | Custom tools | API connections with query parameters, timeout, and Retell/args-only request shape; a signature change and any non-default speech, retry, response-variable, or form-encoding setting are reported |
    | `transfer_call`, `end_call`, `press_digit` | Conditional transfers (including extensions) + built-ins; inferred and warm-transfer differences are reported |
    | `check_availability_cal`, `book_appointment_cal` | Reported as Cal.com tools to reconnect under Integrations; Retell credentials never carry over |
    | `send_sms`, MCP | Reported with SMS or MCP setup instructions |
    | `voice_id` (`11labs-`, `openai-`, `cartesia-`, …) | Closest catalog voice |
    | `language` (one locale, multilingual mode, or a locale list) | Primary and additional languages |
    | `model` / `s2s_model` | Intelligence tier |
    | `knowledge_base_ids` (url, document, text sources) | Knowledge base with documents |
    | `default_dynamic_variables`, supported system variables | ThunderPhone variable defaults and plain call-context instructions |
    | `voicemail_option`, `end_call_after_silence_ms`, `max_call_duration_ms`, `ring_duration_ms`, recording disabled, `boosted_keywords` | Voicemail behavior; call limits; recording setting; prompt terms |
    | `webhook_url`, custom-LLM engines, unsupported flow nodes and vendor-only settings | Reported for manual review, not silently dropped |
  </Tab>
  <Tab title="ElevenLabs Agents">
    **Getting a key**

    1. Open [elevenlabs.io/app/settings/api-keys](https://elevenlabs.io/app/settings/api-keys)
       and choose **Create API key**.
    2. Under permissions, give it **Agents Platform: Read**
       (and **Knowledge base: Read** if shown); the importer needs nothing
       else.
    3. Copy the key into the dialog.

    | ElevenLabs field | ThunderPhone |
    |---|---|
    | `conversation_config.agent.prompt.prompt`, Agent Workflow nodes and ordered branch conditions | Shared instructions and one step per workflow node; tool nodes run their tool as the step starts; expression branches are labelled for review |
    | `first_message`, `language`, `language_presets` | Opening line; primary and additional languages; translated openings |
    | `prompt.llm` | Intelligence tier |
    | `tts.voice_id` | Closest catalog voice |
    | webhook `tool_ids`, including tools attached to workflow steps | API connections with portable body/query parameters; fixed vendor parameters and credentials are removed and reported |
    | `built_in_tools` for end call, phone transfer, keypad, and voicemail | Built-ins, transfer rules, and voicemail behavior; SIP and dynamic destinations are reported for rebuilding |
    | Transfers to another agent (`transfer_to_agent`, agent workflow nodes) | Handoffs to the ElevenLabs agents imported in the same run |
    | `knowledge_base` url/text/file/folder entries, including workflow-step knowledge | Knowledge base documents; folders are expanded and text/file content is fetched by id |
    | `turn.silence_end_call_timeout`, `conversation.max_duration_seconds`, `asr.keywords`, `privacy.record_voice` | Silence and maximum-duration limits; pronunciation terms; recording turned off is reported on the review page |
    | custom LLMs, MCP servers, procedures, workspace webhooks, per-step model/voice/language overrides, ElevenLabs booking tools | Reported with the action needed after import |
  </Tab>
  <Tab title="Bland">
    **Getting a key**

    1. Open [app.bland.ai/dashboard/settings](https://app.bland.ai/dashboard/settings).
    2. Copy the **API key** shown there (Bland has one key per account; it is
       not scoped, so rotate it afterwards if you prefer).
    3. Paste it into the dialog.

    Bland display labels are not treated as the agent's identity. The importer
    derives who the agent says it is from the greeting and prompt; for a
    pathway it uses the global prompt and start node. If that check is
    unavailable or finds no name, the imported prompt stays neutral.

    | Bland field | ThunderPhone |
    |---|---|
    | Web agent `prompt`, `first_sentence`, `language`, `model`, `voice`, `pathway_id` | Prompt; opening line; language; tier; closest voice; attached published pathway flow |
    | Persona production version | Personality and orchestration prompts; voice; language; caller-first setting; recording; maximum duration; default tools and knowledge. A single attached pathway is included; multiple-pathway routing is reported for manual setup |
    | Custom and pathway tools (url, method, schema, headers, body variables) | API connections. Bland Secret references are reported and must be added again |
    | Cal.com, Slack, HubSpot, Salesforce, Google Calendar, and Google Sheets tools | Matching ThunderPhone integration is named for you to connect and enable |
    | Inbound number detail (`prompt`, `pathway_id` / version, tools, transfers, keywords, request data) | One agent per inbound number, with call-variable defaults and transfer rules |
    | Every pathway, attached to a number or not | Published version when available; an unpublished draft is clearly flagged |
    | Global prompt; Default, Knowledge Base, Transfer Call, End Call, Webhook, and Wait for Response nodes; edges, loop conditions, global nodes, extracted variables, static speech | Shared instructions and one step per node, including any-time steps, values to collect, exact speech, webhook steps, transfers, and hang-ups. Webhook response pathways on a response field or extracted variable are checked exactly |
    | Inline knowledge text and resolvable knowledge ids | Knowledge documents. Items whose text or file cannot be read are reported for manual upload |
    | `max_duration`, `wait_for_greeting`, recording setting | Call limit, speaking order, recording setting |
    | `webhook`, dynamic-data lookups, multi-path persona routing, unsupported node settings, v2 agents | Reported with the manual follow-up needed |
    | Inbound numbers | Listed with both options, since Bland does not say whether it or your Twilio account owns them |
  </Tab>
</Tabs>

## What needs a step on ThunderPhone

The report at the bottom of the review page lists numbers, webhooks, and
tools that did not move; each agent's notes cover the rest. Together they
show everything that did not move and why:

- **Phone numbers.** After the import, each source number shows where it
  lives and what you can do with it:
  - **In your own Twilio or Telnyx account** (for example a Twilio number you
    connected to Vapi or ElevenLabs): an admin can move it to an imported
    agent. If no [VoIP connection](/guides/bring-your-own-numbers) holds that
    account yet, connect it first. Before anything changes, a confirm step
    says that calls to the number will stop going to the old platform.
    ThunderPhone then points the number at itself in your carrier account (a
    Twilio number joins ThunderPhone's SIP trunk; a Telnyx number moves to
    ThunderPhone's SIP connection) and places a short test call to switch it
    on. To undo it, delete the number on **Phone numbers**, keeping it in your
    carrier account, then re-import it on the old platform.
  - **On your SIP trunk**: connect the trunk as a
    [SIP connection](/guides/voip-providers#manual-sip-configuration) and
    import the number on **Phone numbers**.
  - **Sold by the platform** (Vapi, Retell and Bland numbers bought there):
    ThunderPhone cannot move it. Port it to a carrier and import it, or get a
    ThunderPhone number and attach it to the imported agent.
  - Bland does not say whether a number is its own or from your Twilio
    account, so Bland numbers show both options.
- **Per-agent webhooks.** ThunderPhone delivers signed webhooks per
  organization; set one up under [Webhooks](/webhooks/overview).
- **Vendor-stored credentials.** Tool headers that were visible are copied.
  Credentials the old platform stored by id are flagged; add them to the API
  connection's headers.
- **Built-in integrations.** Calendar, CRM, and messaging tools the old
  platform hosted (for example Cal.com booking) are named with the
  ThunderPhone integration to connect instead; their credentials do not
  carry over. The review also flags a prompt that still tells the agent to
  use a tool that was not imported.
- **Text messages.** ThunderPhone agents text through your own carrier
  connection; set up SMS in the agent's settings.
- **Tools without an equivalent** (platform-specific automations) are listed
  so nothing is dropped silently.
- **Call variables.** `{{name}}` placeholders are kept, with the defaults
  your platform had. ThunderPhone fills them from the
  [variables passed when a call starts](/guides/call-variables) and leaves
  them blank otherwise; the review lists the ones you need to pass.
- **Call limits and recording.** The maximum call length is imported. When
  the source agent never changed it, the platform's own default is set: 10
  minutes for Vapi and ElevenLabs, 1 hour for Retell, 30 minutes for Bland. A
  source value that is not a positive number imports with no maximum, and the
  review says so. Silence and maximum-duration limits outside ThunderPhone's
  ranges are adjusted, and the review note names the source value and the
  imported one. When the source agent had call recording turned off, the
  agent's review note says whether it is imported with recording off or,
  where turning recording off is not yet available, with recording on.

## What changes when you import

A few settings your old platform left at its own default take ThunderPhone's
default instead. The review lists them in one note per agent, under
**Show details**, only where the two platforms differ. The ThunderPhone
figures below are its defaults, which you can change per agent:

| Setting | Old platform default | ThunderPhone default |
|---|---|---|
| Ring time on outbound calls | Retell: 30 seconds | 60 seconds |
| Ending a silent call | Retell: hang up after 10 minutes; ElevenLabs: never | Check in every 15 seconds, hang up after 1 minute of silence |
| Call recording | Bland inbound numbers and personas: off | On. Contact support, or change it in the agent's settings where available |
| At a voicemail | Bland personas: hang up | The agent decides from its prompt |

A setting you changed on the old platform is imported as you set it, not
listed here. The one exception is a silent-call setting of "never hang up":
it is listed like a default, and the agent keeps ThunderPhone's check-ins.
Change any of these in the agent's settings after import.

## Importing without a key

Choose **Paste exported JSON** and paste the object(s) your platform's API
or dashboard exports, as one object or a JSON list:

- **Vapi** — an assistant object (`GET /assistant/{id}`), a Squad object
  (`GET /squad/{id}`), or a list of either. Tools attached only by id and
  knowledge files need a key to resolve. Vapi retired Workflows, so convert a
  Workflow to a Squad before pasting it.
- **Retell** — the agent object (`GET /get-agent/{id}?version=...`) **together
  with** its same-version Retell LLM (`GET /get-retell-llm/{id}?version=...`)
  or conversation flow object in the same list. The importer links by id and
  version, prefers a pasted published agent when publication status is present,
  and imports a standalone LLM or flow under a generated name.
- **ElevenLabs** — the agent object (`GET /v1/convai/agents/{id}`). Current
  exports usually reference webhook tools and knowledge documents only by id.
  A paste reports those items as unresolved; use an API key for a complete import.
- **Bland** — a web agent, the `/v1/agents` response, or a pathway object.
  Each pasted object imports as its own agent, even when two share an id;
  tool and knowledge ids that need API access are listed for manual setup
  instead of being dropped.

Anything referenced only by id and not present in the paste is listed in the
notes.

## After the import

1. Open each agent and read its notes.
2. Place a test call from the builder.
3. Move your numbers over, or attach a new one (see **Phone numbers** above).
4. Test each API connection with the request tester.
5. Check that knowledge documents finished indexing.
6. Set an organization webhook if the old agents used one.

The importer is also available over the [REST API](/api-reference/agent-imports).
