Skip to content

ElevenLabs Agents

Use Runway Characters with an ElevenLabs agent when you already have one and want a custom Character to deliver it. ElevenLabs handles speech recognition, reasoning, and text-to-speech; Runway lip-syncs that audio to your Character over WebRTC and does not run its own conversation model for the session.

You’ll need:

Set these server-side environment variables (see the Next.js example for a full .env.example):

Terminal window
RUNWAYML_API_SECRET=...
RUNWAY_AVATAR_ID=...
ELEVENLABS_API_KEY=...
ELEVENLABS_AGENT_ID=...
  1. Install the Characters SDK

    Terminal window
    npm install @runwayml/avatars @runwayml/avatars-react

    Server helpers such as createElevenLabsSession live in @runwayml/avatars/api. The React package re-exports them for convenience, but your API route should import from the core package.

  2. Create a server route

    createElevenLabsSession from @runwayml/avatars/api fetches an ElevenLabs signed URL, creates a Runway session with integration: { type: "elevenlabs", signedUrl }, polls until READY, and returns sessionId, sessionKey, avatarId, and baseUrl for AvatarCall.

    app/api/avatar/connect/route.ts
    // app/api/avatar/connect/route.ts
    import { createElevenLabsSession } from '@runwayml/avatars/api';
    export async function POST() {
    const session = await createElevenLabsSession({
    runwayApiSecret: process.env.RUNWAYML_API_SECRET!,
    avatarId: process.env.RUNWAY_AVATAR_ID!,
    elevenLabsApiKey: process.env.ELEVENLABS_API_KEY!,
    elevenLabsAgentId: process.env.ELEVENLABS_AGENT_ID!,
    });
    return Response.json(session);
    }

    Also exported from @runwayml/avatars-react/api if you already depend on the React package only.

    Without the SDK, run the same three steps manually: fetch the signed URL, create the session, poll until ready. See Building your integration for session lifecycle patterns.

  3. Connect from the client

    Pass the JSON from your connect route to AvatarCall:

    'use client';
    import { AvatarCall } from '@runwayml/avatars-react';
    import '@runwayml/avatars-react/styles.css';
    export function Conversation({ sessionId, sessionKey, avatarId, baseUrl }) {
    return (
    <AvatarCall
    avatarId={avatarId}
    sessionId={sessionId}
    sessionKey={sessionKey}
    baseUrl={baseUrl}
    />
    );
    }

    createElevenLabsSession echoes avatarId and baseUrl so you can forward the server response without rebuilding those fields.

  4. Test it

    Trigger your connect route, then confirm Character video appears while your ElevenLabs agent responds. Mic audio goes Runway → worker → ElevenLabs; agent audio drives lip sync on the way back.

Full working app: Next.js + ElevenLabs example.

Runway bills realtime Character sessions while the Character worker is active. End calls via AvatarCall onEnd and handle errors on your connect route so sessions are not left running.

SymptomFix
404 Could not find AvatarUse a Character ID scoped to the same API key (see Custom Avatars)
401 or inactive API keyCheck your Runway API key in the Developer Portal
Session stuck NOT_READYRetry; confirm your environment has the ElevenLabs integration deployed
Silent agent / no audioSet PCM 16000Hz input format on the ElevenLabs agent
personality… cannot be used with integrationRemove personality, startScript, and tools from the session create request
ElevenLabs signed URL failsCheck xi-api-key, agent ID, and ElevenAgents read permission

See Troubleshooting for general Characters SDK debugging.