Skip to content

Read Speak AI voice agent engagement metrics

Workspace and per-agent call metrics: totals, completion rate, duration, engagement funnels, and a full per-agent report on audience, leads and outcomes.

Updated View as MarkdownAsk ClaudeOpen in ChatGPTllms.txt

The Speak AI API exposes 4 analytics endpoints under the base URL https://api.speakai.co/v1. Every request needs your API key in the x-speakai-key header, as described in Authentication. No access token is needed.

What can you do with the analytics endpoints?

Speak AI groups these 4 endpoints under the analytics resource. Each entry below links to the full reference for that endpoint further down this page.

Agent Analytics

GET/voice/analytics/agent

Agent Analytics

Everything the agent analytics view shows for one agent over a date range: headline numbers with an optional comparison to the previous period, a daily series, audience (locations, devices, traffic sources), leads, handoffs, action items, engagement, sentiment, topics, end reasons, satisfaction, call timing, languages and web versus phone. The response payload sits directly on data, not nested under a named key.

Leave out start for all time. A start more than 5 years before end is moved up to 5 years before end. A start after end returns 400. Rates are fractions from 0 to 1.

Parameters

Parameter In Type Required Description
agentId query string Yes The agent to report on. Required. Must be an agent in your workspace, otherwise the request returns 404.
start query string (date-time) No Start of the window, as an ISO 8601 date. Optional. Leave it out for all time.
end query string (date-time) No End of the window, as an ISO 8601 date. Optional. Defaults to now.
tz query string No IANA time zone used to bucket days, hours and weekdays, such as America/Toronto. Optional. Defaults to UTC. At most 100 characters. An unknown zone returns 400.
compare query boolean No Also return the same numbers for the period of equal length just before start, in previousKpis. Optional. Defaults to false. Has no effect without start.
includeTests query boolean No Count test calls placed from the dashboard. Optional. Defaults to false. testCalls.count reports them either way.
Example request
curl -X GET 'https://api.speakai.co/v1/voice/analytics/agent?agentId=a1b2c3d4-e5f6-7890-abcd-ef1234567890&start=2026-09-01T00%3A00%3A00.000Z&end=2026-09-30T23%3A59%3A59.999Z&tz=America%2FToronto&compare=true&includeTests=false' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data – 9 more fields
Field Type Description
range object The window the numbers cover.
range.start string (date-time) Start of the window. Null when you sent no start, which means all time.
range.end string (date-time) End of the window. Now when you sent no end.
range.tz string The time zone used to bucket days, hours and weekdays.
range.previousStart string (date-time) Start of the comparison window. Null unless compare is true and start was sent.
range.previousEnd string (date-time) End of the comparison window, which is the current start. Null unless compare is true and start was sent.
testCalls object
testCalls.count integer Test calls placed from the dashboard in the window, counted whether or not they are included.
testCalls.included boolean Whether test calls are counted in the other numbers, matching includeTests.
overview object
overview.kpis object
overview.previousKpis object The same numbers for the comparison window. Null unless compare is true and start was sent.
overview.overTime object[] One entry per day in the window, zero filled, in the requested time zone. Capped at the most recent 3,660 days. Empty when no start was sent and there are no conversations.
audience object
audience.locations object[] Up to 10 locations with the most conversations.
audience.locationUnknown integer Conversations not counted in locations.
audience.devices object Web calls only. Phone calls carry no device data.
audience.sources object[] Up to 10 traffic sources for web calls.
attention object
attention.notJoined integer Web calls that ended before the caller said anything.
attention.unanswered integer Knowledge gaps for this agent still waiting for an answer. Not limited to the window.
outcomes object
outcomes.leads object
outcomes.handoffs object
outcomes.actionItems object
quality object
quality.engagement object[] Always 4 buckets, in order: Bounce (0-1 turns), Brief (2-5), Engaged (6-15), Deep (16+).
quality.sentiment object
quality.topTopics object[] Up to 10 key topics, lowercased.
quality.endReasons object[] Up to 10 reasons calls ended.
quality.satisfaction object Average post-call rating. Null when no call in the window was rated.
whenAndWho object
whenAndWho.byHour object[] 24 entries, hour 0 to 23 in the requested time zone.
whenAndWho.byWeekday object[] 7 entries, weekday 0 (Sunday) to 6 (Saturday) in the requested time zone.
whenAndWho.languages object[] Up to 10 caller languages.
channel object
channel.web object
channel.phone object
overview.kpis – 4 more fields
Field Type Description
conversations integer
completionRate number Completed conversations divided by all conversations, from 0 to 1.
avgDurationSeconds number
returningCallers integer Callers in the window who called more than once, or who also called before the window.
overview.previousKpis – 4 more fields
Field Type
conversations integer
completionRate number
avgDurationSeconds number
returningCallers integer
overview.overTime – 4 more fields
Field Type Description
date string Day as YYYY-MM-DD.
conversations integer
web integer
phone integer
audience.locations – 4 more fields
Field Type Description
city string
region string
country string Country name.
count integer
audience.devices – 4 more fields
Field Type Description
withDeviceData integer
deviceTypes object
deviceTypes.desktop integer
deviceTypes.mobile integer
deviceTypes.tablet integer
browsers object[] Up to 5 browsers.
browsers[].name string
browsers[].count integer
os object[] Up to 5 operating systems.
os[].name string
os[].count integer
audience.sources – 3 more fields
Field Type Description
kind string campaign when the call carried UTM tags, page when it came from a referring page, direct otherwise. One of: page, campaign, direct .
label string The UTM source and campaign, or the referring host and path. Empty for direct.
count integer
outcomes.leads – 4 more fields
Field Type Description
count integer
rate number Lead conversations divided by all conversations, from 0 to 1.
fields object[] Up to 6 collected fields that were filled in most often.
fields[].field string
fields[].count integer
latest object[] Up to 10 most recent conversations that collected data.
latest – 8 more fields
Field Type
conversationId string
createdAt string
name string
email string
phone string
summary string
mediaId string
folderId string
outcomes.handoffs – 3 more fields
Field Type Description
count integer
rate number Handed off conversations divided by all conversations, from 0 to 1.
reasons object[] Up to 5 most common handoff reasons.
reasons[].reason string
reasons[].count integer
outcomes.actionItems – 3 more fields
Field Type Description
conversations integer
rate number Conversations with action items divided by all conversations, from 0 to 1.
recent object[] Up to 5 action items from the most recent conversations.
recent[].conversationId string
recent[].createdAt string
recent[].item string
quality.engagement – 7 more fields
Field Type
label string
minMessages integer
maxMessages integer
count integer
percentage integer
avgDurationSeconds number
sentimentBreakdown object
sentimentBreakdown.positive integer
sentimentBreakdown.neutral integer
sentimentBreakdown.negative integer
sentimentBreakdown.unanalyzed integer
quality.sentiment – 4 more fields
Field Type
positive integer
neutral integer
negative integer
unanalyzed integer
quality.topTopics – 2 more fields
Field Type
topic string
count integer
quality.endReasons – 2 more fields
Field Type
reason string
count integer
quality.satisfaction – 2 more fields
Field Type
average number
count integer
whenAndWho.byHour – 2 more fields
Field Type
hour integer
count integer
whenAndWho.byWeekday – 2 more fields
Field Type
weekday integer
count integer
whenAndWho.languages – 2 more fields
Field Type
language string
count integer
channel.web – 2 more fields
Field Type
count integer
avgDurationSeconds number
channel.phone – 2 more fields
Field Type
count integer
avgDurationSeconds number

