Recordings
Smart Recording records each call from the moment the lead is connected to the agent. In all-party consent states only the agent side is recorded until the lead gives consent. Use this resource to read and download recordings, mark consent, pause and resume during a call, and set retention. Recordings are kept for 1 year by default and are never used to train models.
Guide: Smart Recording.
Endpoints
| GET | /v1/recordings/{id} | Retrieve a recording |
| GET | /v1/recordings | List recordings |
| GET | /v1/recordings/{id}/audio | Download the audio |
| DELETE | /v1/recordings/{id} | Delete a recording |
| POST | /v1/calls/{id}/recording/pause | Pause recording |
| POST | /v1/calls/{id}/recording/resume | Resume recording |
| POST | /v1/calls/{id}/recording/consent | Mark consent |
| GET | /v1/recording_settings | Retrieve recording settings |
| PATCH | /v1/recording_settings | Update recording settings |
| POST | /v1/retention_rules | Create a retention rule |
| GET | /v1/retention_rules | List retention rules |
| DELETE | /v1/retention_rules/{id} | Delete a retention rule |
The recording object
| Field | Type | Description |
|---|---|---|
id | string | Unique ID, starts with rec_. |
call_id | string | The call that was recorded. |
status | string | in_progress during the call, ready after hang-up, deleted after deletion. |
lead_state | string | null | The lead state used for the consent rule. Null when unknown. |
rule | string | one_party or all_party. Leads with no known state are all_party. |
sides | string | What is recorded now, or at hang-up: none, agent or both. |
duration_seconds | integer | Length of the audio. |
channels | object | Agent on the left channel, prospect on the right. |
sides_timeline | object[] | from_ms and sides for each change: consent, pause or resume. |
consent | object | null | rule, method, consented_by and at_ms on all-party calls where consent was given. |
consent_audio_url | string | null | The audio of the lead giving consent. Needs your API key. |
redactions | integer | Spoken card numbers removed from the audio and transcript. |
delete_after | string | The date the recording is deleted, from the retention setting or a retention rule. |
url | string | The audio file. Needs your API key. |
created_at | string | When recording started, ISO 8601. |
Retrieve a recording
Returns one recording with its consent details and the sides recorded over time.
GET/v1/recordings/{id}
curl https://api.liveleg.dev/v1/recordings/rec_0Hy3k \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/recordings/rec_0Hy3k', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.get(
"https://api.liveleg.dev/v1/recordings/rec_0Hy3k",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "rec_0Hy3k",
"object": "recording",
"call_id": "cal_8Jq2mT4x",
"status": "ready",
"lead_state": "FL",
"rule": "all_party",
"sides": "both",
"duration_seconds": 262,
"channels": {
"left": "agent",
"right": "prospect"
},
"sides_timeline": [
{
"from_ms": 0,
"sides": "agent"
},
{
"from_ms": 5660,
"sides": "both"
}
],
"consent": {
"rule": "all_party",
"method": "agent_ask",
"consented_by": "Dana Ruiz",
"at_ms": 5660
},
"consent_audio_url": "https://api.liveleg.dev/v1/recordings/rec_0Hy3k/consent_audio",
"redactions": 1,
"delete_after": "2027-11-03",
"url": "https://api.liveleg.dev/v1/recordings/rec_0Hy3k/audio",
"created_at": "2026-11-03T15:42:07Z"
} List recordings
Returns recordings, newest first.
GET/v1/recordings
| Query parameters | Type | Description |
|---|---|---|
call_id | string | Only the recording of this call. |
dial_session_id | string | Only calls from this dial session. |
agent_id | string | Only calls taken by this agent. |
rule | string | one_party or all_party. |
created_after | string | ISO 8601. |
created_before | string | ISO 8601. |
limit | integer | 1 to 100. Default 20. |
starting_after | string | The last ID from the previous page. |
curl "https://api.liveleg.dev/v1/recordings?agent_id=agt_114&created_after=2026-11-03T00%3A00%3A00Z&limit=20" \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/recordings?agent_id=agt_114&created_after=2026-11-03T00%3A00%3A00Z&limit=20', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.get(
"https://api.liveleg.dev/v1/recordings",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
params={
"agent_id": "agt_114",
"created_after": "2026-11-03T00:00:00Z",
"limit": 20,
},
).json() {
"object": "list",
"data": [
{
"id": "rec_0Hy3k",
"object": "recording",
"call_id": "cal_8Jq2mT4x",
"status": "ready",
"lead_state": "FL",
"rule": "all_party",
"sides": "both",
"duration_seconds": 262,
"channels": {
"left": "agent",
"right": "prospect"
},
"sides_timeline": [
{
"from_ms": 0,
"sides": "agent"
},
{
"from_ms": 5660,
"sides": "both"
}
],
"consent": {
"rule": "all_party",
"method": "agent_ask",
"consented_by": "Dana Ruiz",
"at_ms": 5660
},
"consent_audio_url": "https://api.liveleg.dev/v1/recordings/rec_0Hy3k/consent_audio",
"redactions": 1,
"delete_after": "2027-11-03",
"url": "https://api.liveleg.dev/v1/recordings/rec_0Hy3k/audio",
"created_at": "2026-11-03T15:42:07Z"
}
],
"has_more": false
} Download the audio
Returns the audio file with the agent on the left channel and the prospect on the right. With redirect=false you get a download link that works without your key for 1 hour.
GET/v1/recordings/{id}/audio
| Query parameters | Type | Description |
|---|---|---|
format | string | mp3 or wav. Default mp3. |
redirect | boolean | false returns a JSON download link in place of the file. Default true. |
curl "https://api.liveleg.dev/v1/recordings/rec_0Hy3k/audio?format=wav&redirect=false" \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/recordings/rec_0Hy3k/audio?format=wav&redirect=false', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.get(
"https://api.liveleg.dev/v1/recordings/rec_0Hy3k/audio",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
params={
"format": "wav",
"redirect": False,
},
).json() {
"object": "recording_audio",
"recording_id": "rec_0Hy3k",
"format": "wav",
"url": "https://files.liveleg.dev/rec_0Hy3k.wav?token=f3a91c",
"expires_at": "2026-11-03T17:02:00Z"
} Delete a recording
Deletes the audio, the consent audio and the transcript. The call record stays. recording.deleted is sent with reason requested. Deleted recordings and transcripts are removed from our systems, except where the law requires us to keep a copy.
DELETE/v1/recordings/{id}
curl -X DELETE https://api.liveleg.dev/v1/recordings/rec_0Hy3k \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/recordings/rec_0Hy3k', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.delete(
"https://api.liveleg.dev/v1/recordings/rec_0Hy3k",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "rec_0Hy3k",
"object": "recording",
"status": "deleted",
"deleted_at": "2026-11-04T09:12:03Z"
} Pause recording
Stops recording both sides on a live call, for example while a card number is read out. recording.sides_changed is sent.
POST/v1/calls/{id}/recording/pause
curl -X POST https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/pause \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/pause', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.post(
"https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/pause",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "rec_0Hy3k",
"object": "recording",
"call_id": "cal_8Jq2mT4x",
"status": "in_progress",
"sides": "none"
} Resume recording
Starts recording again with the same sides as before the pause. recording.sides_changed is sent.
POST/v1/calls/{id}/recording/resume
curl -X POST https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/resume \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/resume', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.post(
"https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/resume",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "rec_0Hy3k",
"object": "recording",
"call_id": "cal_8Jq2mT4x",
"status": "in_progress",
"sides": "both"
} Mark consent
Marks that the lead agreed to be recorded on an all-party call. Both sides are recorded from that moment. We store who consented, when, and the audio of the consent. If the lead says no, do not call this endpoint. Their side is not recorded on that call.
POST/v1/calls/{id}/recording/consent
| Body parameters | Type | Description |
|---|---|---|
consented_byrequired | string | Who gave consent, usually the lead's name as they said it. |
methodrequired | string | announcement or agent_ask. How consent was asked for. |
at_ms | integer | Milliseconds from the bridge when consent was given. Defaults to the time of the request. |
curl https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/consent \
-H "Authorization: Bearer $LIVELEG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"consented_by": "Dana Ruiz",
"method": "agent_ask"
}'const res = await fetch('https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/consent', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
consented_by: "Dana Ruiz",
method: "agent_ask"
}),
});
const data = await res.json();import os, requests
data = requests.post(
"https://api.liveleg.dev/v1/calls/cal_8Jq2mT4x/recording/consent",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
json={
"consented_by": "Dana Ruiz",
"method": "agent_ask",
},
).json() {
"object": "recording_consent",
"recording_id": "rec_0Hy3k",
"call_id": "cal_8Jq2mT4x",
"consented_by": "Dana Ruiz",
"method": "agent_ask",
"marked_by": "api",
"at_ms": 5660,
"sides": "both",
"consent_audio_url": "https://api.liveleg.dev/v1/recordings/rec_0Hy3k/consent_audio"
} Retrieve recording settings
Returns the recording, transcription and retention settings of the account.
GET/v1/recording_settings
curl https://api.liveleg.dev/v1/recording_settings \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/recording_settings', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.get(
"https://api.liveleg.dev/v1/recording_settings",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"object": "recording_settings",
"mode": "smart",
"consent_rule": "by_lead_location",
"consent_method": "agent_ask",
"announcement_id": null,
"before_consent": "agent_side",
"redact": "payment_card",
"retention_days": 365,
"transcription": "post_call",
"tonality": false
} Update recording settings
Changes the settings for new calls. Calls in progress keep the settings they started with.
PATCH/v1/recording_settings
| Body parameters | Type | Description |
|---|---|---|
mode | string | smart or off. smart records from the moment the lead is connected to the agent. Default smart. |
consent_rule | string | by_lead_location applies the rule for the lead's state. all_party treats every call as all-party. Default by_lead_location. |
consent_method | string | agent_ask or announcement. How consent is asked for on all-party calls. announcement plays only to leads whose consent record has recorded_voice true; other leads get agent_ask. Default agent_ask. |
announcement_id | string | Your recorded consent announcement. A standard one is used if you leave it out. |
before_consent | string | agent_side or none. What is recorded on an all-party call before consent. Default agent_side. |
redact | string | payment_card removes spoken card numbers from the audio and the transcript. |
retention_days | integer | 30 to 3653 (10 years). Default 365. |
transcription | string | off, post_call or live. Default off. |
tonality | boolean | Tonality analysis on transcribed calls. Default false. |
curl -X PATCH https://api.liveleg.dev/v1/recording_settings \
-H "Authorization: Bearer $LIVELEG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "smart",
"consent_rule": "by_lead_location",
"consent_method": "agent_ask",
"redact": "payment_card",
"transcription": "post_call"
}'const res = await fetch('https://api.liveleg.dev/v1/recording_settings', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
mode: "smart",
consent_rule: "by_lead_location",
consent_method: "agent_ask",
redact: "payment_card",
transcription: "post_call"
}),
});
const data = await res.json();import os, requests
data = requests.patch(
"https://api.liveleg.dev/v1/recording_settings",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
json={
"mode": "smart",
"consent_rule": "by_lead_location",
"consent_method": "agent_ask",
"redact": "payment_card",
"transcription": "post_call",
},
).json() {
"object": "recording_settings",
"mode": "smart",
"consent_rule": "by_lead_location",
"consent_method": "agent_ask",
"announcement_id": null,
"before_consent": "agent_side",
"redact": "payment_card",
"retention_days": 365,
"transcription": "post_call",
"tonality": false
} Create a retention rule
Keeps the recordings and transcripts of one campaign or lead list for a different time than the account setting. Medicare sales calls must be kept 6 years and collections calls 3 years. When more than one rule matches a call, the longest one applies. A new rule also applies to recordings you already have.
POST/v1/retention_rules
| Body parameters | Type | Description |
|---|---|---|
namerequired | string | A name for your own use. |
retention_daysrequired | integer | 30 to 3653 (10 years). |
campaign_id | string | Calls in this campaign. Send campaign_id or lead_list_id. |
lead_list_id | string | Calls to leads on this list. |
curl https://api.liveleg.dev/v1/retention_rules \
-H "Authorization: Bearer $LIVELEG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Medicare sales",
"campaign_id": "cmp_medicare_aep",
"retention_days": 2190
}'const res = await fetch('https://api.liveleg.dev/v1/retention_rules', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: "Medicare sales",
campaign_id: "cmp_medicare_aep",
retention_days: 2190
}),
});
const data = await res.json();import os, requests
data = requests.post(
"https://api.liveleg.dev/v1/retention_rules",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
json={
"name": "Medicare sales",
"campaign_id": "cmp_medicare_aep",
"retention_days": 2190,
},
).json() {
"id": "rtr_4Bm81Sv",
"object": "retention_rule",
"name": "Medicare sales",
"campaign_id": "cmp_medicare_aep",
"lead_list_id": null,
"retention_days": 2190,
"created_at": "2026-11-03T18:22:40Z"
} List retention rules
Returns the retention rules of the account.
GET/v1/retention_rules
curl https://api.liveleg.dev/v1/retention_rules \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/retention_rules', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.get(
"https://api.liveleg.dev/v1/retention_rules",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"object": "list",
"data": [
{
"id": "rtr_4Bm81Sv",
"object": "retention_rule",
"name": "Medicare sales",
"campaign_id": "cmp_medicare_aep",
"lead_list_id": null,
"retention_days": 2190,
"created_at": "2026-11-03T18:22:40Z"
},
{
"id": "rtr_4Bm93Kd",
"object": "retention_rule",
"name": "Roofing leads TX",
"campaign_id": null,
"lead_list_id": "lst_roofing_tx",
"retention_days": 730,
"created_at": "2026-11-03T18:25:02Z"
}
],
"has_more": false
} Delete a retention rule
Deletes a rule. The matching recordings go back to the account retention setting, counted from the day each call was recorded. Recordings older than that are then deleted.
DELETE/v1/retention_rules/{id}
curl -X DELETE https://api.liveleg.dev/v1/retention_rules/rtr_4Bm93Kd \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/retention_rules/rtr_4Bm93Kd', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
},
});
const data = await res.json();import os, requests
data = requests.delete(
"https://api.liveleg.dev/v1/retention_rules/rtr_4Bm93Kd",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "rtr_4Bm93Kd",
"object": "retention_rule",
"deleted": true
}