Dial sessions
A dial session calls a lead list for one agent or a pool of agents, up to 5 lines per agent at a time. The first live person who answers is connected to the agent and the other lines are dropped. Every lead passes the pre-dial checks before it is dialed.
Guide: Dial sessions.
Endpoints
| POST | /v1/dial_sessions | Start a dial session |
| GET | /v1/dial_sessions/{id} | Retrieve a dial session |
| GET | /v1/dial_sessions | List dial sessions |
| POST | /v1/dial_sessions/{id}/pause | Pause a dial session |
| POST | /v1/dial_sessions/{id}/resume | Resume a dial session |
| POST | /v1/dial_sessions/{id}/stop | Stop a dial session |
The dial_session object
| Field | Type | Description |
|---|---|---|
id | string | Unique ID, starts with dls_. |
status | string | running, paused or stopped. |
livemode | boolean | false for sessions started with a test key. |
agent_id | string | null | The agent who takes the calls. |
agent_pool_id | string | null | The pool that shares the calls, when set instead of agent_id. |
lead_list_id | string | The list being dialed. |
campaign_id | string | The campaign the abandonment rate is counted for. |
lines | auto | 1-5 | Lines per agent as requested. |
max_lines | integer | Upper limit when lines is auto. |
current_lines | integer | Lines per agent in the current round. 1 while the campaign is at the abandonment cap. |
caller_id_pool | string | The pool caller IDs are picked from. |
amd | boolean | Answering machine detection. |
recording | smart | off | Smart Recording. |
transcription | off | post_call | live | Transcripts for bridged calls. |
ivr | object | null | Phone tree navigation defaults for the session. |
metadata | object | Your keys. Returned on every event for the session. |
totals | object | dialed, answered, bridged and blocked counts so far. |
stop_reason | string | null | requested, agent_idle, list_empty or calling_hours_closed. Set when the session stops. |
created_at | string | When the session started, ISO 8601. |
stopped_at | string | null | When the session stopped. |
Start a dial session
Starts dialing a lead list for one agent or a pool. The agent must be connected in the browser or on a SIP phone. With an Idempotency-Key, a retry returns the first session.
POST/v1/dial_sessions
| Body parameters | Type | Description |
|---|---|---|
agent_idrequired | string | The agent who takes the calls. Use agent_pool_id instead to share one session across a pool of agents. |
agent_pool_id | string | Agents in the pool share answered calls. A second live person goes to the next free agent. |
lead_list_idrequired | string | The list to dial. Leads are dialed in list order, with scheduled callbacks first. |
lines | auto | 1-5 | Lines per agent. auto sets the count from the live answer rate and the campaign abandonment rate. Default auto. |
max_lines | integer | Upper limit when lines is auto. 1 to 5, default 5. |
caller_id_pool | string | The pool caller IDs are picked from. Each lead sees the same number on every call. |
campaign_id | string | Groups sessions for the 30-day abandonment rate. Defaults to the campaign of the lead list. |
amd | boolean | Answering machine detection. Default true. |
recording | smart | off | Smart Recording. Default smart. Consent rule, retention and redaction come from recording settings. |
transcription | off | post_call | live | Transcripts for bridged calls. Default off. |
ivr.target | string | Turns on phone tree navigation. A department (sales, owner, billing, service), a person's name, or an extension such as ext:214. Leads can override it. |
ivr.fallback | operator | any_human | none | What to try when the target is not in the menu. Default operator. |
ivr.max_hold_seconds | integer | Longest time to wait on hold before ending the line. Default 600. |
ivr.max_steps | integer | Most menu choices to make before giving up. Default 8. |
ivr.screener.enabled | boolean | Answer call screeners with the agent's recorded line. Plays only when the lead's consent record has recorded_voice true, and never on calls to Washington numbers. Default false. |
ivr.screener.line | string | Who is calling, the business, why, and a callback number. Placeholders: {agent_first_name}, {company}, {reason}, {callback_number}. |
metadata | object | Up to 20 keys. Returned on every event for the session. |
curl https://api.liveleg.dev/v1/dial_sessions \
-H "Authorization: Bearer $LIVELEG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_114",
"lead_list_id": "lst_roofing_tx",
"lines": "auto",
"caller_id_pool": "pool_local_presence",
"amd": true,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600
},
"metadata": {
"crm_team": "austin"
}
}'const res = await fetch('https://api.liveleg.dev/v1/dial_sessions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
agent_id: "agt_114",
lead_list_id: "lst_roofing_tx",
lines: "auto",
caller_id_pool: "pool_local_presence",
amd: true,
recording: "smart",
transcription: "post_call",
ivr: {
target: "owner",
fallback: "operator",
max_hold_seconds: 600
},
metadata: {
crm_team: "austin"
}
}),
});
const data = await res.json();import os, requests
data = requests.post(
"https://api.liveleg.dev/v1/dial_sessions",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
json={
"agent_id": "agt_114",
"lead_list_id": "lst_roofing_tx",
"lines": "auto",
"caller_id_pool": "pool_local_presence",
"amd": True,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600,
},
"metadata": {
"crm_team": "austin",
},
},
).json() {
"id": "dls_31Ka9",
"object": "dial_session",
"status": "running",
"livemode": true,
"agent_id": "agt_114",
"agent_pool_id": null,
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"lines": "auto",
"max_lines": 5,
"current_lines": 3,
"caller_id_pool": "pool_local_presence",
"amd": true,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600,
"max_steps": 8,
"screener": {
"enabled": false
}
},
"metadata": {
"crm_team": "austin"
},
"totals": {
"dialed": 0,
"answered": 0,
"bridged": 0,
"blocked": 0
},
"stop_reason": null,
"created_at": "2026-11-03T14:00:02.118Z",
"stopped_at": null
} Retrieve a dial session
Returns the session with its current line count and totals.
GET/v1/dial_sessions/{id}
curl https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9 \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9', {
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/dial_sessions/dls_31Ka9",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "dls_31Ka9",
"object": "dial_session",
"status": "running",
"livemode": true,
"agent_id": "agt_114",
"agent_pool_id": null,
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"lines": "auto",
"max_lines": 5,
"current_lines": 4,
"caller_id_pool": "pool_local_presence",
"amd": true,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600,
"max_steps": 8,
"screener": {
"enabled": false
}
},
"metadata": {
"crm_team": "austin"
},
"totals": {
"dialed": 212,
"answered": 41,
"bridged": 33,
"blocked": 9
},
"stop_reason": null,
"created_at": "2026-11-03T14:00:02.118Z",
"stopped_at": null
} List dial sessions
Returns dial sessions, newest first.
GET/v1/dial_sessions
| Query parameters | Type | Description |
|---|---|---|
status | string | running, paused or stopped. |
agent_id | string | Sessions for this agent. |
lead_list_id | string | Sessions for this list. |
campaign_id | string | Sessions in this campaign. |
limit | integer | 1 to 100. Default 20. |
starting_after | string | The last ID from the previous page. |
curl "https://api.liveleg.dev/v1/dial_sessions?status=running&campaign_id=cmp_roofing_q4" \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/dial_sessions?status=running&campaign_id=cmp_roofing_q4', {
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/dial_sessions",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
params={
"status": "running",
"campaign_id": "cmp_roofing_q4",
},
).json() {
"object": "list",
"data": [
{
"id": "dls_31Ka9",
"object": "dial_session",
"status": "running",
"agent_id": "agt_114",
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"current_lines": 4,
"totals": {
"dialed": 212,
"answered": 41,
"bridged": 33,
"blocked": 9
},
"created_at": "2026-11-03T14:00:02.118Z"
},
{
"id": "dls_31Kb2",
"object": "dial_session",
"status": "running",
"agent_id": "agt_207",
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"current_lines": 3,
"totals": {
"dialed": 148,
"answered": 26,
"bridged": 21,
"blocked": 4
},
"created_at": "2026-11-03T14:01:40.502Z"
}
],
"has_more": false
} Pause a dial session
Lets the lines that are already ringing finish and places no new ones. The agent stays connected. Sends dial_session.paused.
POST/v1/dial_sessions/{id}/pause
| Body parameters | Type | Description |
|---|---|---|
reason | string | Your own note, for example break. Returned on dial_session.paused. |
curl https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/pause \
-H "Authorization: Bearer $LIVELEG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "break"
}'const res = await fetch('https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/pause', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LIVELEG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
reason: "break"
}),
});
const data = await res.json();import os, requests
data = requests.post(
"https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/pause",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
json={
"reason": "break",
},
).json() {
"id": "dls_31Ka9",
"object": "dial_session",
"status": "paused",
"livemode": true,
"agent_id": "agt_114",
"agent_pool_id": null,
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"lines": "auto",
"max_lines": 5,
"current_lines": 0,
"caller_id_pool": "pool_local_presence",
"amd": true,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600,
"max_steps": 8,
"screener": {
"enabled": false
}
},
"metadata": {
"crm_team": "austin"
},
"totals": {
"dialed": 212,
"answered": 41,
"bridged": 33,
"blocked": 9
},
"stop_reason": null,
"created_at": "2026-11-03T14:00:02.118Z",
"stopped_at": null
} Resume a dial session
Starts dialing again from the next lead in the list. Sends dial_session.resumed.
POST/v1/dial_sessions/{id}/resume
curl -X POST https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/resume \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/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/dial_sessions/dls_31Ka9/resume",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "dls_31Ka9",
"object": "dial_session",
"status": "running",
"livemode": true,
"agent_id": "agt_114",
"agent_pool_id": null,
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"lines": "auto",
"max_lines": 5,
"current_lines": 3,
"caller_id_pool": "pool_local_presence",
"amd": true,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600,
"max_steps": 8,
"screener": {
"enabled": false
}
},
"metadata": {
"crm_team": "austin"
},
"totals": {
"dialed": 212,
"answered": 41,
"bridged": 33,
"blocked": 9
},
"stop_reason": null,
"created_at": "2026-11-03T14:00:02.118Z",
"stopped_at": null
} Stop a dial session
Ends the session and returns the totals. A call that is already bridged continues until it ends. A stopped session cannot be resumed. Start a new one on the same list to continue.
POST/v1/dial_sessions/{id}/stop
curl -X POST https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/stop \
-H "Authorization: Bearer $LIVELEG_API_KEY"const res = await fetch('https://api.liveleg.dev/v1/dial_sessions/dls_31Ka9/stop', {
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/dial_sessions/dls_31Ka9/stop",
headers={"Authorization": f"Bearer {os.environ['LIVELEG_API_KEY']}"},
).json() {
"id": "dls_31Ka9",
"object": "dial_session",
"status": "stopped",
"livemode": true,
"agent_id": "agt_114",
"agent_pool_id": null,
"lead_list_id": "lst_roofing_tx",
"campaign_id": "cmp_roofing_q4",
"lines": "auto",
"max_lines": 5,
"current_lines": 0,
"caller_id_pool": "pool_local_presence",
"amd": true,
"recording": "smart",
"transcription": "post_call",
"ivr": {
"target": "owner",
"fallback": "operator",
"max_hold_seconds": 600,
"max_steps": 8,
"screener": {
"enabled": false
}
},
"metadata": {
"crm_team": "austin"
},
"totals": {
"dialed": 486,
"answered": 92,
"bridged": 74,
"blocked": 17
},
"stop_reason": "requested",
"created_at": "2026-11-03T14:00:02.118Z",
"stopped_at": "2026-11-03T17:58:31.044Z"
}