curl --request GET \
--url https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"sessions": [
{
"sessionId": "25661352-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"realtimeAssistantId": "452dda41-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "a12b7e74-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"projectId": "c782a4ec-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"channel": "telephony",
"direction": "outbound",
"state": "completed",
"connected": true,
"toNumber": "+923001234567",
"fromNumber": "+924238900100",
"roomName": "call-25661352-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"participantIdentity": "callee-25661352",
"transportProvider": "twilio",
"variables": {
"source": "assistant-test"
},
"createdAt": "2026-08-16T18:55:22.677Z",
"ringingAt": "2026-08-16T18:55:30.758Z",
"connectedAt": "2026-08-16T18:55:36.927Z",
"answeredAt": "2026-08-16T18:55:37.641Z",
"endedAt": "2026-08-16T18:56:17.411Z",
"durationSec": 40
},
{
"sessionId": "138d6508-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"realtimeAssistantId": "452dda41-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "a12b7e74-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"projectId": "c782a4ec-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"channel": "web",
"direction": "inbound",
"state": "created",
"connected": false,
"outcome": "no_answer",
"roomName": "web-138d6508-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"participantIdentity": "عائشہ صدیقی",
"createdAt": "2026-08-18T05:14:25.444Z"
}
],
"nextCursor": "eyJyZWFsdGltZUFzc2lzdGFudElkIjogIjQ1MmRkYTQxLXh4eHgteHh4eC14eHh4LXh4eHh4eHh4eHh4eCIsICJzZXNzaW9uSWQiOiAiMTM4ZDY1MDgteHh4eC14eHh4LXh4eHgteHh4eHh4eHh4eHh4IiwgImNyZWF0ZWRBdCI6ICIyMDI2LTA4LTE4VDA1OjE0OjI1LjQ0NFoifQ"
}{
"message": [
"state must be one of the following values: created, dispatched, dialing, ringing, answered, active, completed, failed"
],
"error": "Bad Request",
"statusCode": 400
}{
"message": "invalid authorization",
"error": "Unauthorized",
"statusCode": 401
}{
"message": "Forbidden resource",
"error": "Forbidden",
"statusCode": 403
}{
"message": "Realtime assistant not found: 00000000-0000-4000-8000-000000000000",
"error": "Not Found",
"statusCode": 404
}List an assistant's sessions
Every web session and phone call one assistant handled, newest first. Filters are applied after each page is read, so a page can come back short or even empty with more behind it — keep paging until nextCursor is absent. Records are kept for 90 days.
curl --request GET \
--url https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.upliftai.org/v1/realtime-assistants/{realtimeAssistantId}/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"sessions": [
{
"sessionId": "25661352-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"realtimeAssistantId": "452dda41-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "a12b7e74-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"projectId": "c782a4ec-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"channel": "telephony",
"direction": "outbound",
"state": "completed",
"connected": true,
"toNumber": "+923001234567",
"fromNumber": "+924238900100",
"roomName": "call-25661352-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"participantIdentity": "callee-25661352",
"transportProvider": "twilio",
"variables": {
"source": "assistant-test"
},
"createdAt": "2026-08-16T18:55:22.677Z",
"ringingAt": "2026-08-16T18:55:30.758Z",
"connectedAt": "2026-08-16T18:55:36.927Z",
"answeredAt": "2026-08-16T18:55:37.641Z",
"endedAt": "2026-08-16T18:56:17.411Z",
"durationSec": 40
},
{
"sessionId": "138d6508-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"realtimeAssistantId": "452dda41-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"organizationId": "a12b7e74-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"projectId": "c782a4ec-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"channel": "web",
"direction": "inbound",
"state": "created",
"connected": false,
"outcome": "no_answer",
"roomName": "web-138d6508-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"participantIdentity": "عائشہ صدیقی",
"createdAt": "2026-08-18T05:14:25.444Z"
}
],
"nextCursor": "eyJyZWFsdGltZUFzc2lzdGFudElkIjogIjQ1MmRkYTQxLXh4eHgteHh4eC14eHh4LXh4eHh4eHh4eHh4eCIsICJzZXNzaW9uSWQiOiAiMTM4ZDY1MDgteHh4eC14eHh4LXh4eHgteHh4eHh4eHh4eHh4IiwgImNyZWF0ZWRBdCI6ICIyMDI2LTA4LTE4VDA1OjE0OjI1LjQ0NFoifQ"
}{
"message": [
"state must be one of the following values: created, dispatched, dialing, ringing, answered, active, completed, failed"
],
"error": "Bad Request",
"statusCode": 400
}{
"message": "invalid authorization",
"error": "Unauthorized",
"statusCode": 401
}{
"message": "Forbidden resource",
"error": "Forbidden",
"statusCode": 403
}{
"message": "Realtime assistant not found: 00000000-0000-4000-8000-000000000000",
"error": "Not Found",
"statusCode": 404
}Authorizations
Project API key (sk_api_…).
Path Parameters
Query Parameters
web, telephony, whatsapp Web sessions are always inbound — the user opens them.
inbound, outbound created, dispatched, dialing, ringing, answered, active, completed, failed Inclusive lower bound on createdAt. Compared as a raw string against the ISO-8601 UTC timestamps in the response, so a non-ISO value silently shifts or voids the range instead of erroring.
Inclusive upper bound on createdAt, same format as from.
Sessions read per page before filtering. Values above the maximum are clamped, not rejected.
1 <= x <= 100The previous page's nextCursor, passed back unchanged. Treat it as opaque.
draft lists only sessions launched on the draft. prod lists everything else, including sessions launched by an exact version number and sessions from before versions existed.
prod, draft Adds each call's summary to its row, up to about 1 KB each. Must be exactly true or false, anything else is a 400. A row with no summary leaves the key out: a call that never connected, one not summarised yet, or one from before summaries.
