Skip to main content
Interaction Events let you control and customize live conversations with a Replica in real time. You can send interaction events to the Conversational Video Interface (CVI) and listen to events the Replica sends back during the call.

Interaction Types

Observable Events

Which Interaction Should I Send?

InteractionUse when
conversation.respondA user typed a message and the replica should respond as if the user had spoken that text. This is the natural text-input event for chat-style UI.
conversation.echoYour app supplies text or audio for the replica to speak directly, such as echo-mode or custom ASR flows.
conversation.interruptYour app needs to stop the replica while it is speaking.

Daily sendAppMessage Payloads

Use Daily’s sendAppMessage(interaction, '*') to send interaction events over the call data channel.

Text input: conversation.respond

call.sendAppMessage(
  {
    message_type: 'conversation',
    event_type: 'conversation.respond',
    conversation_id: 'YOUR_CONVERSATION_ID',
    properties: {
      text: 'User message as if they had just finished speaking.',
    },
  },
  '*'
);

Replica speaks supplied content: conversation.echo

call.sendAppMessage(
  {
    message_type: 'conversation',
    event_type: 'conversation.echo',
    conversation_id: 'YOUR_CONVERSATION_ID',
    properties: {
      modality: 'text',
      text: 'Text for the replica to speak directly.',
      done: true,
    },
  },
  '*'
);
For audio echo, set modality: 'audio', pass base64 audio, include sample_rate, and keep done: false until the final audio chunk.

Stop the replica: conversation.interrupt

call.sendAppMessage(
  {
    message_type: 'conversation',
    event_type: 'conversation.interrupt',
    conversation_id: 'YOUR_CONVERSATION_ID',
  },
  '*'
);

Event Ordering and Turn Tracking

All events broadcasted by Tavus include the following fields for timing, ordering, and grouping:
  • timestamp (number) — Unix timestamp (seconds since epoch) indicating when the event was created. Use this to build timestamped transcripts or reconstruct the full timeline of a conversation.
  • seq (integer) — A globally monotonic sequence number. Every event gets the next value in the sequence, so a higher seq always means the event was sent later. Use this to reconcile events that may arrive out of order over the data channel.
  • turn_idx (integer, optional) — The conversation turn index. This value increments each time a conversation.respond interaction is received, and groups all events that belong to the same conversational turn. Use it to correlate related events — for example, an utterance, its tool calls, and the replica speaking state changes that all stem from the same user input. This field is present on conversation-related events (utterances, tool calls, speaking state changes, perception events, etc.) and omitted on events that are not tied to a specific turn.
  • inference_id (string, optional) — A stable identifier for a generated utterance or inference. Use it with conversation.utterance, conversation.utterance.streaming, and tool-call events to reconcile optimistic UI state with the final events Tavus emits.

Call Client Example

Interaction events use a WebRTC data channel for communication. In Tavus’s case, this is powered by Daily, which makes setting up the call client quick and simple.
Here’s an example of using DailyJS to create a call client in JavaScript:
The Daily app-message event is used to send and receive events and interactions between your server and CVI.
<html>
  <script crossorigin src="https://unpkg.com/@daily-co/daily-js"></script>
  <body>
    <!-- Add input field and send button -->
    <input type="text" id="messageInput" placeholder="Enter your message">
    <button onclick="sendAppMessage()">Send Message</button>

    <script>
      call = window.Daily.createFrame();
      call.on('app-message', (event) => {
        console.log('app-message', event);
      });
      
      call.join({ url: 'YOUR_CONVERSATION_URL' });

      function sendAppMessage() {
        const messageInput = document.getElementById('messageInput');
        const message = messageInput.value;
        if (message) {
          const interaction = {
            "message_type": "conversation",
            "event_type": "conversation.respond",
            "conversation_id": "YOUR_CONVERSATION_ID",
            "properties": {
              "text": `${message}`
            }
          }
          const hi = call.sendAppMessage(interaction, '*');
          console.log('Sending message: ', hi);
          console.log('Sent message: ', interaction);
          messageInput.value = '';
        }
      }
    </script>
  </body>
</html>