Skip to content

Create and manage Speak AI voice agents

Create, list, update, and delete voice agents; the avatar and voice catalogs they draw from; and generating or refining a config from a prompt.

Updated View as MarkdownAsk ClaudeOpen in ChatGPTllms.txt

The Speak AI API exposes 9 voice agents 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.

Create and manage voice agents. Mutations (create/update/delete) require the OWNER or ADMIN role.

What can you do with the voice agents endpoints?

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

Agents

Avatars

Voices

Generation

Agents

List Voice Agents

GET/voice/agents

List Agents

Returns every non-deleted agent in your company, newest first, each annotated with its conversation count.

Response

agents is an array of agent objects, each with an extra conversationCount field: the number of conversations recorded against that agent in your company.

Example request
curl -X GET 'https://api.speakai.co/v1/voice/agents' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.agents object[]
data.agents – 25 more fields
Field Type Description
_id string MongoDB document id, included because every document has one; use agentId to identify it.
agentId string Server-generated UUID. Immutable, sent in the body on create or update is silently dropped.
companyId string Stamped from the caller’s authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent.
userId string Id of the user who created the agent.
name string Required on create. Trimmed, non-empty.
personality string Required on create. Free text describing the agent’s tone. Can be cleared to an empty string on update.
instructions string Required on create. The agent’s system instructions. Can be cleared to an empty string on update.
voice object Required on create.
voice.provider string, required TTS provider, e.g. elevenlabs or openai.
voice.voiceId string, required
voice.model string
stt object Speech-to-text provider config. Shape is not validated beyond being an object.
llm object
llm.provider string Must be one of the voice-agent LLM providers if sent.
llm.model string Must be one of the voice-agent model ids if sent.
liveVoice string The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null.
avatar object Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored, they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.
avatar.avatarId string Required to set an avatar. Must match a row in your company’s avatar catalog (your own uploads or the shared system catalog).
avatar.avatarUrl string Read-only in practice: always overwritten from the matched catalog row.
avatar.provider string Read-only in practice: always overwritten from the matched catalog row.
avatar.tavusFaceId string Read-only: derived server-side from the catalog row’s tavus.faceId. Cannot be set by the client.
avatar.tavusPalId string Read-only: derived server-side from the catalog row’s tavus.palId. Cannot be set by the client.
conversationMode string One of: voice, avatar .
status string One of the agent status values.
chatSettings object
websiteUrl string
enableWebSearch boolean
creativityLevel number
folderId string
telephony object
telephony.enabled boolean
telephony.phoneNumberId string
telephony.handoff object
telephony.settings object
isDeleted boolean DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed.
deletedAt string (date-time)
createdAt string (date-time)
updatedAt string (date-time)
conversationCount integer Count of conversations recorded against this agent.
chatSettings – 7 more fields
Field Type Description
welcomeMessage string
conversationStarters string[]
maxResponseLength integer
topicsToAvoid string[]
maxSessionLength integer
language string
responsePace string One of the response-pace presets, if set.
telephony.handoff – 3 more fields
Field Type
enabled boolean
targetNumber string
summaryPrompt string
telephony.settings – 1 more field
Field Type
recordCalls boolean

Example response, application/json.

{
  "status": "success",
  "data": {
    "agents": [
      {
        "agentId": "6a1b2c3d4e5f60718293a4b5",
        "companyId": "6650a1b2c3d4e5f60000000a",
        "userId": "6650a1b2c3d4e5f60000001a",
        "name": "Support Agent",
        "personality": "Friendly and concise",
        "instructions": "Help callers troubleshoot billing questions.",
        "voice": {
          "provider": "elevenlabs",
          "voiceId": "21m00Tcm4TlvDq8ikWAM"
        },
        "llm": {
          "provider": "openai",
          "model": "gpt-5.4"
        },
        "conversationMode": "voice",
        "status": "active",
        "chatSettings": {
          "language": "en",
          "maxResponseLength": 500,
          "maxSessionLength": 1800,
          "conversationStarters": [],
          "topicsToAvoid": []
        },
        "creativityLevel": 0.7,
        "isDeleted": false,
        "createdAt": "2026-09-01T12:00:00.000Z",
        "updatedAt": "2026-09-23T19:33:24.232Z",
        "conversationCount": 42
      }
    ]
  }
}