Example response, application/json. Arrays are shortened to one entry and long strings are cut.

{
  "status": "success",
  "data": {
    "range": {
      "start": "2026-09-01T00:00:00.000Z",
      "end": "2026-09-30T23:59:59.999Z",
      "tz": "America/Toronto",
      "previousStart": "2026-08-03T00:00:00.001Z",
      "previousEnd": "2026-09-01T00:00:00.000Z"
    },
    "testCalls": {
      "count": 3,
      "included": false
    },
    "overview": {
      "kpis": {
        "conversations": 120,
        "completionRate": 0.85,
        "avgDurationSeconds": 142.6,
        "returningCallers": 14
      },
      "previousKpis": {
        "conversations": 96,
        "completionRate": 0.81,
        "avgDurationSeconds": 131.2,
        "returningCallers": 9
      },
      "overTime": [
        {
          "date": "2026-09-01",
          "conversations": 5,
          "web": 4,
          "phone": 1
        }
      ]
    },
    "audience": {
      "locations": [
        {
          "city": "Toronto",
          "region": "Ontario",
          "country": "Canada",
          "count": 22
        }
      ],
      "locationUnknown": 31,
      "devices": {
        "withDeviceData": 88,
        "deviceTypes": {
          "desktop": 52,
          "mobile": 33,
          "tablet": 3
        },
        "browsers": [
          {
            "name": "Chrome",
            "count": 54
          }
        ],
        "os": [
          {
            "name": "Windows",
            "count": 40
          }
        ]
      },
      "sources": [
        {
          "kind": "page",
          "label": "example.com/pricing",
          "count": 27
        }
      ]
    },
    "attention": {
      "notJoined": 4,
      "unanswered": 2
    },
    "outcomes": {
      "leads": {
        "count": 36,
        "rate": 0.3,
        "fields": [
          {
            "field": "email",
            "count": 34
          }
        ],
        "latest": [
          {
            "conversationId": "c0ffee00-1234-4abc-9def-0123456789ab",
            "createdAt": "2026-09-29T15:42:10.000Z",
            "name": "Jordan Example",
            "email": "jordan@example.com",
            "phone": null,
            "summary": "Asked about annual pricing and booked a demo.",
            "mediaId": "3afc714552cd",
            "folderId": null
          }
        ]
      },
      "handoffs": {
        "count": 8,
        "rate": 0.0667,
        "reasons": [
          {
            "reason": "Requested a human agent",
            "count": 5
          }
        ]
      },
      "actionItems": {
        "conversations": 41,
        "rate": 0.3417,
        "recent": [
          {
            "conversationId": "c0ffee00-1234-4abc-9def-0123456789ab",
            "createdAt": "2026-09-29T15:42:10.000Z",
            "item": "Send the annual pricing sheet."
          }
        ]
      }
    },
    "quality": {
      "engagement": [
        {
          "label": "Engaged (6-15)",
          "minMessages": 6,
          "maxMessages": 15,
          "count": 48,
          "percentage": 40,
          "avgDurationSeconds": 168.3,
          "sentimentBreakdown": {
            "positive": 30,
            "neutral": 14,
            "negative": 3,
            "unanalyzed": 1
          }
        }
      ],
      "sentiment": {
        "positive": 70,
        "neutral": 38,
        "negative": 9,
        "unanalyzed": 3
      },
      "topTopics": [
        {
          "topic": "pricing",
          "count": 25
        }
      ],
      "endReasons": [
        {
          "reason": "customer-ended-call",
          "count": 77
        }
      ],
      "satisfaction": {
        "average": 4.4,
        "count": 52
      }
    },
    "whenAndWho": {
      "byHour": [
        {
          "hour": 14,
          "count": 12
        }
      ],
      "byWeekday": [
        {
          "weekday": 2,
          "count": 25
        }
      ],
      "languages": [
        {
          "language": "en",
          "count": 104
        }
      ]
    },
    "channel": {
      "web": {
        "count": 98,
        "avgDurationSeconds": 139.1
      },
      "phone": {
        "count": 22,
        "avgDurationSeconds": 158.2
      }
    }
  }
}

