PUT /agents/{agentId} for complete agent publishes and PATCH /agents/{agentId} for partial top-level amendments. Both methods follow the same save/version behavior as the Dialgood dashboard. Focused settings and credential endpoints are available for narrower updates.https://api.dialgood.com/partner/v1403.api_token header.404.agentName, design, settings, metadata, and phoneNumbers.metadata.commit_message or metadata.commitMessage when you want a specific version history label.PUT and PATCH currently use the same top-level merge behavior. Omitted top-level fields are preserved by both methods.settings, design, or metadata, replace the stored value for that top-level field. Send the complete intended value of every nested object you include.{
"error": "agent not found"
}| Status | Meaning |
|---|---|
200 | Request succeeded. |
201 | Resource was created. |
400 | Request body is malformed or missing required fields. |
401 | API key is missing or invalid. |
403 | Partner API access is disabled or the authenticated user does not have write access to the agent. |
404 | The requested agent or version was not found for this user. |
500 | Unexpected server error. |
| Parameter | Type | Description |
|---|---|---|
vendor | string | Voice provider. Defaults to elevenlabs; supported values are elevenlabs, deepgram, whisper, microsoft, google, and cartesia. |
page | number | Page number. Defaults to 1. |
limit | number | Voices per page. Defaults to 100. |
gender | string | Filter voices by gender. |
accent | string | Filter voices by accent. |
name | string | Filter voices by a case-insensitive partial name match. |
/voices catalog endpoint currently returns elevenlabs, deepgram, whisper, microsoft, google, and cartesia voices. Agent updates also accept existing Rime voice IDs, but Rime is not currently listed by this endpoint.PATCH /agents/{agentId} or the relevant focused wrapper.owner: false, their rights array, and sharing metadata. Owned agents include owner: true.GET /agents/{agentId}, settings reads, version reads, and call-log reads. Write routes require either ownership or the shared agents right. Credential reads also require agent-control access because they return secret values. Shared agents cannot be deleted through the Partner API.| Parameter | Type | Description |
|---|---|---|
limit | number | Maximum number of agents to return. Defaults to 25. |
skip | number | Number of agents to skip. Defaults to 0. |
{
"agents": [
{
"agentId": "agent_123",
"agentName": "Support Agent",
"userId": "dialgood_user_123",
"owner": true,
"settings": {},
"phoneNumbers": [],
"metadata": {},
"updated_at": "2026-05-24T00:00:00.000Z"
},
{
"agentId": "agent_456",
"agentName": "Shared Sales Agent",
"userId": "owner_user_456",
"owner": false,
"rights": ["view"],
"settings": {},
"phoneNumbers": [],
"metadata": {
"sharedByEmail": "owner@example.com",
"sharedByName": "Owner User",
"sharedAt": "2026-05-24T00:00:00.000Z"
},
"updated_at": "2026-05-24T00:00:00.000Z"
}
],
"totalCount": 2,
"limit": 25,
"skip": 0,
"hasMore": false
}{
"agentName": "Support Agent",
"settings": {
"language": "en"
},
"phoneNumbers": [],
"metadata": {
"commit_message": "Initial partner setup"
}
}{
"agent": {
"agentId": "agent_123",
"agentName": "Support Agent",
"userId": "dialgood_user_123",
"settings": {},
"phoneNumbers": []
}
}{
"agent": {
"agentId": "agent_123",
"agentName": "Support Agent",
"userId": "dialgood_user_123",
"settings": {},
"phoneNumbers": []
}
}agentId, records a new agent version, and preserves the source agent's configuration. Use request body fields to override editable top-level fields such as agentName or metadata.agents right. Protected fields such as agentId, userId, owner, rights, and timestamps are ignored.{
"agentName": "Support Agent Copy",
"metadata": {
"commit_message": "Partner cloned support agent"
}
}{
"agent": {
"agentId": "agent_789",
"agentName": "Support Agent Copy",
"userId": "dialgood_user_123",
"metadata": {
"clonedFromAgentId": "agent_123"
}
}
}PUT when publishing the complete editable agent configuration. Use PATCH when changing selected top-level fields. Both methods immediately update the live agent and automatically create a managed version; there is no separate partner draft state.Credential preservation: General agent reads return masked credential keys rather than secret values. Do not send this masked data back through the agent update endpoint. When an agent already has credentials, update non-secret settings through PATCH /agents/{agentId}/settingsand secret values through the credentials endpoint. Each operation creates a separate managed version.
{
"agentName": "Australian Support Agent",
"design": {
"greeting_message": "Hello, how can I help?",
"summaryContext": "Summarise the conversation in five concise points.",
"knowledgebase": {
"faqs": [],
"website": [],
"text": ""
},
"skills": [
{
"id": "receptionist",
"name": "Receptionist",
"context": "Handle incoming customer enquiries.",
"tasks": [
"Understand the caller's request",
"Answer using the supplied knowledge",
"Use the lookupCustomer tool after the caller provides a customer ID",
"Use the fetchOrderStatus tool when the caller asks about an order"
],
"rules": [
"Keep responses concise",
"Do not invent information"
],
"objectivesString": "Understand the caller's request\nAnswer using the supplied knowledge",
"guidelinesString": "Keep responses concise\nDo not invent information",
"utterances": ["Receptionist"],
"actions": [
{
"type": "In Call",
"action": "Nodejs Function",
"isActive": true,
"webhookName": "lookupCustomer",
"condition": "The caller asks for account details and a customer ID is available.",
"variableName": "customerLookup",
"timeoutMs": 3000,
"invokeTimeoutMs": 4000,
"allowedHosts": [
"api.example.com"
],
"input": {
"baseUrl": "https://api.example.com"
},
"metadata": {
"source": "partner-api"
},
"code": "const customerId = entities.customerId || state.customerId;\n\nif (!customerId) {\n return {\n _reply: 'Please provide your customer ID.',\n _mute: true,\n status: 'missing_customer_id'\n };\n}\n\nconst response = await http.get(`${input.baseUrl}/customers/${customerId}`);\nconst customer = response.data || response;\nstate.customer = customer;\n\nreturn {\n status: 'success',\n customer\n};"
},
{
"type": "Pre Call",
"action": "Webhook",
"isActive": true,
"condition": "Before the call begins.",
"webhookName": "loadCustomerContext",
"webhookDescription": "Load customer context before the conversation starts.",
"webhookVariableName": "customerContext",
"method": "POST",
"url": "https://api.example.com/calls/context",
"headers": [
{
"key": "X-Partner-Account",
"value": "example-account"
}
],
"body": [
{
"key": "source",
"value": "dialgood"
}
]
},
{
"type": "In Call",
"action": "Webhook",
"isActive": true,
"agentResponse": "Please wait while I check that order.",
"webhookName": "fetchOrderStatus",
"webhookDescription": "Retrieve the current status of an order.",
"webhookVariableName": "orderStatus",
"method": "GET",
"url": "https://api.example.com/orders/status",
"headers": [],
"body": []
},
{
"type": "Post Call",
"action": "Webhook",
"isActive": true,
"condition": "After every completed call.",
"webhookName": "publishCallOutcome",
"webhookDescription": "Publish the final call outcome to the partner system.",
"webhookVariableName": "publishedOutcome",
"method": "POST",
"url": "https://api.example.com/calls/outcome",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": [
{
"key": "source",
"value": "dialgood"
}
]
},
{
"type": "In Call",
"action": "Transfer Call",
"isActive": true,
"condition": "The caller asks to speak with a human.",
"agentResponse": "I will transfer you to a team member now.",
"webhookName": "transferToSupport",
"transferTo": "+61390000001",
"callerId": "+61390000000",
"enableFailedTransferConfig": true,
"failedTransferMessage": "I could not connect the transfer.",
"failedTransferEndCall": false,
"enableNoAnswerTransferConfig": true,
"noAnswerTransferMessage": "The team did not answer, so I can continue helping you.",
"noAnswerTransferEndCall": false,
"enableBusyTransferConfig": true,
"busyTransferMessage": "The team is currently busy, so I can continue helping you.",
"busyTransferEndCall": false
}
],
"inbound": true,
"outbound": false,
"default": true,
"isActive": true
}
]
},
"settings": {
"language": "en-AU",
"timezone": "Australia/Melbourne",
"general": {},
"voice": {
"vendor": "microsoft",
"voice_id": "microsoft-natasha",
"language": "en-AU",
"category": "Neural"
},
"raw": {
"synthesizer": {
"vendor": "microsoft",
"voice": "microsoft-natasha",
"language": "en-AU",
"engine": "neural"
},
"recognizer": {
"vendor": "deepgram",
"language": "en-AU",
"model": "nova-2-phonecall",
"deepgramOptions": {
"endpointing": 450,
"utteranceEndMs": 1000,
"smartFormatting": true,
"keywords": []
}
}
},
"telephony": {
"timezone": "Australia/Melbourne",
"model": "nova-2-phonecall",
"pauseDetectionRange": 450,
"smart_formatting": true
}
},
"phoneNumbers": [
"+61390000000"
],
"metadata": {
"commit_message": "Partner publish: updated greeting, voice, and skill actions",
"partnerRevision": "revision-482"
}
}design.skills[].actions. Use the exact, case-sensitive type and action strings shown below.| Dashboard action | type | action | Action-specific fields |
|---|---|---|---|
| Pre-call Webhook | Pre Call | Webhook | condition, webhookName, webhookVariableName, method, url; optional webhookDescription, headers, and POST body |
| In-call Webhook | In Call | Webhook | agentResponse, webhookName, webhookVariableName, method, url; optional webhookDescription, headers, and POST body |
| Post-call Webhook | Post Call | Webhook | condition, webhookName, webhookVariableName, method, url; optional webhookDescription, headers, and POST body |
| Transfer Call | In Call | Transfer Call | condition, agentResponse, webhookName, transferTo; optional callerId, SIP credentials, and failed-transfer handling |
| Cloud Function (js) | In Call | Nodejs Function | condition, webhookName, code; optional variableName, timeouts, allowedHosts, input, and metadata |
isActive; set it to false to retain an action without executing it. condition is a natural-language trigger. In-call Webhooks are the exception: the dashboard removes their condition and exposes them to the agent as tools. Mention each in-call Webhook or Cloud Function webhookName in the skill's task prompt so the agent knows when to use it.method supports GET and POST. headers and POST body are arrays of { "key": "...", "value": "..." } objects. webhookName, webhookVariableName, method, and url are required for every enabled Webhook. In-call Webhook and Cloud Function tool names must be unique within the skill.Transfer Call, transferTo may be an international telephone number or a SIP destination. SIP transfers can also include username and password. The optional failure settings are enableFailedTransferConfig, failedTransferMessage, failedTransferEndCall, enableNoAnswerTransferConfig, noAnswerTransferMessage, noAnswerTransferEndCall, enableBusyTransferConfig, busyTransferMessage, and busyTransferEndCall.agentResponse to 150 characters.actions array.{
"type": "Pre Call",
"action": "Webhook",
"isActive": true,
"condition": "Before the call begins.",
"webhookName": "loadCustomerContext",
"webhookDescription": "Load customer context before the conversation starts.",
"webhookVariableName": "customerContext",
"method": "POST",
"url": "https://api.example.com/calls/context",
"headers": [
{
"key": "X-Partner-Account",
"value": "example-account"
}
],
"body": [
{
"key": "source",
"value": "dialgood"
}
]
}{
"type": "In Call",
"action": "Webhook",
"isActive": true,
"agentResponse": "Please wait while I check that order.",
"webhookName": "fetchOrderStatus",
"webhookDescription": "Retrieve the current status of an order.",
"webhookVariableName": "orderStatus",
"method": "GET",
"url": "https://api.example.com/orders/status",
"headers": [],
"body": []
}condition to an in-call Webhook. Its webhookName and webhookDescription define the tool exposed to the agent, and agentResponse is spoken while it runs.{
"type": "Post Call",
"action": "Webhook",
"isActive": true,
"condition": "After every completed call.",
"webhookName": "publishCallOutcome",
"webhookDescription": "Publish the final call outcome to the partner system.",
"webhookVariableName": "publishedOutcome",
"method": "POST",
"url": "https://api.example.com/calls/outcome",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": [
{
"key": "source",
"value": "dialgood"
}
]
}{
"type": "In Call",
"action": "Transfer Call",
"isActive": true,
"condition": "The caller asks to speak with a human.",
"agentResponse": "I will transfer you to a team member now.",
"webhookName": "transferToSupport",
"transferTo": "+61390000001",
"callerId": "+61390000000",
"enableFailedTransferConfig": true,
"failedTransferMessage": "I could not connect the transfer.",
"failedTransferEndCall": false,
"enableNoAnswerTransferConfig": true,
"noAnswerTransferMessage": "The team did not answer, so I can continue helping you.",
"noAnswerTransferEndCall": false,
"enableBusyTransferConfig": true,
"busyTransferMessage": "The team is currently busy, so I can continue helping you.",
"busyTransferEndCall": false
}{
"type": "In Call",
"action": "Nodejs Function",
"isActive": true,
"webhookName": "checkQuote",
"condition": "The caller asks whether their quote is ready.",
"variableName": "quoteResult",
"timeoutMs": 3000,
"invokeTimeoutMs": 4000,
"allowedHosts": [],
"input": {},
"metadata": {
"source": "partner-api"
},
"code": "state.quoteStatus = 'checked';\n\nreturn {\n _reply: 'Your quote is ready.',\n _mute: true,\n status: 'ready'\n};"
}design.skills[].actions with the exact values type: "In Call" and action: "Nodejs Function". The function is available only while its containing skill is active. Give the tool a unique webhookName within that skill and mention that name in the skill's task prompt so the agent knows when to invoke it.| Field | Required | Description |
|---|---|---|
type | Yes | Must be In Call for a Cloud Function skill action. |
action | Yes | Must be the exact API value Nodejs Function. |
isActive | Yes | Enables or disables the action. |
webhookName | Yes | Tool name exposed to the agent. It must be unique among Cloud Function and in-call Webhook tools in the same skill. |
condition | Yes | Natural-language condition under which the agent may select the tool. |
code | Yes | JavaScript function body. It receives state, entities, transcript, input, metadata, and sandbox HTTP helpers, and must return an object. |
variableName | No | Call-state key where the result is saved. Defaults to webhookName. |
timeoutMs | No | Function execution timeout in milliseconds. Defaults to 3000. |
invokeTimeoutMs | No | How long the backend waits for the invocation. Defaults to timeoutMs + 1000. |
allowedHosts | No | Hostnames the sandbox may call, without paths or protocols. Use an empty array when the function makes no outbound requests. |
input | No | Static JSON object available to the function as input. Defaults to {}. |
metadata | No | Static JSON object available to the function as metadata. Defaults to {}. |
state to update public call state. A returned _reply is spoken directly, _mute: true skips AI interpretation of that result, and _transfer can request a call transfer. Keep secrets out of code, input, and metadata; these fields are stored as part of the agent configuration and its managed versions.microsoft-natasha becomes en-AU-NatashaNeural, and the synthesizer vendor, language, category, and engine are aligned with the Microsoft catalog. Agent updates support elevenlabs, deepgram, whisper, microsoft, google, cartesia, and rime. Unknown custom voice IDs and vendors are preserved.{
"agent": {
"agentId": "agent_123",
"agentName": "Australian Support Agent",
"userId": "dialgood_user_123",
"settings": {
"language": "en-AU",
"voice": {
"vendor": "microsoft",
"voice_id": "en-AU-NatashaNeural",
"language": "en-AU",
"category": "Neural"
},
"raw": {
"synthesizer": {
"vendor": "microsoft",
"voice": "en-AU-NatashaNeural",
"language": "en-AU",
"engine": "neural"
}
}
},
"phoneNumbers": [
"+61390000000"
]
}
}id
agentId
userId
owner
rights
created_at
updated_atversion_id and version_number.version_id or version_number. After publishing, use GET /agents/{agentId}/versions?limit=1 to retrieve the latest version and GET /agents/{agentId}/versions/{versionId} to inspect its complete snapshot.{
"status": true
}PATCH /agents/{agentId} with the intended agent fields.{
"settings": {
"language": "en"
}
}{
"settings": {
"language": "en",
"welcomeMessage": "How can I help?"
}
}{
"language": "en",
"welcomeMessage": "How can I help?"
}{
"settings": {
"language": "en",
"welcomeMessage": "How can I help?"
}
}metadata.commit_message or metadata.commitMessage alongside settings when you want to label the resulting version.{
"credentials": [
{
"key": "SERVICE_API_KEY",
"value": "secret-value"
}
]
}{
"credentials": [
{
"key": "SERVICE_API_KEY",
"value": "new-secret-value"
}
]
}[
{
"key": "SERVICE_API_KEY",
"value": "new-secret-value"
}
]{
"status": true
}metadata.commit_message or metadata.commitMessage alongside credentials when you want to label the resulting version.GET /agents/{agentId} in a complete agent publish. If an agent has stored credentials, use the focused settings endpoint for non-secret settings so omitted credentials remain preserved. A settings update and a credential rotation are separate version-managed operations and each creates its own version.| Parameter | Type | Description |
|---|---|---|
from | number | Start timestamp for the call-log range. |
to | number | End timestamp for the call-log range. |
page | number | Page number. Defaults to 1. |
limit | number | Records per page. Defaults to 10. |
tz | string | Timezone used by the CDR lookup. Defaults to Australia/Melbourne. |
fromnumber | string | Filter by caller number. |
tonumber | string | Filter by destination number. |
status | string | Filter by call status. |
direction | string | Filter by call direction. |
campaign | string | Filter by campaign ID. |
conversationid | string | Filter by conversation ID. |
hidewebcalls | boolean | Set to true to hide web calls. |
{
"data": [
{
"botId": "agent_123",
"conversationId": "conversation_123",
"contactId": "contact_123",
"campaignId": "campaign_123",
"created_at": "2026-05-24T00:00:00.000Z",
"data": {
"from": "+15551234567",
"to": "+15557654321",
"direction": "outbound",
"callStatus": "completed",
"callDuration": 3
}
}
],
"totalPages": 1,
"totalRecords": 1,
"currentPage": 1
}PUT and a public HTTPS URL:{
"url": "https://partner.example/post-call"
}rotateSecret: true is supplied. See Agent Post-call Webhooks for the event and signature contract.updates payload for compactness; fetch a specific version when you need its configuration snapshot.version_id or version_number in an agent update request.| Parameter | Type | Description |
|---|---|---|
limit | number | Maximum number of versions to return. Defaults to 25. |
skip | number | Number of versions to skip. Defaults to 0. |
limit=1&skip=0 to retrieve the latest managed version after a publish.{
"versions": [
{
"version_id": "version_123",
"version_number": 2,
"commit_message": "Partner dashboard update",
"agent_id": "agent_123",
"metadata": {
"user": "Partner User",
"userId": "dialgood_user_123",
"timestamp": 1779560000000
}
}
],
"totalCount": 2,
"limit": 25,
"skip": 0,
"hasMore": false
}{
"version": {
"version_id": "version_123",
"version_number": 2,
"commit_message": "Partner dashboard update",
"agent_id": "agent_123",
"updates": {},
"metadata": {
"user": "Partner User",
"userId": "dialgood_user_123",
"timestamp": 1779560000000
}
}
}GET /agents to map Dialgood agentId values into the partner dashboard.GET /agents/{agentId} before editing so the partner starts from the current configuration.POST /agents if needed.PUT /agents/{agentId}, or amend selected top-level fields with PATCH /agents/{agentId}. Include metadata.commit_message for readable version history. If the agent has stored credentials, exclude settings from this operation and update non-secret settings through the focused settings endpoint.GET /agents/{agentId}/versions?limit=1 to confirm that the publish created a managed version.GET /agents/{agentId} to confirm the final normalized live agent state.GET /agents/{agentId}/call-logs when the partner dashboard needs call activity.api_token values.404 as either a missing agent or an agent that belongs to another Dialgood user.