Create Voice Agent

POST/voice/agents

Create Agent

Requires the OWNER or ADMIN role.

Request Body

name, personality, instructions, and voice (with voice.provider and voice.voiceId) are required. Every other agent field can be set on create.

Set avatar.avatarId to attach an avatar from your catalog, the server resolves avatarUrl, provider, and any Tavus ids from that catalog row itself; you cannot set those directly.

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
_id string MongoDB document id, included because every document has one; use agentId to identify it.
agentId string Server-generated UUID. Immutable, sent in the body on create or update is silently dropped.
companyId string Stamped from the caller’s authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent.
userId string Id of the user who created the agent.
name string, required Required on create. Trimmed, non-empty.
personality string, required Required on create. Free text describing the agent’s tone. Can be cleared to an empty string on update.
instructions string, required Required on create. The agent’s system instructions. Can be cleared to an empty string on update.
voice object, required Required on create.
voice.provider string, required TTS provider, e.g. elevenlabs or openai.
voice.voiceId string, required
voice.model string
stt object Speech-to-text provider config. Shape is not validated beyond being an object.
llm object
llm.provider string Must be one of the voice-agent LLM providers if sent.
llm.model string Must be one of the voice-agent model ids if sent.
liveVoice string The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null.
avatar object Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored, they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.
avatar.avatarId string Required to set an avatar. Must match a row in your company’s avatar catalog (your own uploads or the shared system catalog).
avatar.avatarUrl string Read-only in practice: always overwritten from the matched catalog row.
avatar.provider string Read-only in practice: always overwritten from the matched catalog row.
avatar.tavusFaceId string Read-only: derived server-side from the catalog row’s tavus.faceId. Cannot be set by the client.
avatar.tavusPalId string Read-only: derived server-side from the catalog row’s tavus.palId. Cannot be set by the client.
conversationMode string One of: voice, avatar .
status string One of the agent status values.
chatSettings object
websiteUrl string
enableWebSearch boolean
creativityLevel number
folderId string
telephony object Accepted on create and, unlike most other server-managed fields, NOT stripped on update – but its shape is not validated by the request schema (any object is accepted as-is), and no other endpoint in this API populates it from a real phone number assignment (that relationship lives on the phone number’s own agentId field – see Phone Numbers). Treat this as a legacy field: writing to it has no confirmed effect.
telephony.enabled boolean
telephony.phoneNumberId string
telephony.handoff object
telephony.settings object
isDeleted boolean DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed.
deletedAt string (date-time)
createdAt string (date-time)
updatedAt string (date-time)
chatSettings – 7 more fields
Field Type Description
welcomeMessage string
conversationStarters string[]
maxResponseLength integer
topicsToAvoid string[]
maxSessionLength integer
language string
responsePace string One of the response-pace presets, if set.
telephony.handoff – 3 more fields
Field Type
enabled boolean
targetNumber string
summaryPrompt string
telephony.settings – 1 more field
Field Type
recordCalls boolean
Example request
curl -X POST 'https://api.speakai.co/v1/voice/agents' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response

