Switching AI Voice Platforms: What Transfers - Zian AI

Switching AI Voice Platforms: What Transfers

Every object that matters exports from both Vapi and Retell AI: agent config, prompt, tools, knowledge base, phone number, transcripts, recordings, test cases. What differs is request count: pulling 40,000 calls with transcripts costs about 410 API requests on Vapi and about 40,057 on Retell, for a reason Retell documents, or one bulk CSV export. All endpoints read 10 September 2026.

This page is a portability matrix, not a verdict. Each cell answers exactly one question — is there a documented API that gets this object out — and every cell links the vendor’s own API reference. Where we could not find an endpoint, the cell says which document index we searched and on what date, because “we could not locate it” and “it does not exist” are different sentences and only one of them is honest.

What actually transfers when I move my voice agent to another platform?

All nine object types have a documented route out of both platforms. The work is not extraction; it is that the objects are shaped differently on each side, so a field-for-field copy is never the job.

Object Vapi — documented endpoint (read 10 Sep 2026) Retell AI — documented endpoint (OpenAPI spec revision 2026-09-09-6f4e37c, read 10 Sep 2026)
Agent / assistant config GET https://api.vapi.ai/assistant/{id} returns one self-contained object: transcriber, model, voice, name, artifactPlan, compliancePlan, server. GET https://api.retellai.com/get-agent/{agent_id} returns the agent plus a response_engine pointer of type retell-llm, custom-llm or conversation-flow. POST /v2/list-agents returns metadata only: agent_id, agent_name, channel, user_modified_timestamp, tags.
System prompt / conversation logic Inside the assistant object, at model.messages — the reference describes it as “This is the starting state for the conversation.” A separate object. GET /get-retell-llm/{llm_id} returns general_prompt (“General prompt appended to system prompt no matter what state the agent is in”), states, begin_message and knowledge_base_ids. Flow agents use GET /get-conversation-flow instead.
Tool and function definitions GET https://api.vapi.ai/tool returns function name, description, parameters as JSON Schema, plus server URL, auth, timeout and backoff config. Tool types include apiRequest, function, dtmf, endCall. general_tools, on the same Retell LLM object as the prompt: “A list of tools the model may call (to get external knowledge, call API, etc).” No separate tool-collection endpoint appears in the API reference index at docs.retellai.com/llms.txt, checked 10 Sep 2026.
Knowledge base GET https://api.vapi.ai/v2/knowledge-base (id, name, description) and GET /v2/knowledge-base/{id}/file (fileName, mimetype, bytes, status). The original bytes come from GET https://api.vapi.ai/file, whose url is “The URL used to access the uploaded file” and whose parsedTextUrl is “The URL used to access text extracted from the file”. GET /get-knowledge-base/{knowledge_base_id} returns sources carrying file_url (“URL of the document stored”), content_url (“URL of the text content stored”) or url for scraped pages. Enumerate with GET /list-knowledge-bases.
Phone number GET https://api.vapi.ai/phone-number returns number, assistantId, fallbackDestination, status and a provider of byo-phone-number, twilio, vonage, telnyx or vapi. GET /v2/list-phone-numbers returns phone_number in E.164, a phone_number_type of retell-twilio, retell-telnyx or custom, plus sip_outbound_trunk_config, fallback_number and inbound and outbound agent bindings.
Transcripts Returned in the list response. GET https://api.vapi.ai/call includes artifact, which carries transcript (“derived from artifact.messages but provided for convenience”) and the full messages array. Not in the list response. The note on POST /v3/list-calls states: “To keep responses lean, the v3 payload omits transcript, transcript_object, transcript_with_tool_calls, and recording_url.” They come from GET /v2/get-call/{call_id} one call at a time, or in bulk from the dashboard CSV export described below.
Call recordings artifact.presignedMonoUrl and presignedStereoUrl download without authentication and expire at presignedUrlsExpiresAt; after that the reference directs you to the stable authenticated route GET /call/{id}/mono-recording. The older recordingUrl and stereoRecordingUrl fields are marked deprecated. Packet captures and call logs have their own download routes. recording_url on GET /v2/get-call/{call_id}, alongside transcript_object, call_analysis and public_log_url. Expiry is conditional and stated on that same page, under opt_in_signed_url: “When enabled, the generated URLs will include security signatures that restrict access and automatically expire after 24 hours.” Read 10 Sep 2026.
Eval and test suites GET https://api.vapi.ai/eval returns name, description and the messages that form the mock conversation. Simulation suites list at GET https://api.vapi.ai/eval/simulation/suite with simulationIds and targetAssignments. GET /v2/list-test-case-definitions returns name, user_prompt, metrics, tool_mocks, dynamic_variables and llm_model. Runs list at /list-test-runs and /list-batch-tests.
Analytics history POST https://api.vapi.ai/analytics, over the call and subscription tables, with sum, avg, count, min, max and history operations. It returns aggregates, not rows; rows come from the calls endpoint. GET /v2/list-export-requests returns export records with export_request_id, a channel of call or chat, status and url. That page leaves url undescribed, but the session-history guide does describe it: “Export-only fields include transcript data and PII-scrubbed transcripts”, call exports “can also include recording and public log URLs”, and “Completed export records are kept for one week.” No aggregate-analytics query endpoint appears in the API reference index at docs.retellai.com/llms.txt, checked 10 Sep 2026; the analytics dashboard is documented as a dashboard feature.