400 A query parameter failed validation

Response body, application/json.

Field Type Description
status string One of: failed .
message string

404 Agent not found

Response body, application/json.

Field Type Description
status string One of: failed .
requestId string
code integer
message string
hints string[]

Example response, application/json.

{
  "status": "failed",
  "code": 404,
  "message": "Agent not found",
  "hints": []
}

Engagement Funnel Summaries

GET/voice/analytics/funnel

Engagement Funnel Summaries

The same bounce/brief/engaged/deep breakdown as Engagement Funnel For Agent, but as one summary row per agent across your whole workspace, sorted by deepRate descending. The response payload is a bare array directly on data – not an object, and not nested under a named key.

Parameters

Parameter In Type Required Description
since query string No ISO date. Defaults to 30 days ago.
Example request
curl -X GET 'https://api.speakai.co/v1/voice/analytics/funnel' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object[]
data – 7 more fields
Field Type
agentId string
agentName string
totalConversations integer
bounceRate integer
briefRate integer
engagedRate integer
deepRate integer

Example response, application/json.

{
  "status": "success",
  "data": [
    {
      "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "agentName": "Support Agent",
      "totalConversations": 80,
      "bounceRate": 15,
      "briefRate": 30,
      "engagedRate": 40,
      "deepRate": 15
    }
  ]
}