201 Created

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.agent object
data.agent – 24 more fields
Field Type Description
_id string MongoDB document id, included because every document has one; use agentId to identify it.
agentId string Server-generated UUID. Immutable, sent in the body on create or update is silently dropped.
companyId string Stamped from the caller’s authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent.
userId string Id of the user who created the agent.
name string Required on create. Trimmed, non-empty.
personality string Required on create. Free text describing the agent’s tone. Can be cleared to an empty string on update.
instructions string Required on create. The agent’s system instructions. Can be cleared to an empty string on update.
voice object Required on create.
voice.provider string, required TTS provider, e.g. elevenlabs or openai.
voice.voiceId string, required
voice.model string
stt object Speech-to-text provider config. Shape is not validated beyond being an object.
llm object
llm.provider string Must be one of the voice-agent LLM providers if sent.
llm.model string Must be one of the voice-agent model ids if sent.
liveVoice string The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null.
avatar object Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored, they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.
avatar.avatarId string Required to set an avatar. Must match a row in your company’s avatar catalog (your own uploads or the shared system catalog).
avatar.avatarUrl string Read-only in practice: always overwritten from the matched catalog row.
avatar.provider string Read-only in practice: always overwritten from the matched catalog row.
avatar.tavusFaceId string Read-only: derived server-side from the catalog row’s tavus.faceId. Cannot be set by the client.
avatar.tavusPalId string Read-only: derived server-side from the catalog row’s tavus.palId. Cannot be set by the client.
conversationMode string One of: voice, avatar .
status string One of the agent status values.
chatSettings object
websiteUrl string
enableWebSearch boolean
creativityLevel number
folderId string
telephony object
telephony.enabled boolean
telephony.phoneNumberId string
telephony.handoff object
telephony.settings object
isDeleted boolean DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed.
deletedAt string (date-time)
createdAt string (date-time)
updatedAt string (date-time)
chatSettings – 7 more fields
Field Type Description
welcomeMessage string
conversationStarters string[]
maxResponseLength integer
topicsToAvoid string[]
maxSessionLength integer
language string
responsePace string One of the response-pace presets, if set.
telephony.handoff – 3 more fields
Field Type
enabled boolean
targetNumber string
summaryPrompt string
telephony.settings – 1 more field
Field Type
recordCalls boolean

Example response, application/json.

{
  "status": "success",
  "data": {
    "agent": {
      "agentId": "6a1b2c3d4e5f60718293a4b5",
      "companyId": "6650a1b2c3d4e5f60000000a",
      "userId": "6650a1b2c3d4e5f60000001a",
      "name": "Support Agent",
      "personality": "Friendly and concise",
      "instructions": "Help callers troubleshoot billing questions.",
      "voice": {
        "provider": "elevenlabs",
        "voiceId": "21m00Tcm4TlvDq8ikWAM"
      },
      "llm": {
        "provider": "openai",
        "model": "gpt-5.4"
      },
      "conversationMode": "voice",
      "status": "active",
      "chatSettings": {
        "language": "en",
        "maxResponseLength": 500,
        "maxSessionLength": 1800,
        "conversationStarters": [],
        "topicsToAvoid": []
      },
      "creativityLevel": 0.7,
      "isDeleted": false,
      "createdAt": "2026-09-01T12:00:00.000Z",
      "updatedAt": "2026-09-23T19:33:24.232Z"
    }
  }
}

400 Validation failed, or avatar.avatarId does not match a catalog row

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"
}

Get Voice Agent

GET/voice/agents/{agentId}

Get Agent

Fetches a single agent by id, scoped to your company. Returns 404 for an agent belonging to another company or one that has been deleted, the response does not distinguish between the two.

Parameters