The quotable version: nothing on this list is trapped, but nothing on this list is symmetrical either — the prompt is portable text, and the tool contract wrapped around it is not.

One footnote worth carrying into your own testing. On 10 September 2026, Retell’s list-calls page linked the per-call fetch as GET /v1/get-call/{call_id} in its prose note, while the OpenAPI block on the get-call page itself specified get /v2/get-call/{call_id} under spec revision 2026-09-09-6f4e37c. The same note lists recording_url among the fields the v3 payload omits, while the v3 response schema in that page’s own OpenAPI block (V3CallBase) defines recording_url, call_analysis and public_log_url. transcript really is absent from that schema, and it is the transcript the arithmetic below turns on. When a reference and its own spec disagree, believe the spec and confirm with a single request against your own key before you write the loop.

Why does exporting my call history take so long?

Because of where the transcript lives, and nowhere else. Here is the arithmetic end to end for a mid-sized estate. Substitute your own numbers; the shape does not change.

Inputs: 12 agents, 3 knowledge bases, 1 phone number, 40,000 calls in the export window, and you want the transcript and a recording URL for every call.

Step Vapi requests Retell requests
Enumerate agents 1 (GET /assistant, full config returned) 1 (POST /v2/list-agents, metadata only)
Fetch each agent 0 — already in the list 12 (GET /get-agent/{agent_id})
Fetch each prompt or flow 0 — at model.messages on the assistant 1 (GET /v2/list-retell-llms returns the same full object as get-retell-llm, general_prompt included; flow agents add one GET /v2/list-conversation-flows)
Tools 1 (GET /tool) 0 — inside the object above
Knowledge bases and their files 5 (1 + 3 + GET /file) — the v2 list returns id, name and description only 1 — GET /list-knowledge-bases returns each base with its knowledge_base_sources inline
Phone numbers 1 1
Test and eval definitions 2 1
Enumerate calls 400 pages at the documented default of 100 per page 40 pages at the documented maximum of 1,000 per page
Fetch the transcript for each call 0 — artifact ships with the page 40,000 (GET /v2/get-call/{call_id}), or one CSV export — see below
Total HTTP requests 410 40,057

At ten requests per second — our assumption for the sake of the sum, not a published vendor figure — that is 41 seconds against about 67 minutes. Neither vendor publishes a numeric HTTP request limit we could locate. docs.vapi.ai/llms.txt indexes no rate-limit page at all; the limits page Retell does index, Understand concurrency & limits, sets out simultaneous calls and calls per second rather than API requests, and the OpenAPI spec defines a 429 response reading “Account rate limited, please throttle your requests” without attaching a figure to it. All checked 10 September 2026, so measure your own ceiling before you plan the window rather than trusting ours.

Three honest qualifications. The audio bytes are the same download on both platforms and are not counted above — 40,000 recordings is 40,000 file fetches whichever way you came. Vapi’s list-calls reference documents a default page size of 100 with no maximum stated on that page, and no cursor or offset parameter: pagination is done by walking the createdAtLt window. A larger page size would cut the 400, but it would not touch the 40,000, which is where the difference actually sits.

And the 40,057 is the cost of the API route only. Retell documents a second, bulk route that the arithmetic above deliberately does not use: a CSV export over the filtered call history in the dashboard, whose “Export-only fields include transcript data and PII-scrubbed transcripts” and whose call exports “can also include recording and public log URLs”. It is started from the dashboard rather than by a documented create endpoint, the API side of it is GET /v2/list-export-requests, and “Completed export records are kept for one week.” If you are moving tens of thousands of calls off Retell, start there rather than with the loop. Vapi’s documentation index lists no equivalent bulk export, which is the mirror image of the same trade-off: the artifact ships with every list page, so there is nothing to batch.

