#i have built a scalable ai voice agent with dynamic variables based on initial webhook. could i int
1 messages · Page 1 of 1 (latest)
Short answer: Yes. You can run your agent in chat-only mode and you can keep using dynamic variables.
What to use
- Your own chat UI (SDK): Start a session with the JavaScript SDK and set the conversation override textOnly: true to force chat-only (no audio I/O). (elevenlabs.io)
- ElevenLabs web widget: Enable Chat Mode in the Interface settings (or via SDK overrides) and embed the widget on your site. Note the widget requires a public agent (auth disabled) and you can allowlist domains. (elevenlabs.io)
Dynamic variables in chat-only
- Supported in chat-only exactly like voice. Provide them at runtime:
- SDK: pass dynamic_variables when starting the conversation. (elevenlabs.io)
- Web widget: set the dynamic-variables attribute with a JSON object. (elevenlabs.io)
- Public talk-to page: pass via URL (vars= base64 JSON or var_ prefixed params). (elevenlabs.io)
- Webhook/tools can create or update dynamic variables by returning JSON and mapping fields via Assignments. (elevenlabs.io, help.elevenlabs.io)
- Secret variables: prefix with secret__ to use them only in webhook tool headers (never sent to the LLM). (elevenlabs.io)
- Note: system variables like system__caller_id are voice-call only and won’t be present in chat mode. (elevenlabs.io)
References
- Chat Mode (text-only) guide. (elevenlabs.io)
- Widget customization (Chat Mode + dynamic-variables attribute + embedding requirements). (elevenlabs.io)
- Dynamic variables (system/secret vars, runtime passing, URL methods, tool updates). (elevenlabs.io)
- Tools and webhooks with
can you show me an example onm how to do this. i have build my own widget in next.js how to apply these dynamic vars properly based on like a secret key or public key for example?
Below is a minimal, docs-aligned way to wire a custom Next.js chat widget to an ElevenLabs Conversational AI agent in chat-only mode and pass dynamic variables (including secrets) safely.
- Configure your agent to use dynamic variables
- In your agent’s First message and/or System prompt, reference variables with double curly braces, for example: “Hi {{user_name}}”. Secret variables should be prefixed with secret__ and only used in webhook tool headers, not in prompts. (elevenlabs.io)
- Generate a signed URL on your server (never expose your XI API key in the browser)
- Add a Next.js API route that calls get_signed_url with your agent_id and returns the signed_url to the client.
Example: app/api/signed-url/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const agentId = process.env.ELEVEN_AGENT_ID!;
const res = await fetch(
`https://api.elevenlabs.io/v1/convai/conversation/get_signed_url?agent_id=${agentId}`,
{
method: 'GET',
headers: { 'xi-api-key': process.env.ELEVEN_API_KEY! },
}
);
if (!res.ok) {
return new NextResponse('Failed to get signed url', { status: 500 });
}
const body = await res.json(); // { signed_url: "wss://..." }
return NextResponse.json({ signedUrl: body.signed_url });
}
- Signed URLs are intended for client-side use and expire after 15 minutes; create a new one per session. (elevenlabs.io)
- Start a chat-only session from your Next.js widget and pass dynamic variables
- Use the React SDK’s useConversation hook. Enable chat-only mode via an override, and pass dynamicVariables (include non-sensitive fields like user_name and secret fields prefixed with secret__ for usage in webhook tool headers).
Example: a React component in your widget
'use client';
import { useCallback, useState } from 'react';
import { useConversation } from '@elevenlabs/react';
async function getSignedUrl(): Promise<string> {
const res = await fetch('/api/signed-url');
if (!res.ok) throw new Error('Failed to get signed url');
const data = await res.json();
return data.signedUrl;
}
export default function ChatOnlyWidget() {
const [userName, setUserName] = useState('Ada');
const [conversationId, setConversationId] = useState<string>('');
const conversation = useConversation({
// Handle agent text messages in chat mode
onMessage: (msg: any) => {
if (msg?.type === 'agent_response') {
console.log('Agent:', msg.text);
}
},
onError: (e) => console.error(e),
});
const start = useCallback(async () => {
const signedUrl = await getSignedUrl();
const convId = await conversation.startSession({
signedUrl,
// Force text-only/chat mode at runtime
overrides: { conversation: { textOnly: true } },
// Dynamic variables for this session
dynamicVariables: {
user_name: userName,
// secret dynamic vars are never sent to the LLM;
// use them in webhook tool headers only
'secret__crm_token': 'example-session-token',
},
});
setConversationId(convId);
}, [conversation, userName]);
const send = useCallback(async (text: string) => {
await conversation.sendUserMessage({ text });
}, [conversation]);
return null;
}
- Chat mode can be enabled when creating the agent (text_only true) or enforced at runtime via overrides as shown above. In chat mode, handle agent_response events and send user messages programmatically with sendUserMessage. (elevenlabs.io)
- Passing dynamicVariables when starting the session is supported; use secret__ prefix for sensitive data that should only populate tool headers. (elevenlabs.io)
- Use secret
should i use langchain maybe better.
Short answer: there’s no need to use LangChain for this. ElevenLabs doesn’t provide or require a LangChain integration, and our docs don’t recommend it. For a chat-only experience with dynamic variables, use either the ElevenLabs widget or the official SDKs/WebSocket API.
What our docs support
- Chat-only in your site: the Conversational AI widget supports text-only mode and accepts dynamic-variables at runtime. Note: widgets currently require public agents (auth disabled). (elevenlabs.io)
- Dynamic variables (including secrets): define {{vars}} in prompts/tools, pass them at session start or via the widget, and use secret__ prefixed variables to keep sensitive values out of the LLM and only in webhook tool headers. (elevenlabs.io)
- Custom chat UI in Next.js: connect directly via the Conversational AI WebSocket API or the SDKs, and pass dynamic_variables when initiating the conversation. Never expose your API key client-side; use signed URLs for private agents. (elevenlabs.io)
- First‑party SDKs and libraries: use the official JavaScript/React/Python/React Native/Swift libraries for type‑safe integration. (elevenlabs.io)
- Bring your own LLM: if you do want external orchestration, you can point the agent at an OpenAI‑compatible custom LLM endpoint. This is the documented path for “bring any LLM”; LangChain itself isn’t documented by us. (elevenlabs.io)
Bottom line: unless you specifically need LangChain for your own app logic, stick with the ElevenLabs widget or SDK/WebSocket. You’ll get chat‑only mode plus dynamic variables without extra framework complexity, all within supported, documented flows. (elevenlabs.io)
Sources:
Widget customization | ElevenLabs Documentation
Dynamic variables | ElevenLabs Documentation
Agent WebSockets
Libraries & SDKs | ElevenLabs Documentation
Integrate your own model | ElevenLabs Documentation
Widget customization | ElevenLabs Documentation
is elevenlabs chat only mode seession based? or could one create a 'completion' api powered on top of it?
Short answer: Chat Mode is session-based.
- ElevenLabs Chat Mode is implemented via conversations that you start as a session (e.g., Conversation.startSession) and interact with over WebSocket/WebRTC. You send text using user_message and receive agent_response events, and you can end the session afterward. (elevenlabs.io)
- The official docs do not expose a stateless “chat completions” REST endpoint for agents; the documented interface for runtime chat is the session/WebSocket flow. (elevenlabs.io)
- There are simulation endpoints for testing/evaluation (“simulate conversation” batch/streaming), but they are positioned for simulation workflows, not real-time end-user chat. (elevenlabs.io)
- If you want an OpenAI-style /v1/chat/completions backend, you can plug in a custom LLM server with that interface to power the agent; you still talk to the agent via the session APIs. (elevenlabs.io)
References:
- Chat Mode guide and SDK usage. (elevenlabs.io)
- Agent WebSockets API (conversation_id, user_message, agent_response). (elevenlabs.io)
- Simulate Conversations (testing endpoints). (elevenlabs.io)
- Custom LLM (OpenAI-compatible chat completions to back your agent). (elevenlabs.io)
Sources:
Chat Mode | ElevenLabs Documentation
Agent WebSockets | ElevenLabs Documentation
Simulate Conversations | ElevenLabs Documentation
Integrate your own model | ElevenLabs Documentation
Chat Mode | ElevenLabs Documentation
Agent WebSockets | ElevenLabs Documentation
Simulate Conversations | ElevenLabs Documentation
Integrate your own model | ElevenLabs Documentation
so how would this work with a widget than. especially if one wants dnyamic variables loaded.