Overview
A call is the metadata of a phone call, or of a web voice session, linked to a lead: its direction, when it started, how long it lasted, and how it ended. Recordings, transcripts and summaries are never exported. The caller's name and number travel on the linked lead, not on the call.
outcome says how the call ended: answered_human, answered_ai, voicemail, no_answer, busy, failed, or unknown when the call is still live or nothing shows who answered. Read it together with outcome_basis, which names the evidence behind it:
outcome_basis | The outcome rests on |
|---|---|
inbound_verdict | Totem's classification of an inbound call. |
ai_analysis | Totem's classification of the status, end reason and length that Retell reports. |
duration_floor | The length of a call on a human line: one of at least 10 seconds counts as answered. |
carrier_answer_only | Only the carrier's answer signal. It never counts as answered, so a connected call reads unknown. |
browser_session | A web voice session with the assistant. |
none | No evidence. |
Which basis a call gets depends on how it was placed. Inbound calls on Totem's phone lines get inbound_verdict, or carrier_answer_only when Totem has not classified them. Every outbound call on Totem's phone lines, whether the AI or a person made it, gets carrier_answer_only, so a connected outbound call reads unknown. Calls handled through the Retell voice platform get ai_analysis, and calls on a connected Zadarma PBX get duration_floor. A web voice session gets browser_session, and a call that is still live gets none. A lead's last_answered_call_at counts only answered_human and answered_ai, so it leaves out connected outbound calls on Totem's phone lines.
duration_seconds is rounded down to whole seconds, and is null while the call is still live. lead is null when the call is not linked to a lead, or when the lead no longer exists.
Use GET /v1/calls and GET /v1/calls/{id} to look calls up; GET /v1/calls?lead= lists one lead's calls. To keep a copy, follow the changes feed, which delivers every new call and every change: Keep a copy in sync explains it.
GET /
Returns a page of the team's calls, each with its direction, start time, duration and a normalized outcome, and linked to its lead when there is one. Pass lead for one lead's calls. Recordings and transcripts are not exported.
Query parameters
limitinteger Range 1–100 Default25Items per page, 1–100. Defaults to 25.
cursorstring 1–512 charsThe
next_cursorof the previous page. Omit it for the first page.leadstring ID prefixlead_…Only the calls linked to this lead: every item's
leadis this id. A lead of another team, or one that does not exist, matches nothing.
Headers
Totem-Teamstring Conditional ID prefixteam_…The team to read, as a
team_…id. Omit it when the key reads one team; it is required when the key reads several (400 team_required). When you send it, it must name a team the key reads: a malformed id gets400 invalid_request, and a team outside the key gets404 team_not_accessible, as does a request without it once the key reads no team at all.
Returns
Returns a list of Call objects.
objectstringAlways
list.dataArray<Call>The items of this page.
has_morebooleantruewhen another page follows: fetch it withnext_cursor, even if this page holds fewer items thanlimit.next_cursorstring NullableOpaque cursor for the next page, or null on the last page. Never parse it.
Errors
- 400
team_requiredTeam required - 403
team_state_restrictedTeam restricted - 403
sector_restrictedSector restricted - 404
team_not_accessibleTeam not accessible - 409
capture_not_readyTeam data is still being prepared - 429
quota_exceededDaily quota exceeded
curl 'https://api.totemstudio.ai/v1/calls?limit=25' \
-H "Authorization: Bearer $TOTEM_API_KEY" \
-H "Totem-Team: $TOTEM_TEAM_ID"{
"object": "list",
"data": [
{
"id": "call_m2kUbFcayHlZ5Lgs9xZNmDS3c3Jvk",
"object": "call",
"livemode": false,
"team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
"lead": "lead_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMXKSF0QbLS8CiUKJpEP34LFQG",
"direction": "inbound",
"started_at": "2026-09-28T10:17:00.000Z",
"duration_seconds": 184,
"outcome": "answered_ai",
"outcome_basis": "inbound_verdict",
"version": 2,
"updated_at": "2026-09-28T10:21:04.010Z"
}
],
"has_more": false,
"next_cursor": null
}GET /
Returns one call by its id. A call this key cannot read, or one that was removed, answers 404 resource_missing.
Path parameters
idstring Required ID prefixcall_…The call's public id.
Returns
Returns a Call object.
idstring ID prefixcall_…Public id of the record.
objectstringAlways
call.livemodebooleantruefor real data;falsein example data.teamstring ID prefixteam_…The team this record belongs to.
leadstring Nullable ID prefixlead_…The lead this call is linked to, or null when it is unlinked or the lead no longer exists. Identity (name, phone) travels on the lead only.
directionstring Nullableinboundoroutbound; null when not stored.Possible valuesinboundoutbound
started_atstring Nullable Formatdate-timeWhen the call started (UTC), or when it was recorded if the provider gave no start time.
duration_secondsinteger Nullable Range ≥ 0Whole seconds of the call (rounded down); null while the call is still live, or when not stored.
outcomestringHow the call ended:
answered_human,answered_ai,voicemail,no_answer,busy,failed, orunknown(still live, or no evidence of who answered). Read it withoutcome_basis.Possible valuesanswered_humananswered_aivoicemailno_answerbusyfailedunknown
outcome_basisstringThe evidence behind
outcome:inbound_verdict(Totem's classification of an inbound call on its phone lines),ai_analysis(Totem's classification of the status, end reason and length that Retell reports),duration_floor(a call on a connected Zadarma PBX, where at least 10 seconds counts as answered),carrier_answer_only(only the carrier's answer signal, which never counts as answered, so a connected call readsunknown: every outbound call on Totem's phone lines, made by the AI or by a person, and an inbound one Totem has not classified),browser_session(a web voice session with the assistant), ornone(no evidence, as for a call that is still live).Possible valuesinbound_verdictai_analysisduration_floorcarrier_answer_onlybrowser_sessionnone
versioninteger Range ≥ 1Increases every time one of the record's exported fields changes. Apply a change only when its version is greater than the one you hold.
updated_atstring Formatdate-timeWhen Totem recorded this version (UTC). It is not the time the business event happened.
Errors
- 403
team_state_restrictedTeam restricted - 403
sector_restrictedSector restricted - 404
resource_missingResource not found - 409
capture_not_readyTeam data is still being prepared
curl 'https://api.totemstudio.ai/v1/calls/call_m2kUbFcayHlZ5Lgs9xZNmDS3c3Jvk' \
-H "Authorization: Bearer $TOTEM_API_KEY"{
"id": "call_m2kUbFcayHlZ5Lgs9xZNmDS3c3Jvk",
"object": "call",
"livemode": false,
"team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
"lead": "lead_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMXKSF0QbLS8CiUKJpEP34LFQG",
"direction": "inbound",
"started_at": "2026-09-28T10:17:00.000Z",
"duration_seconds": 184,
"outcome": "answered_ai",
"outcome_basis": "inbound_verdict",
"version": 2,
"updated_at": "2026-09-28T10:21:04.010Z"
}A call: its direction, timing and a normalized outcome. No recording or transcript.
Attributes
idstring ID prefixcall_…Public id of the record.
objectstringAlways
call.livemodebooleantruefor real data;falsein example data.teamstring ID prefixteam_…The team this record belongs to.
leadstring Nullable ID prefixlead_…The lead this call is linked to, or null when it is unlinked or the lead no longer exists. Identity (name, phone) travels on the lead only.
directionstring Nullableinboundoroutbound; null when not stored.Possible valuesinboundoutbound
started_atstring Nullable Formatdate-timeWhen the call started (UTC), or when it was recorded if the provider gave no start time.
duration_secondsinteger Nullable Range ≥ 0Whole seconds of the call (rounded down); null while the call is still live, or when not stored.
outcomestringHow the call ended:
answered_human,answered_ai,voicemail,no_answer,busy,failed, orunknown(still live, or no evidence of who answered). Read it withoutcome_basis.Possible valuesanswered_humananswered_aivoicemailno_answerbusyfailedunknown
outcome_basisstringThe evidence behind
outcome:inbound_verdict(Totem's classification of an inbound call on its phone lines),ai_analysis(Totem's classification of the status, end reason and length that Retell reports),duration_floor(a call on a connected Zadarma PBX, where at least 10 seconds counts as answered),carrier_answer_only(only the carrier's answer signal, which never counts as answered, so a connected call readsunknown: every outbound call on Totem's phone lines, made by the AI or by a person, and an inbound one Totem has not classified),browser_session(a web voice session with the assistant), ornone(no evidence, as for a call that is still live).Possible valuesinbound_verdictai_analysisduration_floorcarrier_answer_onlybrowser_sessionnone
versioninteger Range ≥ 1Increases every time one of the record's exported fields changes. Apply a change only when its version is greater than the one you hold.
updated_atstring Formatdate-timeWhen Totem recorded this version (UTC). It is not the time the business event happened.
{
"id": "call_m2kUbFcayHlZ5Lgs9xZNmDS3c3Jvk",
"object": "call",
"livemode": false,
"team": "team_r9uYrIW4gSFJJ6hZQ9ip1UIpPaAD1CF7NR",
"lead": "lead_r72EfbRNUzuqORFJR0O8HxAwEXd93jGUTYMaMMXKSF0QbLS8CiUKJpEP34LFQG",
"direction": "inbound",
"started_at": "2026-09-28T10:17:00.000Z",
"duration_seconds": 184,
"outcome": "answered_ai",
"outcome_basis": "inbound_verdict",
"version": 2,
"updated_at": "2026-09-28T10:21:04.010Z"
}