The quotable version: the cost of an export is not the size of your data, it is whether the transcript rides along with the list or has to be fetched one call at a time.

The Last-Number Rule: move the phone number last, and move it once

This is the decision rule we would give anyone doing this, and it is the one part of a platform switch that is genuinely hard to undo, so it belongs at the end of the sequence rather than the start.

The Last-Number Rule: stand the new platform up on a number you already control, run real traffic through it, and only re-point the trunk once the new agent has passed. The PSTN number moves last, and it moves once.

Both platforms document accepting a number you already own, which is what makes the rule possible:

  • Vapi documents a bring-your-own SIP trunk flow at docs.vapi.ai/advanced/sip/sip-trunk: create a credential with "provider": "byo-sip-trunk" holding your gateway address and auth, then a phone number with "provider": "byo-phone-number" pointing at it. The reference describes it as allowing “integration with any SIP provider”, and the byo-phone-number value also appears in the phone-numbers list schema.
  • Retell documents POST /import-phone-number, taking phone_number in E.164, termination_uri (“The termination uri to uniquely identify your elastic SIP trunk”), and optional sip_trunk_auth_username, sip_trunk_auth_password and transport. Its custom telephony guide names Twilio, Telnyx and Vonage as documented import paths and calls elastic SIP trunking “The recommended option if your telephony provider supports elastic SIP trunking.”

Because the number stays on your trunk in both cases, rollback is a routing change you make yourself, in minutes. That is the whole point of the rule.

The threshold that decides whether the rule costs you anything: if your number is already a byo-phone-number or a custom-type import, following this rule is free. If it is a platform-issued number — Vapi’s vapi provider, or Retell’s retell-twilio and retell-telnyx types — then you have a port in front of you, and a port is a regulated carrier process rather than a platform feature. In the United States, 47 CFR 52.35(a) requires that “All telecommunications carriers required by the Commission to port telephone numbers must complete a simple wireline-to-wireline or simple intermodal port request within one business day unless a longer period is requested by the new provider or by the customer.” That one business day is the outer limit the rule sets for a simple port, not a floor and not a promise about a complex one: 47 CFR 52.35(d) gives non-simple ports four business days on the same “unless a longer period is requested” terms. The rule also defines the working day it means, excluding “the current service provider’s company-defined holidays”.

How long does a voice platform migration take, stage by stage?

We are not going to publish invented durations for the stages we cannot source. Below, the clock is stated only where something actually sets it: our own request arithmetic, or a published rule.

Stage What you are doing What sets the clock
1. Inventory Run the matrix rows above against your own account and diff the result against what you thought you had. Bounded by the request counts above. The slip is agents nobody documented and a webhook whose owner left.
2. Re-author the config Prompts move as text. Tool schemas, webhook contracts and dynamic variables have to be rebuilt against the new shape. Unbounded and specific to you. This is an engineering job, not an export — the API gets the object out, it does not make the two shapes agree.
3. Export the call history — usually the longest technical stage Pull transcripts, recordings and analysis for the retention window you actually need. 410 requests versus 40,057 for 40,000 calls over the API, on the arithmetic above — or one CSV export on Retell. Slips when a run dies mid-way with no resumable cursor, or when presigned URLs expire before the downloader reaches them.
4. Parallel run on a number you control Both platforms live. Real traffic on the new one over your own trunk. You set this, and you should set it by call volume rather than by calendar. Nothing technical is blocking; you are waiting for enough calls to judge.
5. Cutover Re-point the trunk. Minutes — if you did stage 4. This is the stage that is short precisely because the previous one was long.
6. Port the number, only if you must Applies only to platform-issued numbers. One business day at most for a simple port under 47 CFR 52.35(a), four for a non-simple port under 52.35(d), and longer if the new provider or the customer requests it.

What running this migration actually costs you

The method above is complete. Someone competent can follow it with a shell script, a token and a weekend, and nothing on this page is withheld to make you call anyone. What it costs is worth stating plainly, because the arithmetic is the argument.

