← ElevenLabsCONTENT HISTORY

Update to ElevenLabs

Snapshot Sep 30, 2026 · 22:53 UTC · version 1.0.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "name": "agents",
  "description": "Build voice AI agents with ElevenLabs. Use when creating voice assistants, customer service bots, interactive voice characters, or any real-time voice conversation experience, and when configuring an agent's tools, workflows, or procedures, including creating, editing, compiling, and publishing procedure drafts on an agent branch over the SDKs or REST API.",
  "included_files": [
    {
      "relative_path": "references/agent-configuration.md",
      "size_in_bytes": 31031
    },
    {
      "relative_path": "references/client-tools.md",
      "size_in_bytes": 19766
    },
    {
      "relative_path": "references/installation.md",
      "size_in_bytes": 4836
    },
    {
      "relative_path": "references/outbound-calls.md",
      "size_in_bytes": 6976
    },
    {
      "relative_path": "references/using-procedure-api.md",
      "size_in_bytes": 14870
    },
    {
      "relative_path": "references/widget-embedding.md",
      "size_in_bytes": 8240
    },
    {
      "relative_path": "references/writing-procedures.md",
      "size_in_bytes": 5545
    }
  ],
  "skill_md_contents": "---\nname: agents\ndescription: Build voice AI agents with ElevenLabs. Use when creating voice assistants, customer service bots, interactive voice characters, or any real-time voice conversation experience, and when configuring an agent's tools, workflows, or procedures, including creating, editing, compiling, and publishing procedure drafts on an agent branch over the SDKs or REST API.\nlicense: MIT\ncompatibility: Requires internet access and an ElevenLabs API key (ELEVENLABS_API_KEY).\nmetadata: {\"openclaw\": {\"requires\": {\"env\": [\"ELEVENLABS_API_KEY\"]}, \"primaryEnv\": \"ELEVENLABS_API_KEY\"}}\n---\n\n# ElevenLabs Agents Platform\n\nBuild voice AI agents with natural conversations, multiple LLM providers, custom tools, and easy web embedding.\n\n> **Setup:** See [Installation Guide](references/installation.md) for CLI and SDK setup.\n\n## Quick Start with CLI\n\nThe ElevenLabs CLI is the recommended way to create and manage agents:\n\n```bash\n# Install CLI and authenticate\nnpm install -g @elevenlabs/cli\nelevenlabs auth login\n\n# Initialize project and create an agent\nelevenlabs agents init\nelevenlabs agents add \"My Assistant\" --template complete\n\n# Push to ElevenLabs platform\nelevenlabs agents push\n```\n\n**Available templates:** `complete`, `minimal`, `voice-only`, `text-only`, `customer-service`, `assistant`\n\n### Python\n\n```python\nfrom elevenlabs import ElevenLabs\n\nclient = ElevenLabs()\n\nagent = client.conversational_ai.agents.create(\n    name=\"My Assistant\",\n    conversation_config={\n        \"agent\": {\n            \"first_message\": \"Hello! How can I help?\",\n            \"language\": \"en\",\n            \"prompt\": {\n                \"prompt\": \"You are a helpful assistant. Be concise and friendly.\",\n                \"llm\": \"gemini-2.0-flash\",\n                \"temperature\": 0.7\n            }\n        },\n        \"tts\": {\"voice_id\": \"JBFqnCBsd6RMkjVDRZzb\"}\n    }\n)\n```\n\n### JavaScript\n\n```javascript\nimport { ElevenLabsClient } from \"@elevenlabs/elevenlabs-js\";\nconst client = new ElevenLabsClient();\n\nconst agent = await client.conversationalAi.agents.create({\n  name: \"My Assistant\",\n  conversationConfig: {\n    agent: {\n      firstMessage: \"Hello! How can I help?\",\n      language: \"en\",\n      prompt: {\n        prompt: \"You are a helpful assistant.\",\n        llm: \"gemini-2.0-flash\",\n        temperature: 0.7\n      }\n    },\n    tts: { voiceId: \"JBFqnCBsd6RMkjVDRZzb\" }\n  }\n});\n```\n\n### CLI\n\nThe CLI reads `ELEVENLABS_API_KEY` from the environment automatically:\n\n```bash\nelevenlabs agents create \\\n  --json '{\"name\": \"My Assistant\", \"conversation_config\": {\"agent\": {\"first_message\": \"Hello!\", \"language\": \"en\", \"prompt\": {\"prompt\": \"You are helpful.\", \"llm\": \"gemini-2.0-flash\"}}, \"tts\": {\"voice_id\": \"JBFqnCBsd6RMkjVDRZzb\"}}}'\n```\n\n## Starting Conversations\n\n### Temporary LiveKit WebSocket Pin\n\nUntil the ElevenLabs LiveKit server supports `/rtc/v1`, browser clients using WebRTC can fail or stall during the underlying LiveKit WebSocket handshake with `livekit-client` versions newer than `2.16.1`. For React, Next.js, Electron, or other `@elevenlabs/client` / `@elevenlabs/react` integrations that use `connectionType: \"webrtc\"` or hit `wss://livekit.rtc.elevenlabs.io/rtc/v1`, add this temporary pin to `package.json`:\n\n```json\n{\n  \"overrides\": {\n    \"livekit-client\": \"2.16.1\"\n  }\n}\n```\n\nUse the pin when the app logs `/rtc/v1` 404s, `v1 RTC path not found`, or `could not establish pc connection` during session startup. This is a LiveKit server compatibility workaround for WebRTC sessions, not the ElevenLabs `connectionType: \"websocket\"` transport. Remove it after the upstream LiveKit server or SDK issue is fixed.\n\n**Authenticated WebRTC:** Request a session token from your backend. The response includes both\nthe token and the conversation ID:\n```python\nsession = client.conversational_ai.conversations.get_webrtc_token(\n    agent_id=\"your-agent-id\",\n)\nprint(session.token, session.conversation_id)\n```\n\n**Server-side (Python):** Get signed URL for client connection:\n```python\nsigned_url = client.conversational_ai.conversations.get_signed_url(\n    agent_id=\"your-agent-id\",\n    environment=\"staging\",\n)\n```\n\n**Client-side (JavaScript):**\n```javascript\nimport { Conversation } from \"@elevenlabs/client\";\n\nconst conversation = await Conversation.startSession({\n  agentId: \"your-agent-id\",\n  environment: \"staging\",\n  overrides: { asr: { keywords: [\"ElevenLabs\", \"TechCorp\"] } },\n  onMessage: (msg) => console.log(\"Agent:\", msg.message),\n  onUserTranscript: (t) => console.log(\"User:\", t.message),\n  onPing: (event) => console.log(\"Estimated latency:\", event.ping_ms),\n  onError: (e) => console.error(e)\n});\n```\n\n**React Hook:** Wrap hook consumers in `ConversationProvider`. Prefer granular hooks such as\n`useConversationControls` and `useConversationStatus` for session controls and UI state;\n`useConversation` remains available as the convenience all-in-one hook. Pass provider-level\ncallbacks such as `onError` when you want React to handle conversation errors in one place.\n```typescript\nimport {\n  ConversationProvider,\n  useConversationControls,\n  useConversationStatus,\n} from \"@elevenlabs/react\";\n\nfunction Agent({ signedUrl }: { signedUrl: string }) {\n  const { startSession, endSession } = useConversationControls();\n  const { status } = useConversationStatus();\n\n  if (status === \"connected\") {\n    return <button onClick={endSession}>End conversation</button>;\n  }\n\n  return (\n    <button onClick={() => startSession({ signedUrl })}>\n      Start conversation\n    </button>\n  );\n}\n\nfunction App({ signedUrl }: { signedUrl: string }) {\n  return (\n    <ConversationProvider\n      onError={(error) => console.error(\"Conversation error:\", error)}\n      onPing={(event) => console.log(\"Estimated latency:\", event.ping_ms)}\n    >\n      <Agent signedUrl={signedUrl} />\n    </ConversationProvider>\n  );\n}\n```\n\n## Configuration\n\n| Provider | Models |\n|----------|--------|\n| OpenAI | `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.5`, `gpt-5.5-2026-04-23`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5.4-2026-03-05`, `gpt-5.4-mini-2026-03-17`, `gpt-5.4-nano-2026-03-17`, `gpt-5`, `gpt-5-mini`, `gpt-5-nano`, `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano`, `gpt-4o`, `gpt-4o-mini`, `gpt-4-turbo` |\n| Anthropic | `claude-opus-4-7`, `claude-sonnet-4-6`, `claude-sonnet-4-5`, `claude-sonnet-4`, `claude-haiku-4-5`, `claude-3-7-sonnet`, `claude-3-5-sonnet`, `claude-3-haiku` |\n| Google | `gemini-3.7-flash`, `gemini-3.6-flash`, `gemini-3.1-flash-lite-preview`, `gemini-3.1-pro-preview`, `gemini-3-pro-preview`, `gemini-3-flash-preview`, `gemini-2.5-flash`, `gemini-2.5-flash-lite`, `gemini-2.0-flash`, `gemini-2.0-flash-lite` |\n| ElevenLabs | `glm-45-air-fp8`, `qwen3-30b-a3b`, `qwen36-35b-a3b`, `qwen35-35b-a3b`, `qwen35-397b-a17b`, `gpt-oss-120b` |\n| Custom | `custom-llm` (bring your own endpoint) |\n\nUse `GET /v1/convai/llm/list` to inspect the current model catalog, including deprecation state, token/context limits, capability flags such as image-input support, and model-specific reasoning effort support.\n\n**Popular voices:** `JBFqnCBsd6RMkjVDRZzb` (George), `EXAVITQu4vr4xnSDxMaL` (Sarah), `onwK4e9ZLuTAKqWW03F9` (Daniel), `XB0fDUnXU5powFXDhCwa` (Charlotte)\n\n**Turn eagerness:** `patient` (waits longer for user to finish), `normal`, or `eager` (responds quickly)\n\nSee [Agent Configuration](references/agent-configuration.md) for all options.\n\n## System Prompt Structure\n\nSection the prompt with markdown headings — the model prioritizes and interprets instructions more reliably ([prompting guide](https://elevenlabs.io/docs/eleven-agents/best-practices/prompting-guide)):\n\n```\n# Personality   – named character, 2-3 traits\n# Environment   – where they work, who they talk to\n# Tone          – vocal style as 4-5 bullets\n# Goal          – what success looks like (numbered for multi-step flows)\n```\n\nKeep instructions short and action-based. Mark critical steps with \"This step is important.\" For critical refusal/safety rules, include concise instructions in the prompt and also configure independent custom Guardrails via `platform_settings.guardrails` (see [Guardrails](#guardrails)).\n\n## Tools\n\nExtend agents with webhook, client, or built-in system tools. Tools are defined inside `conversation_config.agent.prompt`:\n\nWorkspace environment variables can resolve per-environment server tool URLs, headers, and auth connections, and runtime system variables such as `{{system__conversation_history}}` can pass full conversation context into tool calls when needed.\n\n```python\n\"prompt\": {\n    \"prompt\": \"You are a helpful assistant that can check the weather.\",\n    \"llm\": \"gemini-2.0-flash\",\n    \"tools\": [\n        # Webhook: server-side API call\n        {\"type\": \"webhook\", \"name\": \"get_weather\", \"description\": \"Get weather\",\n         \"api_schema\": {\"url\": \"https://api.example.com/weather\", \"method\": \"POST\",\n             \"request_body_schema\": {\"type\": \"object\", \"properties\": {\"location\": {\"type\": \"string\"}}, \"required\": [\"location\"]}}},\n        # Client: runs in the browser\n        {\"type\": \"client\", \"name\": \"show_product\", \"description\": \"Display a product\",\n         \"parameters\": {\"type\": \"object\", \"properties\": {\"productId\": {\"type\": \"string\"}}, \"required\": [\"productId\"]}}\n    ],\n    \"built_in_tools\": {\n        \"end_call\": {},\n        \"transfer_to_number\": {\"transfers\": [{\"transfer_destination\": {\"type\": \"phone\", \"phone_number\": \"+1234567890\"}, \"condition\": \"User asks for human support\"}]},\n        \"start_procedure\": {}\n    }\n}\n```\n\n**Client tools** run in browser:\n```javascript\nclientTools: {\n  show_product: async ({ productId }) => {\n    document.getElementById(\"product\").src = `/products/${productId}`;\n    return { success: true };\n  }\n}\n```\n\nSee [Client Tools Reference](references/client-tools.md) for complete documentation.\n\n### Built-in System Tools\n\nSet under `conversation_config.agent.prompt.built_in_tools`. `{}` enables defaults; provide `description` to customize; omit to disable.\n\n| Tool | Enable for |\n|------|------------|\n| `end_call` | All agents |\n| `language_detection` | Multilingual agents |\n| `transfer_to_number` | Phone-based human escalation |\n| `transfer_to_agent` | Multi-agent workflows |\n| `start_procedure` | Procedure-guided conversations (see [Procedures](#procedures)) |\n| `end_procedure` | Completing active procedures |\n| `skip_turn` | Tutoring / coaching (silent listening) |\n| `voicemail_detection` | Outbound calling |\n| `play_keypad_touch_tone` | IVR navigation |\n\n`run_subagent` is a system tool for delegating a task to another configured agent. Add it to\n`conversation_config.agent.prompt.tools` with `params.system_tool_type: \"run_subagent\"` and an\n`agents` array. Each entry requires `agent_id` and `description`; `branch_id` and a JSON-schema\n`parameters` object are optional.\n\n`knowledge_base` is a system tool for letting the model choose how to inspect attached knowledge.\nAdd it to `conversation_config.agent.prompt.tools` with `type: \"system\"`, a `name`, and\n`params.system_tool_type: \"knowledge_base\"`. Use `enabled_strategies` to expose any combination of\n`cat`, `keyword`, `semantic`, and `ls`:\n\n```json\n{\n  \"type\": \"system\",\n  \"name\": \"knowledge_base\",\n  \"description\": \"Search the attached knowledge base.\",\n  \"params\": {\n    \"system_tool_type\": \"knowledge_base\",\n    \"enabled_strategies\": [\"semantic\", \"keyword\"]\n  }\n}\n```\n\n### Integration Tools\n\nPre-built connectors managed by the platform. Create a connection with credentials, then attach via `tool_ids`:\n\n| Integration | Use case |\n|-------------|----------|\n| `calcom` | Scheduling appointments |\n| `salesforce` | CRM lookups, case creation |\n| `hubspot` | CRM, marketing, contacts |\n| `zendesk` | Support ticketing |\n\nThree-step flow: `POST /v1/convai/api-integrations/{id}/connections` → `GET /v1/convai/api-integrations/{id}/tools` → `POST /v1/convai/tools` with `api_integration_id` and `api_integration_connection_id`. Attach to the agent with `\"prompt\": {\"tool_ids\": [\"tool_xxxx\"]}`. Inline `tools` and `tool_ids` can coexist — prefer an integration over a duplicate custom webhook.\n\n### Public-API Webhook Examples\n\nNo-auth APIs useful for prototypes (URLs must be HTTPS):\n\n| Tool | URL | Purpose |\n|------|-----|---------|\n| `get_weather` | `https://wttr.in/{location}?format=j1` | Current weather |\n| `search_wikipedia` | `https://en.wikipedia.org/api/rest_v1/page/summary/{topic}` | Topic summary |\n| `get_exchange_rate` | `https://open.er-api.com/v6/latest/{base_currency}` | FX rates |\n\n## Workflows\n\nRoute conversations through discrete steps with branching logic. Define under the agent's top-level `workflow` field. Reference: [Agent Workflows](https://elevenlabs.io/docs/eleven-agents/customization/agent-workflows).\n\n**Node types:** `start` (ID must be `\"start_node\"`), `end`, `override_agent` (subagent step with `label` + `additional_prompt`), `dispatch_tool` (executes a tool with success/failure routing), `agent_transfer`, `transfer_to_number`.\n\n**Edge types:** `unconditional`, `llm` (natural-language condition), `expression` (deterministic data check). Tool nodes have separate success/failure edges.\n\n**Scope tools per step** with `additional_tool_ids` on a node — prevents the wrong tool firing at the wrong step. Set `additional_tool_ids: []` on conversational routing nodes such as greeting and `classify_intent` so they only converse:\n\n```json\n{\n  \"type\": \"override_agent\",\n  \"label\": \"Book Appointment\",\n  \"additional_prompt\": \"Discuss preferred dates and doctors. Show the booking form once agreed.\",\n  \"entry_behavior\": \"wait_for_user\",\n  \"additional_tool_ids\": [\"show_booking_form\", \"display_appointment_card\"],\n  \"position\": {\"x\": 0, \"y\": 400}\n}\n```\n\nInclude `position` (`{x, y}`) on every node so the editor renders cleanly. Start at `y=0`, put `end` at the bottom, and space branches horizontally at `x=-150` and `x=150`; suggested spacing is 200px vertical between levels and 300px horizontal between branches. Keep workflows to 4-7 nodes and always have a path to `end`.\n\nUse `entry_behavior` on `override_agent` nodes to choose whether a sub-agent speaks immediately (`generate_immediately`), waits for user input (`wait_for_user`), or lets the platform decide (`auto`).\n\nFor nested agent transfers, set `enable_nesting` on a `standalone_agent` node and\n`return_when_nested` on an `end` node that should return control to the parent workflow.\n\n## Procedures\n\nReusable instruction blocks an agent runs when a trigger matches. A procedure is `free_form` (markdown guidance the agent adapts, and the only type that can reference knowledge base documents) or `deterministic` (ordered, typed steps for flows that must run consistently). Procedures are in Alpha. See [Using the Procedure API](references/using-procedure-api.md) for the full CLI and SDK flow, and [Writing Procedures](references/writing-procedures.md) for the step schema and authoring rules.\n\nProcedures live on an agent branch, and every write stages a per-user draft:\n\n| Operation | Call |\n|-----------|------|\n| List, create, read, update, discard, remove | `/v1/convai/agents/{agent_id}/branches/{branch_id}/procedures...` (`procedures.*` and `procedures.drafts.*` in the SDKs) |\n| Compile | `POST .../procedures/compile` (`procedures.compile`) |\n| Publish | `PATCH /v1/convai/agents/{agent_id}?branch_id=...` (`agents.update`) |\n\nSemantics worth knowing before writing any of these calls:\n\n- Nothing reaches the live agent until you publish. Publishing is not a procedure endpoint; one PATCH on the agent versions every changed procedure draft on the branch.\n- `GET .../procedures/{procedure_id}` reads branch HEAD and returns `404` until that procedure's first publish. Read the `/draft` variant to see a procedure you just created; do not retry the create.\n- Compile only when structured (`deterministic`) procedures changed. Compilation turns them into workflow nodes, so the publish must carry the `workflow` that compile returned. Free-form-only changes publish without compiling, because the agent loads free-form procedures from their published versions.\n- Compile validates structured content and is the only way to check it. On `400` it returns `errors` keyed by procedure ID with the offending field `path`; repair the draft and compile again rather than publishing.\n- A draft update replaces the whole body. Read the draft first, then resend `name`, `type`, and `trigger` alongside the new `content`.\n- `content` is markdown for a `free_form` procedure, and a JSON-encoded object with a `trigger` and a `steps` array for a `deterministic` one. Serialize it; do not hand-escape quotes.\n- Routing is driven by the `trigger` text, not the procedure name. Write concrete, non-overlapping triggers that cover the phrasings a user would actually say.\n- Procedure APIs require `elevenlabs` (Python) or `@elevenlabs/elevenlabs-js` at `2.60.0` or newer.\n\n## Guardrails\n\nLayered safety enforcement that runs independently of the LLM — configured under `platform_settings.guardrails`, not in the system prompt. Reference: [Guardrails](https://elevenlabs.io/docs/eleven-agents/best-practices/guardrails).\n\n```json\n\"platform_settings\": {\n  \"guardrails\": {\n    \"version\": \"1\",\n    \"focus\": {\"is_enabled\": true},\n    \"prompt_injection\": {\"is_enabled\": true},\n    \"content\": {\"config\": {\"harassment\": {\"is_enabled\": true, \"threshold\": 0.5}}},\n    \"custom\": {\n      \"config\": {\n        \"configs\": [{\n          \"is_enabled\": true,\n          \"name\": \"No medical diagnoses\",\n          \"prompt\": \"Block the agent from providing medical diagnoses or treatment advice.\",\n          \"execution_mode\": \"blocking\",\n          \"model\": \"gemini-2.5-flash-lite\",\n          \"history_message_count\": 1,\n          \"trigger_action\": {\"type\": \"retry\", \"feedback\": \"Reason: {{trigger_reason}}\"}\n        }]\n      }\n    }\n  }\n}\n```\n\n**Types:** `focus` (on-topic), `prompt_injection` (manipulation defense), `content` (category filters), `custom` (LLM-evaluated domain rules). Content categories include `harassment`, `profanity`, `sexual`, `violence`, `self_harm`, and `medical_and_legal_information` — threshold range `0.0`–`1.0` (default `0.3`). Custom rules use `execution_mode: \"blocking\"` with a `model`, `history_message_count`, and `trigger_action` (e.g., `retry` with feedback). Custom guardrails evaluate in parallel and fail-open.\n\n**Per vertical:** healthcare/finance/legal → enable `medical_and_legal_information`; education/youth → `sexual`/`violence`/`self_harm`/`profanity`; support/sales → `harassment`/`profanity`. All agents benefit from `focus` + `prompt_injection` + 2-4 custom rules.\n\n## Testing Agents\n\nThree test types via `POST /v1/convai/agent-testing/create`, then attached with PATCH on the agent. Reference: [Agent Testing](https://elevenlabs.io/docs/eleven-agents/customization/agent-testing).\n\n| Type | Purpose |\n|------|---------|\n| `llm` | Scenario test — does the agent respond appropriately to a message? |\n| `tool` | Tool-call test — right tool, right parameters? |\n| `simulation` | Multi-turn flow with a simulated user persona |\n\n```json\n// Tool-call test (snake_case throughout; chat_history role is \"user\" or \"agent\")\n{\n  \"name\": \"Books with correct doctor and date\",\n  \"type\": \"tool\",\n  \"chat_history\": [\n    {\"role\": \"user\", \"message\": \"Dr. Smith on March 5 at 2pm\", \"time_in_call_secs\": 10}\n  ],\n  \"tool_call_parameters\": {\n    \"referenced_tool\": {\"id\": \"show_booking_form\", \"type\": \"client\"},\n    \"parameters\": [\n      {\"path\": \"doctor_name\", \"eval\": {\"type\": \"llm\", \"description\": \"Should reference Dr. Smith\"}},\n      {\"path\": \"date\", \"eval\": {\"type\": \"regex\", \"pattern\": \"2025-03-05|March 5\"}}\n    ]\n  }\n}\n```\n\nEval strategies: `exact`, `regex`, `llm`. Prompt evaluation criteria can use binary scoring or\nnumeric scoring with `scoring_mode: \"numeric_uniform\"`, `max_score`, and `score_instructions`;\nnumeric scores are normalized into the aggregate conversation success percentage. Attach via an agent update:\n\n```bash\nelevenlabs agents update --agent-id \"your-agent-id\" \\\n  --json '{\"platform_settings\": {\"testing\": {\"attached_tests\": [{\"test_id\": \"test_xxxx\"}]}}}'\n```\n\nRun selected tests with `POST /v1/convai/agents/{agent_id}/run-tests`. The request\nbody requires `tests` and accepts `repeat_count` from `1` to `50` for repeated runs.\nSimulation tests can define up to 30 `success_conditions` prompts; all criteria are\nevaluated and merged into the final result.\nSimulation tests can also define `tool_mock_overrides`, keyed by tool ID, to replace shared response\nmocks for one test. Each override is an array of mocks with a required `mock_result`; set\n`is_error: true` to exercise a tool-failure path. Overrides only apply to tools enabled for mocking\nthrough `tool_mock_config`.\nFor completed conversations, rerun one evaluation criterion with `POST /v1/convai/conversations/{conversation_id}/analysis/evaluations/run` and a request body containing `evaluation_id`.\n\n## Widget Embedding\n\n```html\n<elevenlabs-convai agent-id=\"your-agent-id\"></elevenlabs-convai>\n<script src=\"https://unpkg.com/@elevenlabs/convai-widget-embed\" async type=\"text/javascript\"></script>\n```\n\nCustomize with attributes: `avatar-image-url`, `action-text`, `start-call-text`, `end-call-text`.\n\nSee [Widget Embedding Reference](references/widget-embedding.md) for all options.\n\n## Outbound Calls\n\nMake outbound phone calls using your agent via Twilio or Exotel integration:\n\nThe examples below use Twilio. See the reference for Exotel usage.\n\n### Python\n\n```python\nresponse = client.conversational_ai.twilio.outbound_call(\n    agent_id=\"your-agent-id\",\n    agent_phone_number_id=\"your-phone-number-id\",\n    to_number=\"+1234567890\",\n    call_recording_enabled=True\n)\nprint(f\"Call initiated: {response.conversation_id}\")\n```\n\n### JavaScript\n\n```javascript\nconst response = await client.conversationalAi.twilio.outboundCall({\n  agentId: \"your-agent-id\",\n  agentPhoneNumberId: \"your-phone-number-id\",\n  toNumber: \"+1234567890\",\n  callRecordingEnabled: true,\n});\n```\n\n### CLI\n\n```bash\nelevenlabs agents twilio outbound_call \\\n  --agent-id \"your-agent-id\" \\\n  --agent-phone-number-id \"your-phone-number-id\" \\\n  --to-number \"+1234567890\" \\\n  --call-recording-enabled true\n```\n\nSee [Outbound Calls Reference](references/outbound-calls.md) for provider-specific endpoints, configuration overrides, and dynamic variables.\n\n## Managing Agents\n\n### Using CLI (Recommended)\n\n```bash\n# List agents and check status\nelevenlabs agents list\nelevenlabs agents status\n\n# Import agents from platform to local config\nelevenlabs agents pull                      # Import all agents\nelevenlabs agents pull --agent <agent-id>   # Import specific agent\n\n# Push local changes to platform\nelevenlabs agents push              # Upload configurations\nelevenlabs agents push --dry-run    # Preview changes first\n\n# Add tools\nelevenlabs tools add-webhook \"Weather API\"\nelevenlabs tools add-client \"UI Tool\"\n```\n\n### Project Structure\n\nThe CLI creates a project structure for managing agents:\n\n```\nyour_project/\n├── agents.json       # Agent definitions\n├── tools.json        # Tool configurations\n├── tests.json        # Test configurations\n├── agent_configs/    # Individual agent configs\n├── tool_configs/     # Individual tool configs\n└── test_configs/     # Individual test configs\n```\n\n### SDK Examples\n\n```python\n# List\nagents = client.conversational_ai.agents.list()\n\n# Get\nagent = client.conversational_ai.agents.get(agent_id=\"your-agent-id\")\n\n# Update (partial - only include fields to change)\nclient.conversational_ai.agents.update(agent_id=\"your-agent-id\", name=\"New Name\")\nclient.conversational_ai.agents.update(agent_id=\"your-agent-id\",\n    conversation_config={\n        \"agent\": {\"prompt\": {\"prompt\": \"New instructions\", \"llm\": \"claude-sonnet-4\"}}\n    })\n\n# Delete\nclient.conversational_ai.agents.delete(agent_id=\"your-agent-id\")\n```\n\nSee [Agent Configuration](references/agent-configuration.md) for all configuration options and SDK examples.\n\n## Error Handling\n\n```python\ntry:\n    agent = client.conversational_ai.agents.create(...)\nexcept Exception as e:\n    print(f\"API error: {e}\")\n```\n\nCommon errors: **401** (invalid key), **404** (not found), **422** (invalid config), **429** (rate limit)\n\n## References\n\n- [Installation Guide](references/installation.md) - SDK setup and migration\n- [Agent Configuration](references/agent-configuration.md) - All config options and CRUD examples\n- [Client Tools](references/client-tools.md) - Webhook, client, and system tools\n- [Using the Procedure API](references/using-procedure-api.md) - Procedure CLI and SDK flow, compile and publish\n- [Writing Procedures](references/writing-procedures.md) - Trigger and content authoring, step schema\n- [Widget Embedding](references/widget-embedding.md) - Website integration\n- [Outbound Calls](references/outbound-calls.md) - Phone call integrations\n"
}

SHA-256: 667756ebfa6734276ad583afde9870f692734ed903590bf44007f1462b2d2ade