Parameter In Type Required Description
agentId path string Yes
Example request
curl -X GET 'https://api.speakai.co/v1/voice/agents/AGENT_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.agent object
data.agent – 24 more fields
Field Type Description
_id string MongoDB document id, included because every document has one; use agentId to identify it.
agentId string Server-generated UUID. Immutable, sent in the body on create or update is silently dropped.
companyId string Stamped from the caller’s authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent.
userId string Id of the user who created the agent.
name string Required on create. Trimmed, non-empty.
personality string Required on create. Free text describing the agent’s tone. Can be cleared to an empty string on update.
instructions string Required on create. The agent’s system instructions. Can be cleared to an empty string on update.
voice object Required on create.
voice.provider string, required TTS provider, e.g. elevenlabs or openai.
voice.voiceId string, required
voice.model string
stt object Speech-to-text provider config. Shape is not validated beyond being an object.
llm object
llm.provider string Must be one of the voice-agent LLM providers if sent.
llm.model string Must be one of the voice-agent model ids if sent.
liveVoice string The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null.
avatar object Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored, they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.
avatar.avatarId string Required to set an avatar. Must match a row in your company’s avatar catalog (your own uploads or the shared system catalog).
avatar.avatarUrl string Read-only in practice: always overwritten from the matched catalog row.
avatar.provider string Read-only in practice: always overwritten from the matched catalog row.
avatar.tavusFaceId string Read-only: derived server-side from the catalog row’s tavus.faceId. Cannot be set by the client.
avatar.tavusPalId string Read-only: derived server-side from the catalog row’s tavus.palId. Cannot be set by the client.
conversationMode string One of: voice, avatar .
status string One of the agent status values.
chatSettings object
websiteUrl string
enableWebSearch boolean
creativityLevel number
folderId string
telephony object
telephony.enabled boolean
telephony.phoneNumberId string
telephony.handoff object
telephony.settings object
isDeleted boolean DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed.
deletedAt string (date-time)
createdAt string (date-time)
updatedAt string (date-time)
chatSettings – 7 more fields
Field Type Description
welcomeMessage string
conversationStarters string[]
maxResponseLength integer
topicsToAvoid string[]
maxSessionLength integer
language string
responsePace string One of the response-pace presets, if set.
telephony.handoff – 3 more fields
Field Type
enabled boolean
targetNumber string
summaryPrompt string
telephony.settings – 1 more field
Field Type
recordCalls boolean

Example response, application/json.

{
  "status": "success",
  "data": {
    "agent": {
      "agentId": "6a1b2c3d4e5f60718293a4b5",
      "companyId": "6650a1b2c3d4e5f60000000a",
      "userId": "6650a1b2c3d4e5f60000001a",
      "name": "Support Agent",
      "personality": "Friendly and concise",
      "instructions": "Help callers troubleshoot billing questions.",
      "voice": {
        "provider": "elevenlabs",
        "voiceId": "21m00Tcm4TlvDq8ikWAM"
      },
      "llm": {
        "provider": "openai",
        "model": "gpt-5.4"
      },
      "conversationMode": "voice",
      "status": "active",
      "chatSettings": {
        "language": "en",
        "maxResponseLength": 500,
        "maxSessionLength": 1800,
        "conversationStarters": [],
        "topicsToAvoid": []
      },
      "creativityLevel": 0.7,
      "isDeleted": false,
      "createdAt": "2026-09-01T12:00:00.000Z",
      "updatedAt": "2026-09-23T19:33:24.232Z"
    }
  }
}

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 Voice Agent

PUT/voice/agents/{agentId}

Update Agent

Requires the OWNER or ADMIN role. Partial update, send only the fields you want to change; fields left out of the body are left untouched, including avatar. companyId, agentId, and other immutable fields are silently dropped if sent.

