API reference / Engine
Engine
The SDK handles signalling and media transport. Use these endpoints when implementing a compatible transport or diagnosing a connection.
| Method | Path | Purpose | Credential |
|---|---|---|---|
| POST | /connect | Exchange an SDP offer for a persistent live stream | API key or streaming token |
| POST | /offer | Lip sync a named audio file | API key or streaming token |
| GET | /health | Service liveness | Public |
| GET | /api/health | The same as /health, through your site domain | Public |
| GET | /api/stats | Runtime diagnostics | Full API key |
Open the live stream
Opens the one persistent WebRTC session. The avatar idles on a silence clip and replies stream straight into the same connection, so there is no reconnect per message.
Opening a session closes any prior one, along with any one shot /offer
sessions. One avatar server, one live session, by design.
Your WebRTC offer.
The offer's type, normally offer.
Which avatar to stream. Falls back to this caller's saved avatar, then to the avatar server's active one.
An explicit idle clip. When you set this, it wins over the automatic choice.
Sanitized facts about the person, such as their timezone and their name, for this session only. Validated field by field and dropped field by field on failure, so a malformed payload costs a nicety rather than the session. Nothing here is persisted.
{
"sdp": "v=0\r\no=- ...",
"type": "answer",
"avatar": "01-presenter-male",
"silence": "01-presenter-male__silence",
"idle_stand_in": false
}idle_stand_in is true when the idle face had to borrow somebody else's,
because no prepared silent clip existed for the avatar you asked for. It is
worth surfacing: the viewer sees one person idle and a different one speak.
One shot lip sync
Lip syncs an already uploaded audio file into a fresh WebRTC stream. There is
no script and no text to speech in this path: upload the audio first with
POST /api/upload, then name it here.
Filename of an uploaded audio asset. Falls back to the avatar server's default clip. An
unknown name is a 404.
Which avatar to render.
An explicit tone. Without one, and with emotion_responsive on,
the tone is inferred from the audio.
Whether to infer a tone from the audio. Defaults to this caller's setting, then the avatar server's.
Your WebRTC offer.
The offer's type.
{
"sdp": "v=0\r\no=- ...",
"type": "answer",
"avatar": "01-presenter-male__warm",
"emotion": "warm",
"transcript": "Thanks for waiting."
}transcript is what the emotion inference heard, and is empty when the tone was
given explicitly.
Box health
The only route besides the page shell and static assets that takes no
credential. Use it as a liveness probe. GET /api/health answers the same
body, and is the one to call through your site domain, which forwards /api/*
to the box but not /health.
{
"status": "ok",
"avatar": "01-presenter-male",
"speaking_face": "01-presenter-male__confident"
}Two facts, not one. avatar is the identity the user picked; speaking_face is
the concrete clip playing right now, which changes every time a reply picks a
tone. Conflating them reports a tone nobody chose.
Runtime stats
Requires a full key, and it is the only GET on the avatar server that does, because
the payload describes the machine rather than the product.
{
"shutdown_minutes": 74,
"cpu_percent": 12.4,
"cpu_cores": 16,
"gpus": [{ "name": "NVIDIA L4", "memory_used_mb": 9214, "utilization": 61 }]
}shutdown_minutes counts down to the avatar server's self termination and is null when
no shutdown is scheduled. It is the field to watch: an avatar server that is about to go is
about to take every live session with it.
Engine provisioning and administrative lifecycle controls are covered in the operator guide.