Quickstart

Connect to an Expressive Agent with the LiveKit SDK in six steps

Create a V2 session for an Expressive Agent and connect to it directly with the LiveKit SDK. This path is for backend services and native apps.

Install the LiveKit SDK

Install the SDK for your platform.

npm install livekit-server-sdk node-fetch

Create an Expressive Agent

V2 sessions only work with Expressive Agents. Create one via the Agents API or D-ID Studio. The presenter type must be expressive.

curl -X POST "https://api.d-id.com/agents" \
  -H "Authorization: Basic <YOUR KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "presenter": {
      "type": "expressive",
      "presenter_id": "public_mia_elegant@avt_TJ0Tq5"
    }
  }'
{
  "id": "agt_abc123",
  "status": "created"
}

Save the id — this is your agentId for the next step.

Create a session

Call Create Session V2 to get a LiveKit URL and token.

curl -X POST "https://api.d-id.com/v2/agents/agt_abc123/sessions" \
  -H "Authorization: Basic <YOUR KEY>"
{
  "id": "session_abc123xyz",
  "session_url": "wss://livekit.d-id.com",
  "session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Save session_url and session_token for the next step.

Connect to the LiveKit room

Use the credentials from step 3 to join the LiveKit room.

import { Room } from "livekit-client";

const room = new Room();
await room.connect(session.session_url, session.session_token);

Render the agent's video and audio

The agent publishes its video and audio as separate LiveKit tracks. Listen for TrackSubscribed and attach each track to a media element so the user can see and hear the agent.

import { RoomEvent, Track } from "livekit-client";

room.on(RoomEvent.TrackSubscribed, (track) => {
  if (track.kind === Track.Kind.Video) {
    track.attach(document.getElementById("agent-video") as HTMLVideoElement);
  } else if (track.kind === Track.Kind.Audio) {
    track.attach(document.getElementById("agent-audio") as HTMLAudioElement);
  }
});

Your HTML needs a <video> and <audio> element for the tracks to attach to:

<video id="agent-video" autoplay playsinline></video>
<audio id="agent-audio" autoplay></audio>

Control the agent and handle responses

Commands are sent as text on a data-channel topic. Responses arrive as data events on the same channel.

// Send a speak command (text → video)
await room.localParticipant.sendText(
  JSON.stringify({ script: { type: "text", input: "Hello!" } }),
  { topic: "did.speak" }
);

// Listen for agent responses
room.on(RoomEvent.DataReceived, (payload) => {
  const data = JSON.parse(new TextDecoder().decode(payload));
  if (data.subject === "stream-video/done") console.log("Video ready");
  if (data.subject === "chat/answer") console.log("Agent:", data.content);
});

Your app is now streaming from the agent. For deeper coverage of each interaction, see Control the Agent, Subscribe to Media Tracks, and Listen for Agent Events.


Did this page help you?