400 Invalid since date

Response body, application/json.

Field Type Description
status string One of: failed .
message string

Analytics Overview

GET/voice/analytics/overview

Analytics Overview

Workspace-level call metrics: totals, week-over-week counts, completion rate, average duration, a 14-day daily time series, and average post-call feedback rating. Optionally scope to one agentId. Unlike most endpoints in this API, the response payload sits directly on data, not nested under a named key.

Parameters

Parameter In Type Required Description
agentId query string No Scope to one agent. Omit for the whole workspace.
Example request
curl -X GET 'https://api.speakai.co/v1/voice/analytics/overview' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data – 8 more fields
Field Type Description
totalConversations integer
thisWeekCount integer
lastWeekCount integer
completionRate number 0-1. Share of calls that reached status completed.
avgDurationSeconds number
dailyCounts object[] Last 14 days, oldest first, zero-filled for days with no calls.
dailyCounts[].date string
dailyCounts[].count integer
averageRating number Average post-call feedback rating (1-5). 0 if no feedback submitted yet.
ratingCount integer

Example response, application/json.

{
  "status": "success",
  "data": {
    "totalConversations": 214,
    "thisWeekCount": 31,
    "lastWeekCount": 27,
    "completionRate": 0.92,
    "avgDurationSeconds": 138.4,
    "dailyCounts": [
      {
        "date": "2026-07-19",
        "count": 4
      },
      {
        "date": "2026-07-20",
        "count": 6
      }
    ],
    "averageRating": 4.3,
    "ratingCount": 58
  }
}

Engagement Funnel For Agent

GET/voice/analytics/funnel/agent

Engagement Funnel For Agent

Buckets one agent’s conversations by transcript turn count (bounce/brief/engaged/deep), each with average duration and sentiment split. Defaults to the last 30 days if since is omitted; since older than 365 days is floored to 365 days ago. The response payload sits directly on data, not nested under a named key.

Parameters

Parameter In Type Required Description
agentId query string Yes Required.
since query string No ISO date. Defaults to 30 days ago.
Example request
curl -X GET 'https://api.speakai.co/v1/voice/analytics/funnel/agent' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.buckets object[] Always 4 buckets, in order: Bounce (0-1 turns), Brief (2-5), Engaged (6-15), Deep (16+).
data.totalConversations integer
data.since string (date-time)
data.buckets – 7 more fields
Field Type
label string
minMessages integer
maxMessages integer
count integer
percentage integer
avgDurationSeconds number
sentimentBreakdown object
sentimentBreakdown.positive integer
sentimentBreakdown.neutral integer
sentimentBreakdown.negative integer
sentimentBreakdown.unanalyzed integer

Example response, application/json.

{
  "status": "success",
  "data": {
    "buckets": [
      {
        "label": "Bounce (0-1)",
        "minMessages": 0,
        "maxMessages": 1,
        "count": 12,
        "percentage": 15,
        "avgDurationSeconds": 8.2,
        "sentimentBreakdown": {
          "positive": 2,
          "neutral": 8,
          "negative": 2,
          "unanalyzed": 0
        }
      }
    ],
    "totalConversations": 80,
    "since": "2026-07-01T00:00:00.000Z"
  }
}

400 Invalid since date

Response body, application/json.

Field Type Description
status string One of: failed .
message string

404 Agent not found

Response body, application/json.

Field Type Description
status string One of: failed .
requestId string
code integer
message string
hints string[]

Example response, application/json.

{
  "status": "failed",
  "code": 404,
  "message": "Agent not found",
  "hints": []
}

Get an API key on the Speak AI developer page.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close