> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inference.net/llms.txt
> Use this file to discover all available pages before exploring further.

# ElevenLabs Agents Traces

> Trace ElevenLabs Agents conversation sessions, transcripts, and client tool calls.

Catalyst instruments the ElevenLabs Agents SDK in TypeScript and Python.
Initialize tracing before starting a conversation so the SDK conversation
lifecycle and client-tool callbacks are patched before the session begins.

Use this guide for applications that use `@elevenlabs/client` or the Python
`elevenlabs.conversational_ai.conversation` APIs.

## What Is Captured

* One AGENT span named `ElevenLabs Conversation` for each conversation session
* User and agent transcript messages as OpenInference message attributes
* ElevenLabs metadata such as agent ID, conversation ID, user ID, auth mode, and
  text-only mode
* TOOL child spans for registered client tools, including tool name, arguments,
  result, and errors
* Error status and exception details when session startup, tool execution, or
  shutdown fails

## Install

<CodeGroup>
  ```bash TypeScript theme={"system"}
  bun add @inference/tracing @elevenlabs/client
  ```

  ```bash Python theme={"system"}
  pip install 'inference-catalyst-tracing[elevenlabs]'
  ```
</CodeGroup>

## TypeScript Conversation Session

Pass the ElevenLabs SDK namespace into `setup()` before calling
`Conversation.startSession()`.

```typescript TypeScript theme={"system"}
import * as ElevenLabs from "@elevenlabs/client";
import { Conversation } from "@elevenlabs/client";
import { setup } from "@inference/tracing";

const tracing = await setup({
  serviceName: "voice-support",
  modules: { elevenlabs: ElevenLabs },
});

const conversation = await Conversation.startSession({
  agentId: process.env.ELEVENLABS_AGENT_ID!,
  textOnly: true,
  userId: "user_123",
  clientTools: {
    lookupAppointment: async ({ user_id }) => {
      return JSON.stringify({
        user_id,
        starts_at: "2026-04-29T10:30:00Z",
      });
    },
  },
  onMessage: (message) => {
    console.log(message.role, message.message);
  },
});

conversation.sendUserMessage("When is my next appointment?");
await conversation.endSession();
await tracing.shutdown();
```

For private agents, use the same tracing setup and pass the `signedUrl` or
`conversationToken` options that your ElevenLabs app already uses. Catalyst
keeps the same outer `ElevenLabs Conversation` span shape.

## Python Conversation Session

Call `setup()` before constructing and starting the `Conversation`. This patches
the installed ElevenLabs SDK and records the session lifecycle automatically.

```python Python theme={"system"}
import os

from elevenlabs.client import ElevenLabs
from elevenlabs.conversational_ai.conversation import ClientTools, Conversation
from inference_catalyst_tracing import setup

tracing = setup(service_name="voice-support")

client = ElevenLabs(api_key=os.environ.get("ELEVENLABS_API_KEY"))
client_tools = ClientTools()
client_tools.register(
    "lookupAppointment",
    lambda params: {
        "user_id": params["user_id"],
        "starts_at": "2026-04-29T10:30:00Z",
    },
)

conversation = Conversation(
    client,
    os.environ["ELEVENLABS_AGENT_ID"],
    user_id="user_123",
    requires_auth=bool(os.environ.get("ELEVENLABS_API_KEY")),
    audio_interface=None,
    client_tools=client_tools,
    callback_agent_response=lambda text: print(f"Agent: {text}"),
    callback_user_transcript=lambda text: print(f"User: {text}"),
)

conversation.start_session()
conversation.send_user_message("When is my next appointment?")
conversation.end_session()
conversation_id = conversation.wait_for_session_end()
print(f"Conversation ID: {conversation_id}")

tracing.shutdown()
```

`audio_interface=None` keeps the example text-only. For voice conversations, use
your normal ElevenLabs audio interface; the instrumentation records the same
conversation span and transcript callbacks.

## Stable Agent Identity

<CodeGroup>
  <Metadata text="integrations/traces/elevenlabs-agent-identity-ts" />

  ```typescript TypeScript theme={"system"}
  import { agentSpan } from "@inference/tracing";

  await agentSpan(
    {
      agentId: "voice-support-agent",
      agentName: "Voice Support Agent",
      spanName: "voice-support.run",
      sessionId: "conversation-voice-1",
      role: "support",
      system: "elevenlabs",
    },
    async (span) => {
      span.setInput("When is my next appointment?");
      const conversation = await Conversation.startSession({
        agentId: process.env.ELEVENLABS_AGENT_ID!,
        textOnly: true,
        userId: "user_123",
      });
      conversation.sendUserMessage("When is my next appointment?");
      await conversation.endSession();
      span.setOutput("conversation ended");
    },
  );
  ```

  <Metadata text="integrations/traces/elevenlabs-agent-identity-python" />

  ```python Python theme={"system"}
  from inference_catalyst_tracing import agent_span

  with agent_span(
      tracing.tracer,
      agent_id="voice-support-agent",
      agent_name="Voice Support Agent",
      span_name="voice-support.run",
      session_id="conversation-voice-1",
      agent_role="support",
      system="elevenlabs",
  ) as span:
      span.set_input("When is my next appointment?")
      conversation.start_session()
      conversation.send_user_message("When is my next appointment?")
      conversation.end_session()
      conversation_id = conversation.wait_for_session_end()
      span.set_output({"conversation_id": conversation_id})
  ```
</CodeGroup>

## Verify In Catalyst

Filter traces by `service.name=voice-support`. A successful session should show
an `ElevenLabs Conversation` AGENT span with nested TOOL spans when your agent
calls `lookupAppointment`. When you add the wrapper above, the trace also has an
outer AGENT span with your stable `agent.id`.

For short-lived scripts, always call `tracing.shutdown()` before process exit so
batched spans are flushed to Catalyst.
