Skip to main content
simli-ai runs Simli sessions from Python. You send the audio the avatar should speak, and get back its lip-synced video and audio as PyAV frames, to save to a file, show in a window or process however you like.
Building a voice agent? LiveKit Agents and Pipecat have Simli integrations that handle the audio and video for you.

What you need

The SDK runs where your API key is safe, so there’s no session token step.

Install

To show the avatar in a window with LocalRenderer, install the local extra instead: pip install "simli-ai[local]".

1. Start a session

Replace "YOUR_SIMLI_API_KEY" with your Simli API key. To use another avatar, replace the face ID with one from your dashboard or the default faces. For the video size, the avatar’s position, the camera and backgrounds, see Trinity-2. async with starts the session and stops it when the block ends. Without it, call await connection.start() first and await connection.stop() when you’re done.

2. Send audio

send() takes raw PCM16 audio, 16 kHz, mono, as bytes. It plays after any audio already queued.
handleSilence in SimliConfig (default True) decides what Simli does when your audio runs out. With True, Simli fills the gaps with silence, so the avatar keeps moving between sentences. Set it to False when you stream continuous audio that already has its own silences: Simli then plays only the audio you send, and the video freezes when you stop sending.

3. Get the video and audio

The renderers in simli.renderers.renderers take the stream for you:
  • FileRenderer(connection) writes it to output.mp4.
  • LocalRenderer(connection) shows it in a window and plays it on your speakers. It needs the local extra and a display.
  • NDArrayRenderer(connection) returns the video and audio as NumPy arrays once the session ends.
To handle the frames yourself, iterate over them:
getAudioStreamIterator() does the same for audio. Run the two loops as separate tasks to receive both at once.

Errors and retries

start() returns once Simli has started the session. If it can’t, it raises one of these exceptions, all exported from simli and all subclasses of SimliError:
  • SimliAPIError: a request to the Simli API failed, for example an invalid API key, an unknown face ID or no minutes left. status_code and detail hold the HTTP status and Simli’s message.
  • SimliSessionError: Simli refused the session, for example an expired session token or the rate limit. Also a message from Simli the SDK doesn’t recognise, sent while the session is starting. That one is logged as Unknown error from Simli: <message>, and its code is UNKNOWN_ERROR.
  • SimliConnectionError: the network failed. A request or the websocket couldn’t connect, timed out or dropped.
start() retries only network failures: SimliConnectionError and HTTP 5xx responses. It tries up to retry_count times in all (3 by default), with exponential backoff: it waits 1, 2, 4 and 8 seconds before the first four retries, then 16 seconds before each one after that, each wait plus a little random jitter. Everything else raises at once.
Once the session has started, a message the SDK doesn’t recognise no longer ends it: it’s logged as a warning on the simli_client logger. Once the session has ended, connection.stopReason holds the reason Simli gave (such as "IDLE" or "MAX"), connection.error holds the error that ended it, if one did, and send() raises instead of failing silently.

Next steps

Trinity-2

Video size, the avatar’s position, the camera, backgrounds and foregrounds.

API reference

Every class, method, event and exception.
Questions? Ask on Discord, or fork simli-ai for your own use case.