Use this page when you are building an app that creates and embeds Tavus CVI
conversations. If you only want to create a PAL and start your first
Tavus-hosted conversation, use API Conversation Quickstart.
- Keep
TAVUS_API_KEYon your server. - Create a conversation with
POST /v2/conversations. - Embed the returned
conversation_urlin an iframe. - End the conversation when the user leaves.
Live conversations can count toward billing and concurrency as soon as they are
created. Use
test_mode: true while wiring automated tests or checking your
integration flow. In test mode, Tavus creates the conversation without the
PAL joining and returns it with status: "ended".Prerequisites
- A Tavus API key from the PAL Maker.
- A usable
pal_id,face_id, or both. The next section shows how to choose. - Node.js 20+ for the TypeScript examples below.
Choose a PAL and Face
For CVI, a Face defines the on-screen likeness and voice. A PAL defines behavior, knowledge, and pipeline configuration (prompt, layers, objectives, guardrails, tools, and more). Use this decision tree:- If you have a PAL with a
default_face_id, create the conversation with justpal_id. - If you have a PAL without a
default_face_id, create the conversation with bothpal_idandface_id. - If you only want to test a Face and voice without a custom PAL, create the conversation with just
face_id.
pal_id and default_face_id. In the faces response, look for face_id, face_type, and model_name.
r90bbd427f71 is the stock Anna face ID used throughout these docs, and
pcb7a34da5fe is a stock Sales Development Rep PAL ID. They are stock
IDs, not placeholder strings, and are available for quickstart use.1. Create the app
Create a Vite React app and install the small server dependencies used in this guide:package.json:
2. Keep your API key server-only
Create.env.example:
.env locally and fill in your real key:
3. Add backend routes
Createserver.ts at the project root. The first route creates a conversation. The second route ends it when the user leaves or your test finishes.
4. Embed the conversation URL
Replacesrc/App.tsx with this frontend. It calls your backend, receives the Tavus conversation_url, and embeds it in an iframe. This quickstart uses an iframe because it is the fastest path to a working CVI app. For Tavus-provided React components, including the complete CVIProvider + Conversation + server-helper example, see the @tavus/cvi-ui component library. For Daily JS/React or LiveKit guidance, see Embed CVI.
http://localhost:5173, enter your pal_id, and click Start conversation.
The iframe must include browser permissions in the
allow attribute. At
minimum, include camera and microphone. fullscreen, display-capture,
and autoplay are recommended for the default Tavus/Daily in-call experience.Expected create response
POST /v2/conversations returns the join URL your app should embed:
test_mode is true, expect the same shape, but status is ended and the PAL does not join.
Cleanup
End live conversations when the user leaves, when a test completes, or when your app no longer needs the room:Errors and cleanup
For automated tests, scaffolding, and agent-generated validation, create conversations withtest_mode: true. the PAL does not join, the response returns status: "ended", and the conversation does not affect billing or concurrency.
For live conversations, call End Conversation when the user leaves or your app no longer needs the room. Use Delete Conversation only when you want destructive data removal, not routine call cleanup.
If conversation creation fails:
400usually means the request body is invalid. Check that you sent a validpal_id,face_id, or both, and that customizations are in the expected location.401means the Tavus API key is missing or invalid. KeepTAVUS_API_KEYon the server and never send it from browser code.- Quota or concurrency errors mean your app should stop creating live conversations, surface a retry/support path, and use
test_mode: truefor validation flows. - For private rooms, join with the returned
meeting_token. If a token is invalid or expired, create a new authenticated conversation instead of reusing the old token.
Where to go next
- Use the React component library when you want Tavus CVI components instead of a plain iframe.
- Use Embed CVI for iframe, vanilla JavaScript, and Daily JS patterns.
- Use customize the conversation UI for Daily Prebuilt styling.
- Use LiveKit Agent only if you already run a LiveKit Agents pipeline and want Tavus as the avatar video layer. It is not the recommended path for most CVI apps because LiveKit only provides rendering, while Tavus’s Full Pipeline includes perception, turn-taking, and rendering for complete conversational intelligence.
- Use conversation customizations for recording, language, participant limits, private rooms, backgrounds, captions, and timeouts.
- Point coding agents at Agents & automation for
llms.txt, OpenAPI, Agent Skills, and MCP access.

