curl --request GET \
--url https://{host}/api/public/analytics/projects/{projectId}/sessions \
--header 'x-api-key: <api-key>'{
"success": true,
"total": 1,
"offset": 0,
"limit": 100,
"hasMore": false,
"sessions": [
{
"id": "sess-01J4S8Y1",
"channel": "web_chat",
"environment": "production",
"status": "ended",
"containmentType": "contained_resolved",
"createdAt": "2026-08-01T00:00:00.000Z",
"lastActivityAt": "2026-08-01T00:05:00.000Z",
"endedAt": "2026-08-01T00:05:30.000Z",
"messageCount": {
"user": 3,
"agent": 4,
"total": 7
},
"traceEventCount": {
"llm_call": 2,
"decision": 1,
"tool_call": 5,
"error": 1,
"total": 12
},
"tokenCount": {
"inputTokens": 100,
"cachedTokens": 10,
"completionTokens": 32,
"reasoningTokens": 8,
"outputTokens": 40,
"totalTokens": 140
},
"traceDimensions": {
"accountTier": "gold"
},
"estimatedCost": 0.0025,
"durationMs": 330000,
"idleDurationMs": 30000,
"isTest": null
}
]
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}List session summaries
Use limit and offset to page through the results. The response includes
message, trace-event, and token counts per session, but not the messages or
trace details themselves. Use the conversation-history endpoint for messages and
the traces endpoint for execution detail.
curl --request GET \
--url https://{host}/api/public/analytics/projects/{projectId}/sessions \
--header 'x-api-key: <api-key>'{
"success": true,
"total": 1,
"offset": 0,
"limit": 100,
"hasMore": false,
"sessions": [
{
"id": "sess-01J4S8Y1",
"channel": "web_chat",
"environment": "production",
"status": "ended",
"containmentType": "contained_resolved",
"createdAt": "2026-08-01T00:00:00.000Z",
"lastActivityAt": "2026-08-01T00:05:00.000Z",
"endedAt": "2026-08-01T00:05:30.000Z",
"messageCount": {
"user": 3,
"agent": 4,
"total": 7
},
"traceEventCount": {
"llm_call": 2,
"decision": 1,
"tool_call": 5,
"error": 1,
"total": 12
},
"tokenCount": {
"inputTokens": 100,
"cachedTokens": 10,
"completionTokens": 32,
"reasoningTokens": 8,
"outputTokens": 40,
"totalTokens": 140
},
"traceDimensions": {
"accountTier": "gold"
},
"estimatedCost": 0.0025,
"durationMs": 330000,
"idleDurationMs": 30000,
"isTest": null
}
]
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": {}
},
"success": false,
"message": "<string>",
"required": "<string>"
}fromDate— Inclusive start timestamp.toDate— Exclusive end timestamp.sessionIds— Filter by specific session IDs; up to 10,000.containmentType— Filter by how the session was resolved, such ascontained_resolved,contained_partial,escalated, orabandoned.environment— Filter by environment:dev,staging,production, orworking-copy.channelUId— Filter by the end-user identity recorded on the channel.callerNumber— Filter by caller number or caller identity.channel— Filter by the channel through which the conversation originated.traceDimensions[key]— Filter by custom session dimensions and their values.status— Filter by session state, such asactive,idle,ended,completed,escalated, orabandoned.
fromDate and toDate together, or sessionIds. All other filters are optional. Multiple filters are combined with AND logic; multiple values within a filter are combined with OR logic.
Use limit and offset to paginate through the results.Authorizations
Project-bound API key. Do not send an Authorization header with this API.
Path Parameters
Project identifier bound to the API key.
1Query Parameters
Inclusive ISO 8601 start timestamp. Required with toDate unless sessionIds is supplied.
Exclusive ISO 8601 end timestamp. Required with fromDate unless sessionIds is supplied.
Filter to specific sessions. Pass up to 10,000 session IDs, comma-separated or by repeating the parameter. Can be used instead of a date range.
100001Filter by how the session was resolved — whether the agent handled it or it went to a human. Pass one or more values, comma-separated or by repeating the parameter, up to 100.
Values are case-sensitive and anything else is rejected with 400 INVALID_CONTAINMENT_TYPE.
100contained, contained_resolved, contained_partial, contained_unresolved, escalated, abandoned Filter by environment. Pass one or more values, comma-separated or by repeating the parameter.
Values are case-sensitive and anything else is rejected with 400 INVALID_ENVIRONMENT. Use dev, not development or prod — the service
handles both stored spellings for you behind the scenes, but only accepts
the four values below as input.
4dev, staging, production, working-copy 128Filter to sessions belonging to specific end users, using the identity recorded for them on the channel. Pass up to 100 values, comma-separated or by repeating the parameter.
1001Filter to sessions from specific callers (ANI or provider caller id). Pass up
to 100 values, comma-separated (spaces after commas are allowed) or by
repeating the parameter; the filter is ANDed with every other filter. The
100-value limit counts entries before duplicates are merged; more returns
400 TOO_MANY_FILTER_VALUES. A value that itself contains a comma cannot be
queried, because commas always separate values.
Paste the value in any format the provider, a transcript, a CDR or a
spreadsheet shows. Each value is turned into the same match key the platform
stored at call time: invisible characters, fullwidth digits and Unicode
dashes are cleaned up, a national trunk (0) after the country code is
removed (+44 (0)20 7946 0958 matches +442079460958), and phone-like
values (including sip: and
tel: URIs, spaces, dashes, dots, slashes and parentheses) become E.164.
7 to 15 bare digits are treated as an international number (919876543210
matches +919876543210). Digits written in a national format keep their
digits (098765 43210 matches 09876543210). Other values, such as softphone
usernames, SDK ids or Anonymous, are matched as cleaned text. Matching is
exact and case-sensitive: anonymous does not match Anonymous, and
+14155550100 ext 12 does not match +14155550100. Non-ASCII digits such as
Arabic-Indic digits are not converted to ASCII. Keys longer than 128
characters are truncated, the same way they were when stored.
There is no country inference: a national number without its country code
(9876543210) does not match a stored +919876543210, and 00 or 011
dial prefixes are not converted. Send the full international form where
possible. Send + as %2B or use the POST twin; an unencoded + decodes to
a space, which is also accepted and gives the same match. Anonymous matches
every withheld-number call in the window.
An entry that is empty or has no letter or digit (for example
callerNumber=, a trailing comma, or only +), or an entry longer than 512
characters, returns 400 INVALID_CALLER_NUMBER. The value is
never returned in the response. When the project's reporting exposure config
disables the identity field group, a request with this parameter returns
403 CALLER_NUMBER_LOOKUP_DISABLED.
Coverage: matches sessions whose summary was written after this filter
shipped. Sessions recorded earlier are not returned for callerNumber (use
/conversation-history, which reads the session record directly).
Playground and Studio debug sessions are never matched.
1001 - 512Filter by the channel the conversation came in on. Pass one or more values, comma-separated or by repeating the parameter, up to 50 distinct channels of 128 characters each.
This endpoint understands shorthand. Values are grouped into channel
families before matching, and each family also matches its older stored
spellings, so channel=web, channel=sdk_web, and channel=web_chat all
return the same web-chat sessions. The groupings are listed under
x-alias-groups, and those alias spellings are accepted here even though
they are not in the enum — the enum is kept identical across all the public
analytics endpoints so there is one channel list to learn.
Because of that grouping, asking for one specific voice channel such as
channel=voice_pipeline returns all voice sessions, not just that
transport. Use the traces endpoint if you need to distinguish them.
Not restricted to a fixed list, so an unrecognised value returns no results rather than an error.
50http_async, slack, line, msteams, whatsapp, messenger, instagram, twilio_sms, zendesk, telegram, genesys, genesys_open_messaging, ai4w, kore_agent_assist, email, voice_vxml, korevg, audiocodes, genesys_audio_connector, voice_pipeline, voice_realtime, voice, voice_twilio, voice_livekit, ag_ui, a2a, sdk_websocket, web_debug, web_chat, api, http 128Filter by a custom dimension recorded against the session. Replace key with
the dimension name — for example traceDimensions[accountTier]=gold. Repeat
with different keys to require all of them. Values match exactly. Remember to
URL-encode the brackets if your HTTP client does not do it for you.
Filter by the session's current state. Pass a single value; if you repeat the parameter only the first value is used.
Case-sensitive, and anything else is rejected with 400 INVALID_STATUS.
Note that sessions can be stored with a status of failed, but failed is
not accepted as a filter value here.
active, idle, ended, completed, escalated, abandoned, archived How many sessions to return. A page may come back with fewer than requested
so the response stays within the 1 MiB size limit — check hasMore rather
than assuming a short page is the last one.
1 <= x <= 10000x >= 0Response
Session page returned successfully.
- Option 1
- Option 2
Always true on a successful response.
The sessions on this page.
Show child attributes
Show child attributes
Total number of sessions matching your filters, across all pages.
x >= 0The offset applied to this response.
x >= 0The page size applied to this response.
1 <= x <= 10000Whether more pages are available after this one.
Was this page helpful?