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

# Agora Integration

> Connect to a LemonSlice Avatar via Agora's Conversational AI Engine

## Overview

The [Agora Conversational AI Engine](https://docs.agora.io/en/conversational-ai/overview/product-overview) provides realtime voice agents over Agora RTC.
LemonSlice plugs in as the avatar layer through Agora's [generic avatar](https://docs.agora.io/en/conversational-ai/models/avatar/generic) vendor.

## Prerequisites

1. A LemonSlice account and API key associated with an active subscription. Create a key at [lemonslice.com/developers](https://lemonslice.com/developers).
2. A reference image for your avatar. See [our guide](/docs/prompting-guide/avatar-image-tips) for recommendations on how to design your avatar image to achieve the best quality possible.
3. Agora Conversational AI setup
   * An Agora project with Conversational AI Engine enabled, plus an App ID and Basic Auth credentials for the REST API
   * A way to mint Agora RTC tokens for the end user, the Agora agent, and the LemonSlice avatar (three distinct UIDs). The agent and avatar tokens need publish permission; the user token needs publish (microphone) and subscribe.

<Note>
  If you are not already using the Agora Conversational AI Engine, start with their voice agent [quickstart](https://docs.agora.io/en/conversational-ai/get-started/quickstart), or explore [other](/docs/introduction#integrate-real-time-avatars-into-your-app) LemonSlice integration paths.
</Note>

## How to use

<Steps>
  <Step title="Add LemonSlice to the Agora join request">
    When you call Agora's Conversational AI `join` endpoint, add an `avatar` block under `properties`. Use Agora's `generic` vendor pointed at LemonSlice:

    ```json theme={null}
    {
      "avatar": {
        "vendor": "generic",
        "enable": true,
        "params": {
          "api_key": "<lemonslice_api_key>",
          "api_base_url": "https://lemonslice.com/api/liveai/agora",
          "avatar_id": "lemonslice",
          "agent_image_url": "<public_image_url>",
          "video_encoding": "H264",
          "agora_uid": "<avatar_rtc_uid>",
          "agora_token": "<avatar_rtc_token>"
        }
      }
    }
    ```

    | Parameter               | Description                                                                                                                                                                                                                                    |
    | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `api_key`               | LemonSlice API key for authentication.                                                                                                                                                                                                         |
    | `api_base_url`          | Always `https://lemonslice.com/api/liveai/agora`                                                                                                                                                                                               |
    | `avatar_id`             | Always `"lemonslice"`                                                                                                                                                                                                                          |
    | `agent_image_url`       | *(Optional)* A publicly accessible URL to the avatar image. Exactly one of `agent_image_url` / `agent_id` / `agent_image_base64` is required.                                                                                                  |
    | `agent_id`              | *(Optional)* The ID of the LemonSlice agent. Exactly one of `agent_image_url` / `agent_id` / `agent_image_base64` is required. If provided, we will also use agent-configured settings as defaults for `agent_prompt` and `agent_idle_prompt`. |
    | `agent_image_base64`    | *(Optional)* A base64-encoded avatar image. Exactly one of `agent_image_url` / `agent_id` / `agent_image_base64` is required.                                                                                                                  |
    | `video_encoding`        | Video codec: `"H264"`, `"VP8"`, or `"AV1"`.                                                                                                                                                                                                    |
    | `agora_uid`             | RTC UID the avatar publishes under. Must be distinct from your `agent_rtc_uid` and any `remote_rtc_uids`.                                                                                                                                      |
    | `agora_token`           | RTC token minted for `agora_uid` on the same channel as the agent, with publish permission.                                                                                                                                                    |
    | `activity_idle_timeout` | *(Optional)* Idle timeout in seconds. Defaults to `120`. Set to `0` for no idle timeout (not recommended for initial development). Ensure sessions are properly terminated to avoid stale calls and runaway billing.                           |
    | `agent_prompt`          | *(Optional)* A high-level system prompt that subtly influences the avatar's movements, expressions, and emotional demeanor while speaking. Defaults to `"a person talking"`.                                                                   |
    | `agent_idle_prompt`     | *(Optional)* A high-level system prompt that influences the avatar during the idle state. Defaults to `"a serious person"`.                                                                                                                    |
    | `model`                 | *(Optional)* Model variant (`"lite"`, `"flash"`, or `"pro"`). Leave unset to use the normal flagship model.                                                                                                                                    |
    | `aspect_ratio`          | *(Optional)* Output aspect ratio (`"2x3"`, `"9x16"`, or `"1x1"`). Defaults to `"2x3"`.                                                                                                                                                         |
    | `response_done_timeout` | *(Optional)* Time in seconds to wait without receiving new audio bytes before marking the response as complete. Some TTS models do not send an end response event, or do not send it in a timely manner.                                       |
  </Step>

  <Step title="Start the Agora agent">
    POST to Agora's `join` endpoint with your usual `asr`, `llm`, and `tts` configuration plus the `avatar` block above:

    ```bash theme={null}
    curl --request POST \
      --url "https://api.agora.io/api/conversational-ai-agent/v2/projects/$AGORA_APP_ID/join" \
      --header "Authorization: Basic $AGORA_BASIC_AUTH" \
      --header "Content-Type: application/json" \
      --data '{
        "name": "lemonslice-session-1",
        "properties": {
          "channel": "demo-room",
          "token": "<agent_rtc_token>",
          "agent_rtc_uid": "1000",
          "remote_rtc_uids": ["2000"],
          "idle_timeout": 120,
          "asr": { "language": "en-US" },
          "llm": {
            "url": "https://api.openai.com/v1/chat/completions",
            "api_key": "<openai_key>",
            "system_messages": [
              { "role": "system", "content": "You are a helpful avatar." }
            ]
          },
          "tts": {
            "vendor": "elevenlabs",
            "params": {
              "base_url": "wss://api.elevenlabs.io/v1",
              "key": "<elevenlabs_api_key>",
              "model_id": "eleven_flash_v2_5",
              "voice_id": "<elevenlabs_voice_id>",
              "sample_rate": 16000
            }
          },
          "avatar": {
            "vendor": "generic",
            "enable": true,
            "params": {
              "api_key": "<lemonslice_api_key>",
              "api_base_url": "https://lemonslice.com/api/liveai/agora",
              "avatar_id": "lemonslice",
              "agent_image_url": "<public_image_url>",
              "video_encoding": "H264",
              "agora_uid": "3000",
              "agora_token": "<avatar_rtc_token>"
            }
          }
        }
      }'
    ```

    Store the `agent_id` returned by Agora — you will need it to stop the session. `agent_rtc_uid`, the user UID in `remote_rtc_uids`, and `avatar.params.agora_uid` must all be different.
  </Step>

  <Step title="Subscribe to the avatar in your frontend">
    The end user joins the same Agora channel and subscribes to the LemonSlice avatar UID (`agora_uid`) for audio and video. Agora's agent handles ASR → LLM → TTS; LemonSlice lip-syncs the TTS audio and publishes the avatar tracks.
  </Step>

  <Step title="Shutdown the session">
    Stop the Agora agent with Agora's `/leave` API. Agora tears down the LemonSlice session together with the agent:

    ```bash theme={null}
    curl --request POST \
      --url "https://api.agora.io/api/conversational-ai-agent/v2/projects/$AGORA_APP_ID/agents/$AGENT_ID/leave" \
      --header "Authorization: Basic $AGORA_BASIC_AUTH"
    ```

    <Warning>
      If the LemonSlice session is not shut down, it will remain active until the configured idle timeout is reached.
    </Warning>
  </Step>
</Steps>
