Recordings
Every session is recorded unless you turn recording off: the avatar’s picture, the character’s voice and the end user’s voice, in one MP4, from the avatar’s first frame to the end of the call.
A recording is kept for 7 days, then removed. You can delete it sooner. In the console it plays on the session’s own page (Sessions, then a session), beside the conversation.
Telling the people on a call that it is recorded, and getting the consent your law asks for, is up to you. If you would rather not record, turn it off.
Turn recording off
Recording is a choice you make for each session, when you create it:
const res = await fetch("https://api.avatargo.ai/v1/auth/session-token", {
method: "POST",
headers: { authorization: `Bearer ${process.env.AVATARGO_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({ characterId, sessionOptions: { recording: false } }),
});A session created this way has no recording: its recording is null.
Get a recording
A session says where its recording stands (GET /v1/sessions/{id}, and each item of
GET /v1/sessions):
{
"id": "se_d8Kq1wZt7Hc3Nf0P",
"status": "ended",
"recording": {
"status": "ready",
"startedAt": "2026-11-13T18:06:39.610Z",
"durationSeconds": 134.2,
"bytes": 11468032,
"width": 768,
"height": 512,
"expiresAt": "2026-11-20T18:09:02.000Z"
}
}recording.status | What it means |
|---|---|
recording | The call has not ended yet. |
processing | The call ended; the file is on its way. |
ready | The file can be fetched. |
failed | Nothing could be saved for this call. |
expired | It was removed after its 7 days. |
deleted | You deleted it. |
More may be added: treat a status you do not know as not ready.
The file arrives shortly after the call ends. To be told when, subscribe a
webhook endpoint to recording.ready: it is sent once, when the
recording becomes ready, and its data is the session as above. Once it is ready, ask for a
link to it:
async function recordingUrl(sessionId) {
const res = await fetch(`https://api.avatargo.ai/v1/sessions/${sessionId}/recording`, {
headers: { authorization: `Bearer ${process.env.AVATARGO_API_KEY}` },
});
if (res.status === 409) return null; // recording_not_ready: ask again in a few seconds
const json = await res.json();
if (!res.ok) throw new Error(`${json.error.code}: ${json.error.message}`);
return json.recordingUrl; // an MP4: play it in a <video>, or download it
}The link works for an hour (recordingUrlExpiresAt). Do not store it: ask again for a fresh one.
| Answer | When |
|---|---|
200 | The recording, with recordingUrl. |
404 not_found | No such session, or it has no recording: recording was off, or nothing could be saved. |
409 recording_not_ready | The call is still going, or the file has not arrived yet. |
410 recording_gone | It was deleted, or removed after its 7 days. |
Line it up with the transcript
recording.startedAt is the moment of the recording’s first frame. Each line of the transcript
(GET /v1/sessions/{id}/transcript) has at, when it began to be spoken, and endedAt, when it
stopped (null when that is not known). A line’s place in the video, in seconds:
const seconds = (Date.parse(line.at) - Date.parse(session.recording.startedAt)) / 1000;
video.currentTime = Math.max(0, seconds);Delete a recording
await fetch(`https://api.avatargo.ai/v1/sessions/${sessionId}/recording`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.AVATARGO_API_KEY}` },
});Only the video goes, for good: the session, its transcript, its measurements and its usage stay.
204 when it is gone — also for one already deleted or expired; 409 recording_not_ready while
the file has not arrived yet.
Every field is in the API reference, under Sessions.