The Speak AI API exposes 16 intelligence endpoints under the base URL https://api.speakai.co/v1. Every request needs the x-speakai-key and x-access-token headers described in Authentication.
What can you do with the intelligence endpoints?
Speak AI groups these 16 endpoints under the intelligence resource. Each entry below links to the full reference for that endpoint further down this page.
Agent Resources
FAQs
Knowledge Base Gaps
Instruction Gaps
Agent Resources
List Agent Resources
/voice/agent-resourcesList Agent Resources
Lists the knowledge documents/links an agent searches during calls – separate from the KB Gaps and FAQ Suggestions above, which are the self-improvement layer that surfaces what an agent is missing, not the content itself. Paginated; optionally scoped to one agentId, and searchable by title/description.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
query | string | No | Scope to one agent’s resources. Omit to list across all your agents. |
page |
query | integer | No | Defaults to 1. |
limit |
query | integer | No | Defaults to 10, max 100. |
search |
query | string | No | Case-insensitive match against title or description. |
curl -X GET 'https://api.speakai.co/v1/voice/agent-resources' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.resources |
object[] | |
data.total |
integer | |
data.page |
integer | |
data.limit |
integer |
data.resources – 15 more fields
| Field | Type | Description |
|---|---|---|
_id |
string | MongoDB document id, included because every document has one; use resourceId to identify it. |
resourceId |
string | Server-generated UUID. Immutable – sent in the body on create or update is silently dropped. |
agentId |
string | Required on create. Immutable after create – sent on update is silently dropped. |
companyId |
string | Stamped from the caller’s authenticated company. Sent in the body is silently dropped. |
userId |
string | Id of the user who created this resource. Sent in the body is silently dropped. |
url |
string (uri) | Required on create. |
title |
string | Required on create. Max 200 characters. |
description |
string | Required on create. Max 1000 characters. |
action |
string | Required on create. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
status |
string | Defaults to pending. Advances as the resource’s content is fetched and embedded for the agent to search during calls. Not settable directly. One of: pending, uploading, processing, completed, failed . |
isDeleted |
boolean | Delete is a soft delete. Not settable directly. |
deletedAt |
string (date-time) | |
createdAt |
string (date-time) | |
updatedAt |
string (date-time) |
Example response, application/json.
{
"status": "success",
"data": {
"resources": [
{
"resourceId": "res-2a9f",
"agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://docs.example.com/pricing",
"title": "Pricing page",
"description": "Current plan pricing and feature comparison",
"action": "link",
"status": "completed",
"isDeleted": false,
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
],
"total": 1,
"page": 1,
"limit": 10
}
}Create Agent Resource
/voice/agent-resourcesCreate Agent Resource
Requires the OWNER or ADMIN role. Adds one document/link to an agent’s knowledge base; the server fetches and embeds the content in the background (status moves from pending to completed).
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
agentId |
string, required | Required. |
url |
string (uri), required | Required. |
title |
string, required | Required. Max 200 characters. |
description |
string, required | Required. Max 1000 characters. |
action |
string, required | Required. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
curl -X POST 'https://api.speakai.co/v1/voice/agent-resources' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'201 Created
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.resource |
object |
data.resource – 15 more fields
| Field | Type | Description |
|---|---|---|
_id |
string | MongoDB document id, included because every document has one; use resourceId to identify it. |
resourceId |
string | Server-generated UUID. Immutable – sent in the body on create or update is silently dropped. |
agentId |
string | Required on create. Immutable after create – sent on update is silently dropped. |
companyId |
string | Stamped from the caller’s authenticated company. Sent in the body is silently dropped. |
userId |
string | Id of the user who created this resource. Sent in the body is silently dropped. |
url |
string (uri) | Required on create. |
title |
string | Required on create. Max 200 characters. |
description |
string | Required on create. Max 1000 characters. |
action |
string | Required on create. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
status |
string | Defaults to pending. Advances as the resource’s content is fetched and embedded for the agent to search during calls. Not settable directly. One of: pending, uploading, processing, completed, failed . |
isDeleted |
boolean | Delete is a soft delete. Not settable directly. |
deletedAt |
string (date-time) | |
createdAt |
string (date-time) | |
updatedAt |
string (date-time) |
Example response, application/json.
{
"status": "success",
"data": {
"resource": {
"resourceId": "res-2a9f",
"agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://docs.example.com/pricing",
"title": "Pricing page",
"description": "Current plan pricing and feature comparison",
"action": "link",
"status": "completed",
"isDeleted": false,
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
}
}400 Validation failed
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agent resources"
}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": []
}Update Agent Resource
/voice/agent-resources/{resourceId}Update Agent Resource
Requires the OWNER or ADMIN role. Partial update – send at least one field. agentId cannot be changed. Changing url, title, or description re-triggers embedding.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
resourceId |
path | string | Yes |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
url |
string (uri) | Required. |
title |
string | Required. Max 200 characters. |
description |
string | Required. Max 1000 characters. |
action |
string | Required. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
curl -X PUT 'https://api.speakai.co/v1/voice/agent-resources/RESOURCE_ID' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.resource |
object |
data.resource – 15 more fields
| Field | Type | Description |
|---|---|---|
_id |
string | MongoDB document id, included because every document has one; use resourceId to identify it. |
resourceId |
string | Server-generated UUID. Immutable – sent in the body on create or update is silently dropped. |
agentId |
string | Required on create. Immutable after create – sent on update is silently dropped. |
companyId |
string | Stamped from the caller’s authenticated company. Sent in the body is silently dropped. |
userId |
string | Id of the user who created this resource. Sent in the body is silently dropped. |
url |
string (uri) | Required on create. |
title |
string | Required on create. Max 200 characters. |
description |
string | Required on create. Max 1000 characters. |
action |
string | Required on create. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
status |
string | Defaults to pending. Advances as the resource’s content is fetched and embedded for the agent to search during calls. Not settable directly. One of: pending, uploading, processing, completed, failed . |
isDeleted |
boolean | Delete is a soft delete. Not settable directly. |
deletedAt |
string (date-time) | |
createdAt |
string (date-time) | |
updatedAt |
string (date-time) |
Example response, application/json.
{
"status": "success",
"data": {
"resource": {
"resourceId": "res-2a9f",
"agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://docs.example.com/pricing",
"title": "Pricing page",
"description": "Current plan pricing and feature comparison",
"action": "link",
"status": "completed",
"isDeleted": false,
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
}
}400 Validation failed
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agent resources"
}404 Resource 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": "Resource not found",
"hints": []
}Delete Agent Resource
/voice/agent-resources/{resourceId}Delete Agent Resource
Requires the OWNER or ADMIN role. Soft-deletes the resource (isDeleted set true) – it stops appearing in lists and the agent stops searching it, but the document is not physically removed.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
resourceId |
path | string | Yes |
curl -X DELETE 'https://api.speakai.co/v1/voice/agent-resources/RESOURCE_ID' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "Resource deleted successfully"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agent resources"
}404 Resource 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": "Resource not found",
"hints": []
}Bulk Create Agent Resources
/voice/agent-resources/bulkBulk Create Agent Resources
Requires the OWNER or ADMIN role. Adds up to 100 documents/links in one call; each is fetched and embedded independently in the background.
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
agentId |
string, required | Required. |
resources |
object[], required | Required. 1 to 100 entries, each shaped like the Create Agent Resource request body minus agentId. |
resources – 6 more fields
| Field | Type | Description |
|---|---|---|
agentId |
string | Required. |
url |
string (uri) | Required. |
title |
string | Required. Max 200 characters. |
description |
string | Required. Max 1000 characters. |
action |
string | Required. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
curl -X POST 'https://api.speakai.co/v1/voice/agent-resources/bulk' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'201 Created
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.resources |
object[] | |
data.total |
integer |
data.resources – 15 more fields
| Field | Type | Description |
|---|---|---|
_id |
string | MongoDB document id, included because every document has one; use resourceId to identify it. |
resourceId |
string | Server-generated UUID. Immutable – sent in the body on create or update is silently dropped. |
agentId |
string | Required on create. Immutable after create – sent on update is silently dropped. |
companyId |
string | Stamped from the caller’s authenticated company. Sent in the body is silently dropped. |
userId |
string | Id of the user who created this resource. Sent in the body is silently dropped. |
url |
string (uri) | Required on create. |
title |
string | Required on create. Max 200 characters. |
description |
string | Required on create. Max 1000 characters. |
action |
string | Required on create. One of: link, presentation . |
contentType |
string | One of: video, pdf, image . |
status |
string | Defaults to pending. Advances as the resource’s content is fetched and embedded for the agent to search during calls. Not settable directly. One of: pending, uploading, processing, completed, failed . |
isDeleted |
boolean | Delete is a soft delete. Not settable directly. |
deletedAt |
string (date-time) | |
createdAt |
string (date-time) | |
updatedAt |
string (date-time) |
Example response, application/json.
{
"status": "success",
"data": {
"resources": [
{
"resourceId": "res-2a9f",
"agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://docs.example.com/pricing",
"title": "Pricing page",
"description": "Current plan pricing and feature comparison",
"action": "link",
"status": "completed",
"isDeleted": false,
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
],
"total": 1
}
}400 Validation failed
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agent resources"
}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": []
}FAQs
List FAQ Suggestions
/voice/knowledge-base/{agentId}/faqsList FAQ Suggestions
Lists this agent’s pending FAQ suggestions – questions multiple callers asked in similar form, clustered and drafted into a reusable question/answer pair. Up to the 20 largest clusters, largest first.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes |
curl -X GET 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/faqs' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.faqs |
object[] |
data.faqs – 11 more fields
| Field | Type | Description |
|---|---|---|
_id |
string | MongoDB document id, included because every document has one; use suggestionId to identify it. |
suggestionId |
string | Server-generated. Immutable. Used as the suggestionId path parameter on every FAQ endpoint. |
agentId |
string | |
question |
string | |
answer |
string | |
sourceConversationIds |
string[] | The calls this FAQ was clustered from. See Conversations. |
clusterSize |
integer | How many similar caller questions were grouped into this one suggestion. |
status |
string | One of: pending, added, dismissed . |
resolvedAt |
string (date-time) | |
createdAt |
string (date-time) | |
updatedAt |
string (date-time) |
Example response, application/json.
{
"status": "success",
"data": {
"faqs": [
{
"suggestionId": "sugg-7c2e",
"agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"question": "What are your business hours?",
"answer": "We're open Monday to Friday, 9am to 5pm.",
"sourceConversationIds": [
"c9d8e7f6-a5b4-3210-9876-543210fedcba"
],
"clusterSize": 4,
"status": "pending",
"resolvedAt": null,
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
]
}
}Update FAQ Suggestion
/voice/knowledge-base/{agentId}/faqs/{suggestionId}Update FAQ Suggestion
Requires the OWNER or ADMIN role. Edits a still-pending suggestion’s question and/or answer before adding it. Fails with 400 if the suggestion was already added or dismissed.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes | |
suggestionId |
path | string | Yes | The FAQ suggestion’s suggestionId. |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
question |
string | Overrides the suggested question. Optional. |
answer |
string | Overrides the suggested answer. Optional. |
curl -X PUT 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/faqs/SUGGESTION_ID' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "FAQ updated"
}400 Cannot edit a resolved FAQ
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}404 FAQ 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": "FAQ not found",
"hints": []
}Dismiss FAQ Suggestion
/voice/knowledge-base/{agentId}/faqs/{suggestionId}Dismiss FAQ Suggestion
Requires the OWNER or ADMIN role. Marks the suggestion dismissed without writing anything to the knowledge base.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes | |
suggestionId |
path | string | Yes | The FAQ suggestion’s suggestionId. |
curl -X DELETE 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/faqs/SUGGESTION_ID' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "FAQ dismissed"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}404 FAQ 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": "FAQ not found",
"hints": []
}Add FAQ To KB
/voice/knowledge-base/{agentId}/faqs/{suggestionId}/addAdd FAQ To Knowledge Base
Requires the OWNER or ADMIN role. Writes the question/answer (or your override) into the agent’s knowledge base as a new document, and marks the suggestion added. Fails with 409 if the suggestion was already added or dismissed, or if the agent has no knowledge base collection to write into.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes | |
suggestionId |
path | string | Yes | The FAQ suggestion’s suggestionId. |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
question |
string | Overrides the suggested question. Optional. |
answer |
string | Overrides the suggested answer. Optional. |
curl -X POST 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/faqs/SUGGESTION_ID/add' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "Added to knowledge base"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}404 FAQ 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": "FAQ not found",
"hints": []
}409 Conflict
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "FAQ already resolved"
}Generate FAQ Suggestions
/voice/knowledge-base/{agentId}/faqs/generateGenerate FAQ Suggestions
Requires the OWNER or ADMIN role. Triggers FAQ clustering over this agent’s recent calls in the background and returns immediately – new suggestions appear in the list once generation finishes, which is not synchronous with this response.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes |
curl -X POST 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/faqs/generate' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "FAQ generation started"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}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": []
}Knowledge Base Gaps
List KB Gaps
/voice/knowledge-base/{agentId}/gapsList Knowledge Base Gaps
Lists this agent’s pending KB gaps – questions callers asked that the agent answered with low confidence or an explicit “I don’t know,” surfaced automatically after calls. Up to the 50 most recent pending gaps, newest first.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes |
curl -X GET 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/gaps' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.gaps |
object[] |
data.gaps – 14 more fields
| Field | Type | Description |
|---|---|---|
_id |
string | MongoDB document id, included because every document has one; use gapId to identify it. |
gapId |
string | Server-generated. Immutable. |
agentId |
string | |
query |
string | The caller question that triggered a low-confidence or hedging KB answer. |
context |
string | |
avgRetrievalScore |
number | |
conversationId |
string | The call this gap surfaced from. See Conversations. |
suggestedTitle |
string | |
suggestedAnswer |
string | AI-drafted answer. Override with title/answer in the request body when adding to the KB. |
status |
string | One of: pending, added, dismissed . |
severity |
string | One of: low, medium, high . |
resolvedAt |
string (date-time) | |
createdAt |
string (date-time) | |
updatedAt |
string (date-time) |
Example response, application/json.
{
"status": "success",
"data": {
"gaps": [
{
"gapId": "gap-4f1a",
"agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"query": "Do you offer a student discount?",
"avgRetrievalScore": 0.31,
"conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
"suggestedTitle": "Student discount policy",
"suggestedAnswer": "We don't currently offer a student discount.",
"status": "pending",
"severity": "medium",
"resolvedAt": null,
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
]
}
}Dismiss Gap
/voice/knowledge-base/{agentId}/gaps/{gapId}Dismiss Gap
Requires the OWNER or ADMIN role. Marks the gap dismissed without writing anything to the knowledge base.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes | |
gapId |
path | string | Yes |
curl -X DELETE 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/gaps/GAP_ID' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "Gap dismissed"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}404 Gap 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": "Gap not found",
"hints": []
}Add Gap To KB
/voice/knowledge-base/{agentId}/gaps/{gapId}/addAdd Gap To Knowledge Base
Requires the OWNER or ADMIN role. Writes the gap’s answer (or your override) into the agent’s knowledge base as a new document, and marks the gap added. Fails with 409 if the gap was already added or dismissed, or if the agent has no knowledge base collection to write into.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes | |
gapId |
path | string | Yes |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
answer |
string | Overrides suggestedAnswer. Optional. |
title |
string | Overrides suggestedTitle. Optional. |
curl -X POST 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/gaps/GAP_ID/add' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "Added to knowledge base"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}404 Gap 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": "Gap not found",
"hints": []
}409 Conflict
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "Gap already resolved"
}Analyze KB Gaps
/voice/knowledge-base/{agentId}/gaps/analyzeAnalyze KB Gaps
Requires the OWNER or ADMIN role. Triggers gap analysis over this agent’s recent calls in the background and returns immediately – new gaps appear in the list once analysis finishes, which is not synchronous with this response.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes |
curl -X POST 'https://api.speakai.co/v1/voice/knowledge-base/AGENT_ID/gaps/analyze' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
message |
string |
Example response, application/json.
{
"status": "success",
"message": "Analysis started"
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}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": []
}Instruction Gaps
Analyze Instruction Gaps
/voice/agents/{agentId}/generation/gaps/analyzeAnalyze Instruction Gaps
Requires the OWNER or ADMIN role. Advisory only – compares the agent’s current instructions against anchors/original intent/conversation summaries you supply and suggests up to 3 patches. Nothing is written; pass a suggestion’s suggestedPatch to Apply Instruction Gap to actually apply it.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
anchors |
string[] | Specific requirements the instructions must cover. Defaults to empty. |
originalPrompt |
string | The original generation prompt, for context. |
conversationSummaries |
string[] | Recent call summaries, to ground suggestions in what actually came up. Defaults to empty. |
curl -X POST 'https://api.speakai.co/v1/voice/agents/AGENT_ID/generation/gaps/analyze' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.gaps |
object[] | Up to 3 suggestions. Nothing is persisted by this endpoint. |
data.gaps – 4 more fields
| Field | Type | Description |
|---|---|---|
description |
string | |
suggestedPatch |
string | Pass this straight into Apply Instruction Gap’s suggestedPatch. |
insertAfterSection |
string | |
severity |
string | One of: low, medium, high . |
Example response, application/json.
{
"status": "success",
"data": {
"gaps": [
{
"description": "No guidance for refund requests",
"suggestedPatch": "If the caller asks about a refund, explain the 30-day policy and offer to transfer to billing.",
"insertAfterSection": null,
"severity": "medium"
}
]
}
}403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}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": []
}Apply Instruction Gap
/voice/agents/{agentId}/generation/gaps/applyApply Instruction Gap
Requires the OWNER or ADMIN role. Inserts suggestedPatch into the agent’s instructions (after insertAfterSection if given, otherwise appended) and persists the result.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
agentId |
path | string | Yes |
Request body
Fields marked required are the ones the server rejects the request without. Anything conditional, where a field becomes required only alongside another, is described under Request rules above rather than marked here.
| Field | Type | Description |
|---|---|---|
suggestedPatch |
string, required | Required. Typically taken directly from Analyze Instruction Gaps. |
insertAfterSection |
string | Insert after this named section heading; omit or null to append at the end. |
curl -X POST 'https://api.speakai.co/v1/voice/agents/AGENT_ID/generation/gaps/apply' \
-H 'x-speakai-key: sk_test_speak_0000000000000000' \
-H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
-H 'Content-Type: application/json' \
-d '{}'200 OK
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: success . |
data |
object | |
data.instructions |
string | The agent’s full instructions after the patch was applied. |
Example response, application/json.
{
"status": "success",
"data": {
"instructions": "You are a helpful support agent...\n\nIf the caller asks about a refund, explain the 30-day policy and offer to transfer to billing."
}
}400 suggestedPatch is required
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
403 Caller’s role is not OWNER or ADMIN
Response body, application/json.
| Field | Type | Description |
|---|---|---|
status |
string | One of: failed . |
message |
string |
Example response, application/json.
{
"status": "failed",
"message": "You do not have permission to manage agents"
}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": []
}Related pages
- API reference for the base URL, authentication, and the error format.
- Authenticate with the Speak AI API using access tokens
- Upload audio and video to Speak AI and read insights
- Create and update live transcription sessions
- Analyze text notes with the Speak AI text endpoints
Get an API key on the Speak AI developer page.