If the body sets avatar.avatarId, the server re-resolves avatarUrl/provider/Tavus ids from the catalog row and overwrites the agent’s whole avatar sub-object with that resolved value; an unresolvable avatarId is rejected with 400 rather than saved.

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
_id string MongoDB document id, included because every document has one; use agentId to identify it.
agentId string Server-generated UUID. Immutable, sent in the body on create or update is silently dropped.
companyId string Stamped from the caller’s authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent.
userId string Id of the user who created the agent.
name string Required on create. Trimmed, non-empty.
personality string Required on create. Free text describing the agent’s tone. Can be cleared to an empty string on update.
instructions string Required on create. The agent’s system instructions. Can be cleared to an empty string on update.
voice object Required on create.
voice.provider string, required TTS provider, e.g. elevenlabs or openai.
voice.voiceId string, required
voice.model string
stt object Speech-to-text provider config. Shape is not validated beyond being an object.
llm object
llm.provider string Must be one of the voice-agent LLM providers if sent.
llm.model string Must be one of the voice-agent model ids if sent.
liveVoice string The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null.
avatar object Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored, they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.
avatar.avatarId string Required to set an avatar. Must match a row in your company’s avatar catalog (your own uploads or the shared system catalog).
avatar.avatarUrl string Read-only in practice: always overwritten from the matched catalog row.
avatar.provider string Read-only in practice: always overwritten from the matched catalog row.
avatar.tavusFaceId string Read-only: derived server-side from the catalog row’s tavus.faceId. Cannot be set by the client.
avatar.tavusPalId string Read-only: derived server-side from the catalog row’s tavus.palId. Cannot be set by the client.
conversationMode string One of: voice, avatar .
status string One of the agent status values.
chatSettings object
websiteUrl string
enableWebSearch boolean
creativityLevel number
folderId string
telephony object Accepted on create and, unlike most other server-managed fields, NOT stripped on update – but its shape is not validated by the request schema (any object is accepted as-is), and no other endpoint in this API populates it from a real phone number assignment (that relationship lives on the phone number’s own agentId field – see Phone Numbers). Treat this as a legacy field: writing to it has no confirmed effect.
telephony.enabled boolean
telephony.phoneNumberId string
telephony.handoff object
telephony.settings object
isDeleted boolean DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed.
deletedAt string (date-time)
createdAt string (date-time)
updatedAt string (date-time)
chatSettings – 7 more fields
Field Type Description
welcomeMessage string
conversationStarters string[]
maxResponseLength integer
topicsToAvoid string[]
maxSessionLength integer
language string
responsePace string One of the response-pace presets, if set.
telephony.handoff – 3 more fields
Field Type
enabled boolean
targetNumber string
summaryPrompt string
telephony.settings – 1 more field
Field Type
recordCalls boolean
Example request
curl -X PUT 'https://api.speakai.co/v1/voice/agents/AGENT_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.agent object
data.agent – 24 more fields
Field Type Description
_id string MongoDB document id, included because every document has one; use agentId to identify it.
agentId string Server-generated UUID. Immutable, sent in the body on create or update is silently dropped.
companyId string Stamped from the caller’s authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent.
userId string Id of the user who created the agent.
name string Required on create. Trimmed, non-empty.
personality string Required on create. Free text describing the agent’s tone. Can be cleared to an empty string on update.
instructions string Required on create. The agent’s system instructions. Can be cleared to an empty string on update.
voice object Required on create.
voice.provider string, required TTS provider, e.g. elevenlabs or openai.
voice.voiceId string, required
voice.model string
stt object Speech-to-text provider config. Shape is not validated beyond being an object.
llm object
llm.provider string Must be one of the voice-agent LLM providers if sent.
llm.model string Must be one of the voice-agent model ids if sent.
liveVoice string The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null.
avatar object Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored, they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.
avatar.avatarId string Required to set an avatar. Must match a row in your company’s avatar catalog (your own uploads or the shared system catalog).
avatar.avatarUrl string Read-only in practice: always overwritten from the matched catalog row.
avatar.provider string Read-only in practice: always overwritten from the matched catalog row.
avatar.tavusFaceId string Read-only: derived server-side from the catalog row’s tavus.faceId. Cannot be set by the client.
avatar.tavusPalId string Read-only: derived server-side from the catalog row’s tavus.palId. Cannot be set by the client.
conversationMode string One of: voice, avatar .
status string One of the agent status values.
chatSettings object
websiteUrl string
enableWebSearch boolean
creativityLevel number
folderId string
telephony object
telephony.enabled boolean
telephony.phoneNumberId string
telephony.handoff object
telephony.settings object
isDeleted boolean DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed.
deletedAt string (date-time)
createdAt string (date-time)
updatedAt string (date-time)
chatSettings – 7 more fields
Field Type Description
welcomeMessage string
conversationStarters string[]
maxResponseLength integer
topicsToAvoid string[]
maxSessionLength integer
language string
responsePace string One of the response-pace presets, if set.
telephony.handoff – 3 more fields
Field Type
enabled boolean
targetNumber string
summaryPrompt string
telephony.settings – 1 more field
Field Type
recordCalls boolean

Example response, application/json.