A one-off export of a few thousand calls is a script. An export of tens of thousands is a small piece of infrastructure: retries with backoff, a resumable cursor, a place to put the audio, and someone watching it. Our threshold: below roughly 5,000 calls of history, do it by hand and accept that a failed run just gets re-run. Above roughly 25,000, build the resume path first — a run that dies at request 31,000 and cannot resume is a run you do twice. The re-authoring in stage 2 is the cost people underestimate by the widest margin, because it is the only stage no API can shorten.

Some of that cost is structural rather than accidental. Where the agent config, the transcripts and the analytics all live inside one vendor’s account, an export is the only way to get at them. Zian AI is built the other way around for exactly this reason: alongside API and CRM integrations for HubSpot, Salesforce, HighLevel and Zapier, it supports private model deployment on your own infrastructure, which changes what the last row of the matrix even means — analytics history sitting on your own systems is not something you export from anybody. If you are earlier than that and still choosing, the honest reading of the same question is in build versus buy for AI agents.

Two related pages carry the choosing half of this decision rather than the moving half: how Zian AI and Vapi compare for outbound calling and the Zian AI and Retell AI outbound comparison. If where the data physically sits is the thing driving your move, AI voice agent data residency is the page for that.

Why Zian is not a column in the matrix above: every cell in that table cites a public API reference, and Zian is in partnership-application beta with no self-serve signup and no free trial, so there is no public reference for us to cite. We are not going to put ourselves in a table we cannot source. When there is one, this page gets a third column.

Frequently asked questions

Does my system prompt transfer between voice AI platforms?

The text does. On Vapi the prompt sits inside the assistant object at model.messages, returned by GET https://api.vapi.ai/assistant/{id}. On Retell it sits in a separate object reached with GET /get-retell-llm/{llm_id}, which returns general_prompt, states and begin_message. Both are plain text you can move in an afternoon. What does not move cleanly is the tool contract the prompt assumes, because the function schemas and webhook shapes are defined differently on each platform.

Do I have to port my phone number to switch voice AI platforms?

Not if the number sits on a SIP trunk you control. Vapi documents a phone number provider value of byo-phone-number backed by a byo-sip-trunk credential, and Retell documents POST /import-phone-number taking a termination_uri for your elastic SIP trunk. If the number was issued by the platform itself, you do have to port it, and porting is a regulated carrier process rather than a platform feature: 47 CFR 52.35(a) requires carriers to complete a simple wireline-to-wireline or simple intermodal port request within one business day unless a longer period is requested by the new provider or by the customer.

Can I export my call recordings from Vapi and Retell?

Yes, on both, and both were read on 10 September 2026. Vapi returns presigned download URLs on the call artifact, at presignedMonoUrl and presignedStereoUrl, which expire at presignedUrlsExpiresAt and are replaced by the stable authenticated route GET /call/{id}/mono-recording after that. Retell returns recording_url on GET /v2/get-call/{call_id}, and where the agent has opt_in_signed_url enabled that same reference says the generated URLs carry security signatures and automatically expire after 24 hours. Budget for the audio bytes as a separate job from the API calls, because the file downloads dominate the transfer either way.

Why does exporting 40000 calls take so many more requests on one platform than the other?

Because of where the transcript lives, and Retell documents the reason on the endpoint itself: to keep responses lean, the v3 payload omits transcript, transcript_object, transcript_with_tool_calls, and recording_url. So the list gives you identifiers and you fetch the content one call at a time. Vapi ships the artifact object inside the list response instead. On our arithmetic for 40,000 calls that is about 410 requests against about 40,057 over the API. Retell also documents a bulk CSV export over the filtered call history whose export-only fields include transcript data, which avoids the per-call loop entirely.

What could you not find a documented export endpoint for?

Two things, scoped to what we searched on 10 September 2026. We found no aggregate-analytics query endpoint in the Retell API reference index at docs.retellai.com/llms.txt, only a dashboard analytics view. And we found no numeric HTTP request rate limit published by either vendor on either documentation index. One thing we did find after looking wider: the reference page for GET /v2/list-export-requests leaves the url field undescribed, but the Retell session-history guide says the export can carry transcript data and PII-scrubbed transcripts and that completed export records are kept for one week. Neither absence above is a statement that a thing does not exist, only that we did not find it where we looked.

Working out whether to move at all

The matrix answers what transfers. It does not answer whether the move is worth the stage-2 rebuild, and that is a question about where you want the agent config and the call history to live in three years, not about endpoints. If that is the conversation you are having, Zian AI is in partnership-application beta and takes partners by application rather than self-serve signup.

Apply For Partnership

Related Blogs

Related from Zian AI