{
  "status": "success",
  "data": {
    "agent": {
      "agentId": "6a1b2c3d4e5f60718293a4b5",
      "companyId": "6650a1b2c3d4e5f60000000a",
      "userId": "6650a1b2c3d4e5f60000001a",
      "name": "Support Agent",
      "personality": "Friendly and concise",
      "instructions": "Help callers troubleshoot billing questions.",
      "voice": {
        "provider": "elevenlabs",
        "voiceId": "21m00Tcm4TlvDq8ikWAM"
      },
      "llm": {
        "provider": "openai",
        "model": "gpt-5.4"
      },
      "conversationMode": "voice",
      "status": "active",
      "chatSettings": {
        "language": "en",
        "maxResponseLength": 500,
        "maxSessionLength": 1800,
        "conversationStarters": [],
        "topicsToAvoid": []
      },
      "creativityLevel": 0.7,
      "isDeleted": false,
      "createdAt": "2026-09-01T12:00:00.000Z",
      "updatedAt": "2026-09-23T19:33:24.232Z"
    }
  }
}

400 Validation failed, or avatar.avatarId does not match a catalog row visible to your company

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": []
}

Delete Voice Agent

DELETE/voice/agents/{agentId}

Delete Agent

Requires the OWNER or ADMIN role. Soft-deletes: the agent is flagged isDeleted and stops appearing in list/get, but the record and its conversation history are retained.

Parameters

Parameter In Type Required Description
agentId path string Yes
Example request
curl -X DELETE 'https://api.speakai.co/v1/voice/agents/AGENT_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

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

Example response, application/json.

{
  "status": "success",
  "message": "Agent 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 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": []
}

Avatars

List Voice Avatars

GET/voice/avatars

List Avatars

Returns the shared system avatar catalog plus any avatars your company has uploaded, newest first. Another company’s private uploads are never included.

Example request
curl -X GET 'https://api.speakai.co/v1/voice/avatars' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.avatars object[]
data.avatars – 22 more fields
Field Type Description
avatarId string Server-generated UUID on create. Immutable.
companyId string Absent on a shared system-catalog avatar, which every company can read but only Speak can write. Present on a company’s own uploaded avatar.
name string Required on create.
provider string Required on create. One of: bey, tavus, heygen, synthesia, d-id .
imageUrl string
videoUrl string
localImagePath string Local file path used by internal upload flows.
localVideoPath string Local file path used by internal upload flows.
tavus object Set when provider is tavus.
bey object Set when provider is bey.
custom object Set when provider is a custom/self-hosted avatar.
custom.uploadedBy string
custom.originalFileName string
custom.fileSize number
custom.mimeType string
category string Defaults to professional if not sent. One of: professional, casual, stock, custom, premium .
tags string[]
isPremium boolean Defaults to false.
status string Defaults to active. One of: active, inactive, processing, error .
isPublic boolean Defaults to true.
description string
metadata object Arbitrary metadata object. Shape is not validated.
createdBy string Id of the user who created this avatar.
lastSyncedAt string (date-time) Set by the system-catalog sync job for shared avatars.
createdAt string (date-time)
updatedAt string (date-time)
tavus – 7 more fields
Field Type Description
faceId string Required within this object if tavus is sent at all.
palId string
status string One of: started, completed, error .
isRecommended boolean
trainingProgress string
faceType string One of: user, system .
modelType string
bey – 8 more fields
Field Type Description
avatarId string Required within this object if bey is sent at all.
gender string
ethnicity string
voiceId string
ageRange string
style string
isDefault boolean
languageCode string

Example response, application/json.

{
  "status": "success",
  "data": {
    "avatars": [
      {
        "avatarId": "r55e6793f10f",
        "name": "Rae",
        "provider": "tavus",
        "imageUrl": "https://cdn.replica.tavus.io/still.png",
        "tavus": {
          "faceId": "r55e6793f10f",
          "palId": "p135a0c8e542"
        },
        "category": "professional",
        "isPremium": false,
        "status": "active",
        "isPublic": true,
        "createdAt": "2026-08-01T12:00:00.000Z",
        "updatedAt": "2026-08-01T12:00:00.000Z"
      }
    ]
  }
}

Voices

List Voices

GET/voice/voices

List Voices

Lists the voices visible to your company: Speak’s shared system catalog, plus your own company’s uploaded voices, whether public or not.

Example request
curl -X GET 'https://api.speakai.co/v1/voice/voices' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object
data.voices object[]
data.total integer
data.voices – 23 more fields
Field Type Description
_id string MongoDB document id, included because every document has one. Not used to identify a voice anywhere in this API – use voiceId for that.
voiceId string Client-supplied on create if you send one, otherwise server-generated. The identifier for this voice everywhere in this API (unlike most resources, this catalog has no separate server-generated UUID).
companyId string Absent on a shared system-catalog voice, which every company can read but only Speak can write. Present on a company’s own uploaded voice. Not settable directly.
createdBy string Id of the user who created this voice. Not settable directly.
name string Required on create.
provider string Required on create. One of: elevenlabs, openai, deepgram, cartesia, google, azure .
language string Defaults to English.
languageCode string Defaults to en.
gender string One of: male, female, neutral .
age string One of: young, middle-aged, old .
accent string
description string
previewUrl string
category string Defaults to premade. One of: premade, cloned, custom, professional, conversational .
tags string[]
isPremium boolean Defaults to false.
isMultilingual boolean Defaults to false.
isPublic boolean Defaults to true.
status string Defaults to active. One of: active, inactive, processing, error .
providerData object Arbitrary provider-specific data. Shape is not validated.
metadata object Arbitrary metadata object. Shape is not validated.
createdAt string (date-time)
updatedAt string (date-time)

Example response, application/json.

{
  "status": "success",
  "data": {
    "voices": [
      {
        "_id": "6650a1b2c3d4e5f678901234",
        "voiceId": "b2c3d4e5-f678-9012-abcd-ef1234567890",
        "createdBy": "user-1",
        "name": "Rachel",
        "provider": "elevenlabs",
        "language": "English",
        "languageCode": "en",
        "gender": "female",
        "category": "premade",
        "tags": [],
        "isPremium": false,
        "isMultilingual": true,
        "isPublic": true,
        "status": "active",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "updatedAt": "2026-01-01T00:00:00.000Z"
      }
    ],
    "total": 1
  }
}

Generation

Create Agent From Prompt

POST/voice/agents/generation

Create Agent From Prompt

Requires the OWNER or ADMIN role. Prompt-first creation: creates a new agent server-side with placeholder config, then runs the same generation flow as Generate Agent Config against it. Response always includes the new agentId, plus either an agent key (generation succeeded) or needsFollowUp: true (prompt needs more detail) – see Generate Agent Config for both shapes.

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
prompt string, required Required. Describe the agent you want in a sentence or two.
name string
manualInstructions string Skips the thin-prompt follow-up question and generates immediately, folding this in as additional context.
Example request
curl -X POST 'https://api.speakai.co/v1/voice/agents/generation' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response

201 Created

Response body, application/json.

Field Type Description
status string One of: success .
data object

Example response, application/json.

{
  "status": "success",
  "data": {
    "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "agent": {
      "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Support Agent"
    }
  }
}

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 agents"
}

Generate Agent Config

POST/voice/agents/{agentId}/generation/generate

Generate Agent Config

Requires the OWNER or ADMIN role. Runs the prompt-to-config pipeline against an existing agent: extracts a config from prompt via the LLM, and either persists it onto the agent (response has an agent key), or, when the prompt is too thin to act on and manualInstructions was not sent, returns a follow-up question instead (response has needsFollowUp: true) so you can call this again with more detail.

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
prompt string, required Required. Describe the agent you want in a sentence or two.
name string
manualInstructions string Skips the thin-prompt follow-up question and generates immediately, folding this in as additional context.
Example request
curl -X POST 'https://api.speakai.co/v1/voice/agents/AGENT_ID/generation/generate' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response

200 OK

Response body, application/json.

Field Type Description
status string One of: success .
data object

Example response, application/json.

{
  "status": "success",
  "data": {
    "agent": {
      "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Support Agent"
    }
  }
}

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 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": []
}

Get an API key on the Speak AI developer page.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close