From af45f6dbb83c3b51c2cf378f93044b0d9a7acd6e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 17:31:06 -0700 Subject: [PATCH 001/171] Update API specifications with fern api update (#648) Co-authored-by: github-actions --- fern/apis/api/openapi.json | 162 ++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 67 deletions(-) diff --git a/fern/apis/api/openapi.json b/fern/apis/api/openapi.json index 0ac803577..f24a120e3 100644 --- a/fern/apis/api/openapi.json +++ b/fern/apis/api/openapi.json @@ -7327,6 +7327,19 @@ "minimum": 0, "maximum": 10, "example": 1 + }, + "excludedStatusCodes": { + "description": "This is the excluded status codes. If the response status code is in this list, the request will not be retried.\nBy default, the request will be retried for any non-2xx status code.", + "example": [ + 400, + 401, + 403, + 404 + ], + "type": "array", + "items": { + "type": "object" + } } }, "required": [ @@ -11424,6 +11437,12 @@ "minimum": 10, "maximum": 43200, "example": 120 + }, + "silenceTimeoutSeconds": { + "type": "number", + "description": "This is the number of seconds of silence to wait before ending the call. Defaults to 30.\n\n@default 30", + "minimum": 10, + "maximum": 3600 } }, "required": [ @@ -25887,6 +25906,22 @@ "SquadMemberDTO": { "type": "object", "properties": { + "assistantDestinations": { + "type": "array", + "description": "These are the other assistants that this assistant can transfer or handoff to.\n\nSupports both:\n- TransferDestinationAssistant: For transfer call tool (legacy)\n- HandoffDestinationAssistant: For handoff tool (recommended)\n\nIf the assistant already has transfer call or handoff tools, these destinations are just appended to existing ones.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationAssistant", + "title": "Transfer Destination" + }, + { + "$ref": "#/components/schemas/HandoffDestinationAssistant", + "title": "Handoff Destination" + } + ] + } + }, "assistantId": { "type": "string", "nullable": true, @@ -25907,13 +25942,6 @@ "$ref": "#/components/schemas/AssistantOverrides" } ] - }, - "assistantDestinations": { - "description": "These are the others assistants that this assistant can transfer to.\n\nIf the assistant already has transfer call tool, these destinations are just appended to existing ones.", - "type": "array", - "items": { - "$ref": "#/components/schemas/TransferDestinationAssistant" - } } } }, @@ -27029,7 +27057,7 @@ "pipeline-error-vapi-429-exceeded-quota", "pipeline-error-vapi-500-server-error", "pipeline-error-vapi-503-server-overloaded-error", - "call.in-progress.error-vapifault-vapi-llm-failed", + "call.in-progress.error-providerfault-vapi-llm-failed", "call.in-progress.error-vapifault-vapi-400-bad-request-validation-failed", "call.in-progress.error-vapifault-vapi-401-unauthorized", "call.in-progress.error-vapifault-vapi-403-model-access-denied", @@ -27072,15 +27100,15 @@ "call.in-progress.error-vapifault-worker-died", "call.in-progress.twilio-completed-call", "call.in-progress.sip-completed-call", - "call.in-progress.error-vapifault-openai-llm-failed", - "call.in-progress.error-vapifault-azure-openai-llm-failed", - "call.in-progress.error-vapifault-groq-llm-failed", - "call.in-progress.error-vapifault-google-llm-failed", - "call.in-progress.error-vapifault-xai-llm-failed", - "call.in-progress.error-vapifault-mistral-llm-failed", - "call.in-progress.error-vapifault-inflection-ai-llm-failed", - "call.in-progress.error-vapifault-cerebras-llm-failed", - "call.in-progress.error-vapifault-deep-seek-llm-failed", + "call.in-progress.error-providerfault-openai-llm-failed", + "call.in-progress.error-providerfault-azure-openai-llm-failed", + "call.in-progress.error-providerfault-groq-llm-failed", + "call.in-progress.error-providerfault-google-llm-failed", + "call.in-progress.error-providerfault-xai-llm-failed", + "call.in-progress.error-providerfault-mistral-llm-failed", + "call.in-progress.error-providerfault-inflection-ai-llm-failed", + "call.in-progress.error-providerfault-cerebras-llm-failed", + "call.in-progress.error-providerfault-deep-seek-llm-failed", "call.in-progress.error-vapifault-chat-pipeline-failed-to-start", "pipeline-error-openai-400-bad-request-validation-failed", "pipeline-error-openai-401-unauthorized", @@ -27212,7 +27240,7 @@ "pipeline-error-anthropic-500-server-error", "pipeline-error-anthropic-503-server-overloaded-error", "pipeline-error-anthropic-llm-failed", - "call.in-progress.error-vapifault-anthropic-llm-failed", + "call.in-progress.error-providerfault-anthropic-llm-failed", "call.in-progress.error-vapifault-anthropic-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-401-unauthorized", "call.in-progress.error-vapifault-anthropic-403-model-access-denied", @@ -27226,7 +27254,7 @@ "pipeline-error-anthropic-bedrock-500-server-error", "pipeline-error-anthropic-bedrock-503-server-overloaded-error", "pipeline-error-anthropic-bedrock-llm-failed", - "call.in-progress.error-vapifault-anthropic-bedrock-llm-failed", + "call.in-progress.error-providerfault-anthropic-bedrock-llm-failed", "call.in-progress.error-vapifault-anthropic-bedrock-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-bedrock-401-unauthorized", "call.in-progress.error-vapifault-anthropic-bedrock-403-model-access-denied", @@ -27240,7 +27268,7 @@ "pipeline-error-anthropic-vertex-500-server-error", "pipeline-error-anthropic-vertex-503-server-overloaded-error", "pipeline-error-anthropic-vertex-llm-failed", - "call.in-progress.error-vapifault-anthropic-vertex-llm-failed", + "call.in-progress.error-providerfault-anthropic-vertex-llm-failed", "call.in-progress.error-vapifault-anthropic-vertex-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-vertex-401-unauthorized", "call.in-progress.error-vapifault-anthropic-vertex-403-model-access-denied", @@ -27254,7 +27282,7 @@ "pipeline-error-together-ai-500-server-error", "pipeline-error-together-ai-503-server-overloaded-error", "pipeline-error-together-ai-llm-failed", - "call.in-progress.error-vapifault-together-ai-llm-failed", + "call.in-progress.error-providerfault-together-ai-llm-failed", "call.in-progress.error-vapifault-together-ai-400-bad-request-validation-failed", "call.in-progress.error-vapifault-together-ai-401-unauthorized", "call.in-progress.error-vapifault-together-ai-403-model-access-denied", @@ -27268,7 +27296,7 @@ "pipeline-error-anyscale-500-server-error", "pipeline-error-anyscale-503-server-overloaded-error", "pipeline-error-anyscale-llm-failed", - "call.in-progress.error-vapifault-anyscale-llm-failed", + "call.in-progress.error-providerfault-anyscale-llm-failed", "call.in-progress.error-vapifault-anyscale-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anyscale-401-unauthorized", "call.in-progress.error-vapifault-anyscale-403-model-access-denied", @@ -27282,7 +27310,7 @@ "pipeline-error-openrouter-500-server-error", "pipeline-error-openrouter-503-server-overloaded-error", "pipeline-error-openrouter-llm-failed", - "call.in-progress.error-vapifault-openrouter-llm-failed", + "call.in-progress.error-providerfault-openrouter-llm-failed", "call.in-progress.error-vapifault-openrouter-400-bad-request-validation-failed", "call.in-progress.error-vapifault-openrouter-401-unauthorized", "call.in-progress.error-vapifault-openrouter-403-model-access-denied", @@ -27296,7 +27324,7 @@ "pipeline-error-perplexity-ai-500-server-error", "pipeline-error-perplexity-ai-503-server-overloaded-error", "pipeline-error-perplexity-ai-llm-failed", - "call.in-progress.error-vapifault-perplexity-ai-llm-failed", + "call.in-progress.error-providerfault-perplexity-ai-llm-failed", "call.in-progress.error-vapifault-perplexity-ai-400-bad-request-validation-failed", "call.in-progress.error-vapifault-perplexity-ai-401-unauthorized", "call.in-progress.error-vapifault-perplexity-ai-403-model-access-denied", @@ -27310,7 +27338,7 @@ "pipeline-error-deepinfra-500-server-error", "pipeline-error-deepinfra-503-server-overloaded-error", "pipeline-error-deepinfra-llm-failed", - "call.in-progress.error-vapifault-deepinfra-llm-failed", + "call.in-progress.error-providerfault-deepinfra-llm-failed", "call.in-progress.error-vapifault-deepinfra-400-bad-request-validation-failed", "call.in-progress.error-vapifault-deepinfra-401-unauthorized", "call.in-progress.error-vapifault-deepinfra-403-model-access-denied", @@ -27324,7 +27352,7 @@ "pipeline-error-runpod-500-server-error", "pipeline-error-runpod-503-server-overloaded-error", "pipeline-error-runpod-llm-failed", - "call.in-progress.error-vapifault-runpod-llm-failed", + "call.in-progress.error-providerfault-runpod-llm-failed", "call.in-progress.error-vapifault-runpod-400-bad-request-validation-failed", "call.in-progress.error-vapifault-runpod-401-unauthorized", "call.in-progress.error-vapifault-runpod-403-model-access-denied", @@ -27338,7 +27366,7 @@ "pipeline-error-custom-llm-500-server-error", "pipeline-error-custom-llm-503-server-overloaded-error", "pipeline-error-custom-llm-llm-failed", - "call.in-progress.error-vapifault-custom-llm-llm-failed", + "call.in-progress.error-providerfault-custom-llm-llm-failed", "call.in-progress.error-vapifault-custom-llm-400-bad-request-validation-failed", "call.in-progress.error-vapifault-custom-llm-401-unauthorized", "call.in-progress.error-vapifault-custom-llm-403-model-access-denied", @@ -47336,7 +47364,7 @@ "pipeline-error-vapi-429-exceeded-quota", "pipeline-error-vapi-500-server-error", "pipeline-error-vapi-503-server-overloaded-error", - "call.in-progress.error-vapifault-vapi-llm-failed", + "call.in-progress.error-providerfault-vapi-llm-failed", "call.in-progress.error-vapifault-vapi-400-bad-request-validation-failed", "call.in-progress.error-vapifault-vapi-401-unauthorized", "call.in-progress.error-vapifault-vapi-403-model-access-denied", @@ -47379,15 +47407,15 @@ "call.in-progress.error-vapifault-worker-died", "call.in-progress.twilio-completed-call", "call.in-progress.sip-completed-call", - "call.in-progress.error-vapifault-openai-llm-failed", - "call.in-progress.error-vapifault-azure-openai-llm-failed", - "call.in-progress.error-vapifault-groq-llm-failed", - "call.in-progress.error-vapifault-google-llm-failed", - "call.in-progress.error-vapifault-xai-llm-failed", - "call.in-progress.error-vapifault-mistral-llm-failed", - "call.in-progress.error-vapifault-inflection-ai-llm-failed", - "call.in-progress.error-vapifault-cerebras-llm-failed", - "call.in-progress.error-vapifault-deep-seek-llm-failed", + "call.in-progress.error-providerfault-openai-llm-failed", + "call.in-progress.error-providerfault-azure-openai-llm-failed", + "call.in-progress.error-providerfault-groq-llm-failed", + "call.in-progress.error-providerfault-google-llm-failed", + "call.in-progress.error-providerfault-xai-llm-failed", + "call.in-progress.error-providerfault-mistral-llm-failed", + "call.in-progress.error-providerfault-inflection-ai-llm-failed", + "call.in-progress.error-providerfault-cerebras-llm-failed", + "call.in-progress.error-providerfault-deep-seek-llm-failed", "call.in-progress.error-vapifault-chat-pipeline-failed-to-start", "pipeline-error-openai-400-bad-request-validation-failed", "pipeline-error-openai-401-unauthorized", @@ -47519,7 +47547,7 @@ "pipeline-error-anthropic-500-server-error", "pipeline-error-anthropic-503-server-overloaded-error", "pipeline-error-anthropic-llm-failed", - "call.in-progress.error-vapifault-anthropic-llm-failed", + "call.in-progress.error-providerfault-anthropic-llm-failed", "call.in-progress.error-vapifault-anthropic-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-401-unauthorized", "call.in-progress.error-vapifault-anthropic-403-model-access-denied", @@ -47533,7 +47561,7 @@ "pipeline-error-anthropic-bedrock-500-server-error", "pipeline-error-anthropic-bedrock-503-server-overloaded-error", "pipeline-error-anthropic-bedrock-llm-failed", - "call.in-progress.error-vapifault-anthropic-bedrock-llm-failed", + "call.in-progress.error-providerfault-anthropic-bedrock-llm-failed", "call.in-progress.error-vapifault-anthropic-bedrock-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-bedrock-401-unauthorized", "call.in-progress.error-vapifault-anthropic-bedrock-403-model-access-denied", @@ -47547,7 +47575,7 @@ "pipeline-error-anthropic-vertex-500-server-error", "pipeline-error-anthropic-vertex-503-server-overloaded-error", "pipeline-error-anthropic-vertex-llm-failed", - "call.in-progress.error-vapifault-anthropic-vertex-llm-failed", + "call.in-progress.error-providerfault-anthropic-vertex-llm-failed", "call.in-progress.error-vapifault-anthropic-vertex-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-vertex-401-unauthorized", "call.in-progress.error-vapifault-anthropic-vertex-403-model-access-denied", @@ -47561,7 +47589,7 @@ "pipeline-error-together-ai-500-server-error", "pipeline-error-together-ai-503-server-overloaded-error", "pipeline-error-together-ai-llm-failed", - "call.in-progress.error-vapifault-together-ai-llm-failed", + "call.in-progress.error-providerfault-together-ai-llm-failed", "call.in-progress.error-vapifault-together-ai-400-bad-request-validation-failed", "call.in-progress.error-vapifault-together-ai-401-unauthorized", "call.in-progress.error-vapifault-together-ai-403-model-access-denied", @@ -47575,7 +47603,7 @@ "pipeline-error-anyscale-500-server-error", "pipeline-error-anyscale-503-server-overloaded-error", "pipeline-error-anyscale-llm-failed", - "call.in-progress.error-vapifault-anyscale-llm-failed", + "call.in-progress.error-providerfault-anyscale-llm-failed", "call.in-progress.error-vapifault-anyscale-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anyscale-401-unauthorized", "call.in-progress.error-vapifault-anyscale-403-model-access-denied", @@ -47589,7 +47617,7 @@ "pipeline-error-openrouter-500-server-error", "pipeline-error-openrouter-503-server-overloaded-error", "pipeline-error-openrouter-llm-failed", - "call.in-progress.error-vapifault-openrouter-llm-failed", + "call.in-progress.error-providerfault-openrouter-llm-failed", "call.in-progress.error-vapifault-openrouter-400-bad-request-validation-failed", "call.in-progress.error-vapifault-openrouter-401-unauthorized", "call.in-progress.error-vapifault-openrouter-403-model-access-denied", @@ -47603,7 +47631,7 @@ "pipeline-error-perplexity-ai-500-server-error", "pipeline-error-perplexity-ai-503-server-overloaded-error", "pipeline-error-perplexity-ai-llm-failed", - "call.in-progress.error-vapifault-perplexity-ai-llm-failed", + "call.in-progress.error-providerfault-perplexity-ai-llm-failed", "call.in-progress.error-vapifault-perplexity-ai-400-bad-request-validation-failed", "call.in-progress.error-vapifault-perplexity-ai-401-unauthorized", "call.in-progress.error-vapifault-perplexity-ai-403-model-access-denied", @@ -47617,7 +47645,7 @@ "pipeline-error-deepinfra-500-server-error", "pipeline-error-deepinfra-503-server-overloaded-error", "pipeline-error-deepinfra-llm-failed", - "call.in-progress.error-vapifault-deepinfra-llm-failed", + "call.in-progress.error-providerfault-deepinfra-llm-failed", "call.in-progress.error-vapifault-deepinfra-400-bad-request-validation-failed", "call.in-progress.error-vapifault-deepinfra-401-unauthorized", "call.in-progress.error-vapifault-deepinfra-403-model-access-denied", @@ -47631,7 +47659,7 @@ "pipeline-error-runpod-500-server-error", "pipeline-error-runpod-503-server-overloaded-error", "pipeline-error-runpod-llm-failed", - "call.in-progress.error-vapifault-runpod-llm-failed", + "call.in-progress.error-providerfault-runpod-llm-failed", "call.in-progress.error-vapifault-runpod-400-bad-request-validation-failed", "call.in-progress.error-vapifault-runpod-401-unauthorized", "call.in-progress.error-vapifault-runpod-403-model-access-denied", @@ -47645,7 +47673,7 @@ "pipeline-error-custom-llm-500-server-error", "pipeline-error-custom-llm-503-server-overloaded-error", "pipeline-error-custom-llm-llm-failed", - "call.in-progress.error-vapifault-custom-llm-llm-failed", + "call.in-progress.error-providerfault-custom-llm-llm-failed", "call.in-progress.error-vapifault-custom-llm-400-bad-request-validation-failed", "call.in-progress.error-vapifault-custom-llm-401-unauthorized", "call.in-progress.error-vapifault-custom-llm-403-model-access-denied", @@ -48530,7 +48558,7 @@ "pipeline-error-vapi-429-exceeded-quota", "pipeline-error-vapi-500-server-error", "pipeline-error-vapi-503-server-overloaded-error", - "call.in-progress.error-vapifault-vapi-llm-failed", + "call.in-progress.error-providerfault-vapi-llm-failed", "call.in-progress.error-vapifault-vapi-400-bad-request-validation-failed", "call.in-progress.error-vapifault-vapi-401-unauthorized", "call.in-progress.error-vapifault-vapi-403-model-access-denied", @@ -48573,15 +48601,15 @@ "call.in-progress.error-vapifault-worker-died", "call.in-progress.twilio-completed-call", "call.in-progress.sip-completed-call", - "call.in-progress.error-vapifault-openai-llm-failed", - "call.in-progress.error-vapifault-azure-openai-llm-failed", - "call.in-progress.error-vapifault-groq-llm-failed", - "call.in-progress.error-vapifault-google-llm-failed", - "call.in-progress.error-vapifault-xai-llm-failed", - "call.in-progress.error-vapifault-mistral-llm-failed", - "call.in-progress.error-vapifault-inflection-ai-llm-failed", - "call.in-progress.error-vapifault-cerebras-llm-failed", - "call.in-progress.error-vapifault-deep-seek-llm-failed", + "call.in-progress.error-providerfault-openai-llm-failed", + "call.in-progress.error-providerfault-azure-openai-llm-failed", + "call.in-progress.error-providerfault-groq-llm-failed", + "call.in-progress.error-providerfault-google-llm-failed", + "call.in-progress.error-providerfault-xai-llm-failed", + "call.in-progress.error-providerfault-mistral-llm-failed", + "call.in-progress.error-providerfault-inflection-ai-llm-failed", + "call.in-progress.error-providerfault-cerebras-llm-failed", + "call.in-progress.error-providerfault-deep-seek-llm-failed", "call.in-progress.error-vapifault-chat-pipeline-failed-to-start", "pipeline-error-openai-400-bad-request-validation-failed", "pipeline-error-openai-401-unauthorized", @@ -48713,7 +48741,7 @@ "pipeline-error-anthropic-500-server-error", "pipeline-error-anthropic-503-server-overloaded-error", "pipeline-error-anthropic-llm-failed", - "call.in-progress.error-vapifault-anthropic-llm-failed", + "call.in-progress.error-providerfault-anthropic-llm-failed", "call.in-progress.error-vapifault-anthropic-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-401-unauthorized", "call.in-progress.error-vapifault-anthropic-403-model-access-denied", @@ -48727,7 +48755,7 @@ "pipeline-error-anthropic-bedrock-500-server-error", "pipeline-error-anthropic-bedrock-503-server-overloaded-error", "pipeline-error-anthropic-bedrock-llm-failed", - "call.in-progress.error-vapifault-anthropic-bedrock-llm-failed", + "call.in-progress.error-providerfault-anthropic-bedrock-llm-failed", "call.in-progress.error-vapifault-anthropic-bedrock-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-bedrock-401-unauthorized", "call.in-progress.error-vapifault-anthropic-bedrock-403-model-access-denied", @@ -48741,7 +48769,7 @@ "pipeline-error-anthropic-vertex-500-server-error", "pipeline-error-anthropic-vertex-503-server-overloaded-error", "pipeline-error-anthropic-vertex-llm-failed", - "call.in-progress.error-vapifault-anthropic-vertex-llm-failed", + "call.in-progress.error-providerfault-anthropic-vertex-llm-failed", "call.in-progress.error-vapifault-anthropic-vertex-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anthropic-vertex-401-unauthorized", "call.in-progress.error-vapifault-anthropic-vertex-403-model-access-denied", @@ -48755,7 +48783,7 @@ "pipeline-error-together-ai-500-server-error", "pipeline-error-together-ai-503-server-overloaded-error", "pipeline-error-together-ai-llm-failed", - "call.in-progress.error-vapifault-together-ai-llm-failed", + "call.in-progress.error-providerfault-together-ai-llm-failed", "call.in-progress.error-vapifault-together-ai-400-bad-request-validation-failed", "call.in-progress.error-vapifault-together-ai-401-unauthorized", "call.in-progress.error-vapifault-together-ai-403-model-access-denied", @@ -48769,7 +48797,7 @@ "pipeline-error-anyscale-500-server-error", "pipeline-error-anyscale-503-server-overloaded-error", "pipeline-error-anyscale-llm-failed", - "call.in-progress.error-vapifault-anyscale-llm-failed", + "call.in-progress.error-providerfault-anyscale-llm-failed", "call.in-progress.error-vapifault-anyscale-400-bad-request-validation-failed", "call.in-progress.error-vapifault-anyscale-401-unauthorized", "call.in-progress.error-vapifault-anyscale-403-model-access-denied", @@ -48783,7 +48811,7 @@ "pipeline-error-openrouter-500-server-error", "pipeline-error-openrouter-503-server-overloaded-error", "pipeline-error-openrouter-llm-failed", - "call.in-progress.error-vapifault-openrouter-llm-failed", + "call.in-progress.error-providerfault-openrouter-llm-failed", "call.in-progress.error-vapifault-openrouter-400-bad-request-validation-failed", "call.in-progress.error-vapifault-openrouter-401-unauthorized", "call.in-progress.error-vapifault-openrouter-403-model-access-denied", @@ -48797,7 +48825,7 @@ "pipeline-error-perplexity-ai-500-server-error", "pipeline-error-perplexity-ai-503-server-overloaded-error", "pipeline-error-perplexity-ai-llm-failed", - "call.in-progress.error-vapifault-perplexity-ai-llm-failed", + "call.in-progress.error-providerfault-perplexity-ai-llm-failed", "call.in-progress.error-vapifault-perplexity-ai-400-bad-request-validation-failed", "call.in-progress.error-vapifault-perplexity-ai-401-unauthorized", "call.in-progress.error-vapifault-perplexity-ai-403-model-access-denied", @@ -48811,7 +48839,7 @@ "pipeline-error-deepinfra-500-server-error", "pipeline-error-deepinfra-503-server-overloaded-error", "pipeline-error-deepinfra-llm-failed", - "call.in-progress.error-vapifault-deepinfra-llm-failed", + "call.in-progress.error-providerfault-deepinfra-llm-failed", "call.in-progress.error-vapifault-deepinfra-400-bad-request-validation-failed", "call.in-progress.error-vapifault-deepinfra-401-unauthorized", "call.in-progress.error-vapifault-deepinfra-403-model-access-denied", @@ -48825,7 +48853,7 @@ "pipeline-error-runpod-500-server-error", "pipeline-error-runpod-503-server-overloaded-error", "pipeline-error-runpod-llm-failed", - "call.in-progress.error-vapifault-runpod-llm-failed", + "call.in-progress.error-providerfault-runpod-llm-failed", "call.in-progress.error-vapifault-runpod-400-bad-request-validation-failed", "call.in-progress.error-vapifault-runpod-401-unauthorized", "call.in-progress.error-vapifault-runpod-403-model-access-denied", @@ -48839,7 +48867,7 @@ "pipeline-error-custom-llm-500-server-error", "pipeline-error-custom-llm-503-server-overloaded-error", "pipeline-error-custom-llm-llm-failed", - "call.in-progress.error-vapifault-custom-llm-llm-failed", + "call.in-progress.error-providerfault-custom-llm-llm-failed", "call.in-progress.error-vapifault-custom-llm-400-bad-request-validation-failed", "call.in-progress.error-vapifault-custom-llm-401-unauthorized", "call.in-progress.error-vapifault-custom-llm-403-model-access-denied", From f36d01983baccba9b2ff62a7f78cab5770e344b3 Mon Sep 17 00:00:00 2001 From: Dan Goosewin Date: Wed, 27 Aug 2025 22:35:02 -0700 Subject: [PATCH 002/171] DEVREL-238: Updates docs to move away from workflows in favor of assistants and squads (#649) * docs(assistants): add appointment scheduling example * docs(assistants): add lead qualification example * docs(squads): add clinic triage & scheduling example * style: add squad badge style and match workflow palette * docs(guides): relink example cards to assistants and squads * docs(quickstart): replace workflows with squads and remove key features card * docs(quickstart): reference squads instead of workflows on web page * docs(assistants): update multilingual agent links to squads * docs(calls): link dynamic transfers to squads property management example * docs(workflows): deprecate workflows in quickstart and overview * docs(workflows): add deprecation warnings to workflow examples * docs(nav): add assistant examples to navigation * docs(assistants): fix cross-links from workflows to squads * docs(assistants): add assistants quickstart page * docs(squads): add ts/python/curl tabs to clinic triage example * docs(squads): add ts/python/curl tabs to ecommerce example * docs(squads): add ts/python/curl tabs to property management example * docs(squads): add ts/python/curl tabs to multilingual example * docs(assistants): add ts/python/curl call tabs to appointment scheduling * docs(assistants): add ts/python/curl call tabs to lead qualification * fix(nav): move workflows lower in the sidebar --- fern/assets/styles.css | 15 +- .../examples/appointment-scheduling.mdx | 277 ++++++++++++++++++ fern/assistants/examples/inbound-support.mdx | 2 +- .../examples/lead-qualification.mdx | 172 +++++++++++ .../examples/multilingual-agent.mdx | 8 +- fern/assistants/quickstart.mdx | 97 ++++++ fern/calls/call-dynamic-transfers.mdx | 4 +- fern/docs.yml | 93 +++--- fern/guides.mdx | 26 +- fern/quickstart/introduction.mdx | 60 ++-- fern/quickstart/web.mdx | 2 +- .../examples/clinic-triage-scheduling.mdx | 183 ++++++++++++ .../examples/ecommerce-order-management.mdx | 103 +++++++ fern/squads/examples/multilingual-support.mdx | 100 +++++++ fern/squads/examples/property-management.mdx | 102 +++++++ .../examples/appointment-scheduling.mdx | 4 + .../examples/clinic-triage-scheduling.mdx | 4 + .../examples/ecommerce-order-management.mdx | 4 + .../workflows/examples/lead-qualification.mdx | 4 + .../examples/multilingual-support.mdx | 4 + .../examples/property-management.mdx | 4 + fern/workflows/overview.mdx | 4 + fern/workflows/quickstart.mdx | 4 + 23 files changed, 1185 insertions(+), 91 deletions(-) create mode 100644 fern/assistants/examples/appointment-scheduling.mdx create mode 100644 fern/assistants/examples/lead-qualification.mdx create mode 100644 fern/assistants/quickstart.mdx create mode 100644 fern/squads/examples/clinic-triage-scheduling.mdx create mode 100644 fern/squads/examples/ecommerce-order-management.mdx create mode 100644 fern/squads/examples/multilingual-support.mdx create mode 100644 fern/squads/examples/property-management.mdx diff --git a/fern/assets/styles.css b/fern/assets/styles.css index 9cf81a30c..ebec09075 100644 --- a/fern/assets/styles.css +++ b/fern/assets/styles.css @@ -31,6 +31,13 @@ border: 1px solid #C7D2FE; } +/* Optional: Squad badge (reuse assistant palette for now) */ +.vapi-badge-squad { + background-color: #EEF2FF; + color: #4338CA; + border: 1px solid #C7D2FE; +} + /* Dark mode adjustments */ :is(.dark) .vapi-badge-assistant { background-color: #134E4A; @@ -44,6 +51,12 @@ border: 1px solid #6366F1; } +:is(.dark) .vapi-badge-squad { + background-color: #312E81; + color: #C7D2FE; + border: 1px solid #6366F1; +} + /* for a grid of videos */ .video-grid { @@ -220,4 +233,4 @@ html.dark button[data-highlighted] .fern-api-property-meta { .light .fern-theme-default.fern-container { background-color: #fff !important; -} +} \ No newline at end of file diff --git a/fern/assistants/examples/appointment-scheduling.mdx b/fern/assistants/examples/appointment-scheduling.mdx new file mode 100644 index 000000000..8fd5c6546 --- /dev/null +++ b/fern/assistants/examples/appointment-scheduling.mdx @@ -0,0 +1,277 @@ +--- +title: Appointment scheduling assistant +subtitle: Build an AI receptionist that books, reschedules, and cancels appointments using Assistants and tools +slug: assistants/examples/appointment-scheduling +description: Build a voice AI appointment scheduling assistant with Google Calendar integration, availability checking, and automated confirmations using Vapi Assistants. +--- + +## Overview + +Build an AI-powered appointment scheduling assistant that handles inbound calls for booking, rescheduling, and canceling appointments. This approach uses a single Assistant with tools for calendar availability, customer lookups, and confirmations. + +**Assistant Capabilities:** +* Real-time availability checks and booking +* Reschedule and cancel with confirmation +* Customer verification and data lookups +* SMS/email confirmations via tools + +**What You'll Build:** +* An assistant with a focused prompt for scheduling flows +* Tools for calendar availability and booking +* Optional CSV knowledge bases for customers/services +* A phone number attached to your assistant + +## Prerequisites + +* A [Vapi account](https://dashboard.vapi.ai/) +* Google Calendar or a scheduling backend + +## 1. Prepare data (optional) + +Use sample CSVs for customers, services, and appointments during development. + + + +
+ + + + + + + + + +
+
+ + + + 1. Open your [Vapi Dashboard](https://dashboard.vapi.ai) → Files + 2. Upload the three CSVs and note their file IDs + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + import fs from "fs"; + + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + async function upload(file: string) { + const res = await vapi.files.create({ file: fs.createReadStream(file) }); + console.log(file, res.id); + return res.id; + } + + const servicesFileId = await upload("services.csv"); + const customersFileId = await upload("customers.csv"); + const appointmentsFileId = await upload("appointments.csv"); + ``` + + + ```python + import requests, os + + def upload(path: str): + r = requests.post( + "https://api.vapi.ai/file", + headers={"Authorization": f"Bearer {os.getenv('VAPI_API_KEY')}"}, + files={"file": open(path, "rb")}, + ) + r.raise_for_status() + print(path, r.json()["id"]) + return r.json()["id"] + + services_file_id = upload("services.csv") + customers_file_id = upload("customers.csv") + appointments_file_id = upload("appointments.csv") + ``` + + + +
+ +--- + +## 2. Create calendar tools + +Use the Google Calendar integration for availability and booking, or your own API via a custom tool. + + + + See: [Google Calendar Integration](/tools/google-calendar) + + Configure tools for: + - `check_availability(service, date)` + - `book_appointment(customer, service, time)` + - `reschedule_appointment(appointmentId, time)` + - `cancel_appointment(appointmentId)` + + + See: [Custom Tools](/tools/custom-tools) + + Define function tools that call your scheduling backend. Attach CSV knowledge bases (customers/services) if using the sample data above. + + + +--- + +## 3. Create the assistant + + + + + + - Go to Assistants → Create Assistant → Blank template + - Name it `Receptionist` + + + ```txt title="System Prompt" maxLines=12 + You are an AI receptionist for a barbershop. Your goals: + 1) Verify the customer + 2) Offer booking, rescheduling, or cancellation + 3) Confirm details and send a confirmation + + When needed, call tools: check_availability, book_appointment, reschedule_appointment, cancel_appointment. + Keep replies under 30 words. Confirm date/time clearly. + ``` + + + Add your scheduling tools to the assistant and publish. + + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + const systemPrompt = `You are an AI receptionist for a barbershop. Verify the customer, then offer booking, rescheduling, or cancellation. Use scheduling tools when needed. Keep replies under 30 words.`; + + const assistant = await vapi.assistants.create({ + name: "Receptionist", + firstMessage: "Welcome to Tony's Barbershop! How can I help you today?", + model: { + provider: "openai", + model: "gpt-4o", + messages: [{ role: "system", content: systemPrompt }], + // toolIds: [ "CHECK_AVAILABILITY_ID", "BOOK_ID", "RESCHEDULE_ID", "CANCEL_ID" ] + } + }); + ``` + + + ```python + from vapi import Vapi + import os + + client = Vapi(token=os.getenv("VAPI_API_KEY")) + + assistant = client.assistants.create( + name="Receptionist", + first_message="Welcome to Tony's Barbershop! How can I help you today?", + model={ + "provider": "openai", + "model": "gpt-4o", + "messages": [{"role": "system", "content": "You are an AI receptionist for a barbershop. Verify the customer, then handle booking/rescheduling/cancel."}] + } + ) + ``` + + + +--- + +## 4. Make calls + + + + ```typescript title="create web call" + import { VapiClient } from "@vapi-ai/server-sdk"; + + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + await vapi.calls.create({ + transport: { type: "web" }, + assistant: { assistantId: "your-assistant-id" } + }); + ``` + + ```typescript title="create phone call" + await vapi.calls.create({ + phoneNumberId: "your-phone-number-id", + customer: { number: "+15551234567" }, + assistant: { assistantId: "your-assistant-id" } + }); + ``` + + + + ```python title="create web call" + import os + from vapi import Vapi + + client = Vapi(token=os.getenv("VAPI_API_KEY")) + + client.calls.create( + transport={"type": "web"}, + assistant_id="your-assistant-id", + ) + ``` + + ```python title="create phone call" + client.calls.create( + phone_number_id="your-phone-number-id", + customer={"number": "+15551234567"}, + assistant_id="your-assistant-id", + ) + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call/web" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "assistant": { "assistantId": "your-assistant-id" } + }' + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "assistant": { "assistantId": "your-assistant-id" }, + "phoneNumberId": "your-phone-number-id", + "customer": { "number": "+15551234567" } + }' + ``` + + + +## 5. Test and validate + + + + Create a phone number and assign your assistant. See [Phone calls quickstart](/quickstart/phone). + + + - New booking → check availability → book → confirm + - Reschedule existing appointment → confirm + - Cancel appointment → confirm + + + +## Next steps + +- **Tools**: [Google Calendar](/tools/google-calendar), [Custom Tools](/tools/custom-tools) +- **Structured outputs**: [Extract structured data](/assistants/structured-outputs) +- **Multichannel**: [Web integration](/quickstart/web) + diff --git a/fern/assistants/examples/inbound-support.mdx b/fern/assistants/examples/inbound-support.mdx index d0b726861..3c10c11c4 100644 --- a/fern/assistants/examples/inbound-support.mdx +++ b/fern/assistants/examples/inbound-support.mdx @@ -1146,7 +1146,7 @@ Consider the reading the following guides to further enhance your assistant: * [**Knowledge Bases**](../knowledge-base/) - Learn more about knowledge bases to build knowledge-based agents. * [**External Integrations**](../tools/) - Configure integrations with [Google Calendar](../tools/google-calendar), [Google Sheets](../tools/google-sheets), [Slack](../tools/slack), etc. -* [**Workflows**](../workflows/) - Learn about workflows to build voice agents for more complex use cases. +* [**Squads**](../squads) - Learn how to compose multiple assistants and transfer seamlessly for complex use cases. Need help? Chat with the team on our [Discord](https://discord.com/invite/pUFNcf2WmH) or mention us on [X/Twitter](https://x.com/Vapi_AI). diff --git a/fern/assistants/examples/lead-qualification.mdx b/fern/assistants/examples/lead-qualification.mdx new file mode 100644 index 000000000..ff761c360 --- /dev/null +++ b/fern/assistants/examples/lead-qualification.mdx @@ -0,0 +1,172 @@ +--- +title: Lead qualification assistant +subtitle: Build an outbound sales assistant that qualifies leads and books meetings using tools +slug: assistants/examples/lead-qualification +description: Build a voice AI outbound sales assistant with BANT data capture, CRM integration, objection handling, and automated follow-ups using Vapi Assistants. +--- + +## Overview + +Create an outbound sales assistant that calls prospects, qualifies them using BANT signals, and books meetings. The assistant uses tools to look up leads, score qualification, update CRM, and schedule on a calendar. + +**Assistant Capabilities:** +* BANT data capture with structured outputs +* Objection handling and call outcome logging +* Calendar booking and follow-up creation +* CRM updates with next steps + +**What You'll Build:** +* Focused sales prompt with clear call flow +* Tools for lead lookup, scoring, CRM update, and scheduling +* Optional CSV knowledge bases for demo leads/products + +## Prerequisites + +* A [Vapi account](https://dashboard.vapi.ai/) +* CRM or spreadsheet data; Google Calendar or scheduling backend + +## 1. Prepare sample data (optional) + + + +
+ + + + + + + + + +
+
+ + + + Upload `leads.csv`, `products.csv`, and `call_outcomes.csv` and note file IDs. + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + import fs from "fs"; + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + async function upload(p: string) { return (await vapi.files.create({ file: fs.createReadStream(p) })).id; } + const leadsFileId = await upload("leads.csv"); + const productsFileId = await upload("products.csv"); + const outcomesFileId = await upload("call_outcomes.csv"); + ``` + + + +
+ +--- + +## 2. Create sales tools + +Configure function tools or your CRM API for: +- `lookup_lead(leadId)` +- `score_lead(budget, authority, need, timeline)` +- `update_crm(leadId, callOutcome, nextSteps)` +- `book_meeting(prospect, time)` + +See [Custom Tools](/tools/custom-tools) and [Google Calendar](/tools/google-calendar). + +--- + +## 3. Define the assistant + + + + + + - Name: `Outbound SDR` + - First message: concise opener asking permission to talk + + + ```txt title="System Prompt" maxLines=12 + You are an outbound SDR. Goals: get permission, qualify with BANT, schedule a meeting, and log the outcome. Keep answers ≤ 25 words and be respectful. Use tools when needed. + ``` + + + Capture: `permission_status`, `bant_budget`, `bant_authority`, `bant_need`, `bant_timeline`, `meeting_time`, `call_outcome`. + See [Structured outputs](/assistants/structured-outputs). + + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + const systemPrompt = `Outbound SDR. Get permission, qualify with BANT, then book. Keep responses short. Use lookup_lead, score_lead, update_crm, book_meeting.`; + const assistant = await vapi.assistants.create({ + name: "Outbound SDR", + firstMessage: "Hi, this is Alex from TechFlow. Is now a good time to chat for 2 minutes?", + model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: systemPrompt }] } + }); + ``` + + + +--- + +## 4. Make calls + + + + ```typescript title="create web call" + import { VapiClient } from "@vapi-ai/server-sdk"; + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + await vapi.calls.create({ transport: { type: "web" }, assistant: { assistantId: "your-assistant-id" } }); + ``` + + ```typescript title="create phone call" + await vapi.calls.create({ phoneNumberId: "your-phone-number-id", customer: { number: "+15551234567" }, assistant: { assistantId: "your-assistant-id" } }); + ``` + + + + ```python title="create web call" + import os + from vapi import Vapi + client = Vapi(token=os.getenv("VAPI_API_KEY")) + client.calls.create(transport={"type": "web"}, assistant_id="your-assistant-id") + ``` + + ```python title="create phone call" + client.calls.create(phone_number_id="your-phone-number-id", customer={"number": "+15551234567"}, assistant_id="your-assistant-id") + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call/web" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ "assistant": { "assistantId": "your-assistant-id" } }' + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ "assistant": { "assistantId": "your-assistant-id" }, "phoneNumberId": "your-phone-number-id", "customer": { "number": "+15551234567" } }' + ``` + + + +## 5. Test outbound calls + +Create a phone number or trigger an outbound call. See [Phone calls](/quickstart/phone). + +## Next steps + +- **CRM integration**: Connect your CRM via [Custom Tools](/tools/custom-tools) +- **Calendar**: [Google Calendar](/tools/google-calendar) +- **Escalation**: Use a [Squad](/squads) to hand off to a specialized closer + diff --git a/fern/assistants/examples/multilingual-agent.mdx b/fern/assistants/examples/multilingual-agent.mdx index 0726fffe5..3a2813bac 100644 --- a/fern/assistants/examples/multilingual-agent.mdx +++ b/fern/assistants/examples/multilingual-agent.mdx @@ -18,7 +18,7 @@ Build a dynamic customer support agent for GlobalTech International that automat * Advanced prompting for cultural context awareness -**Alternative Approach**: For a more structured multilingual experience with explicit language selection, see our [Workflow-based multilingual support](../../workflows/examples/multilingual-support) that guides customers through language selection and dedicated conversation paths. +**Alternative Approach**: For a more structured multilingual experience with explicit language selection, see our [Squad-based multilingual support](../../squads/examples/multilingual-support) that guides customers through language selection and dedicated conversation paths. ## Prerequisites @@ -1082,9 +1082,9 @@ Keep responses concise (under 50 words) while being thorough and helpful.""" --- -## Alternative: Workflow-Based Language Selection +## Alternative: Squad-Based Language Selection -For a more structured approach with explicit language selection, see our comprehensive [Workflow-based multilingual support](../../workflows/examples/multilingual-support) guide. This approach lets customers choose their language at the start of the call, then routes them to dedicated conversation paths optimized for each language. +For a more structured approach with explicit language selection, see our comprehensive [Squad-based multilingual support](../../squads/examples/multilingual-support) guide. This approach lets customers choose their language at the start of the call, then routes them to dedicated conversation paths optimized for each language. @@ -1175,7 +1175,7 @@ Just like that, you've built a dynamic multilingual customer support agent that Consider reading the following guides to further enhance your multilingual implementation: -* [**Workflow-based Multilingual Support**](../../workflows/examples/multilingual-support) - Compare with structured language selection approach +* [**Squad-based Multilingual Support**](../../squads/examples/multilingual-support) - Compare with structured language selection approach * [**Multilingual Configuration Guide**](../../../customization/multilingual) - Learn about all multilingual configuration options * [**Custom Tools**](../../../tools/custom-tools) - Build advanced multilingual tools and integrations diff --git a/fern/assistants/quickstart.mdx b/fern/assistants/quickstart.mdx new file mode 100644 index 000000000..e7c42ba04 --- /dev/null +++ b/fern/assistants/quickstart.mdx @@ -0,0 +1,97 @@ +--- +title: Assistants quickstart +subtitle: Build your first assistant and make a phone call in minutes +slug: assistants/quickstart +--- + +## Overview + +Create a voice assistant with a simple prompt, attach a phone number, and make your first call. You’ll also learn how to add tools to take real actions. + +**In this quickstart, you’ll:** +- Create an assistant (Dashboard or SDK) +- Attach a phone number +- Make inbound and outbound calls + +## Prerequisites + +- A Vapi account and API key + +## 1) Create an assistant + + + + + + Go to the [Vapi Dashboard](https://dashboard.vapi.ai) → Assistants → Create Assistant. + + + ```txt title="System Prompt" maxLines=8 + You are a friendly phone support assistant. Greet the caller and offer help. Keep responses under 30 words. If a transfer is requested, confirm reason first. + ``` + + + Click Publish and then “Talk to Assistant” to validate behavior. + + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + const assistant = await vapi.assistants.create({ + name: "Support Assistant", + firstMessage: "Hello! How can I help you today?", + model: { + provider: "openai", + model: "gpt-4o", + messages: [ + { role: "system", content: "You are a friendly phone support assistant. Keep responses under 30 words." } + ] + } + }); + ``` + + + +## 2) Add a phone number + + + + In the Dashboard, go to Phone Numbers → Create Phone Number → assign your assistant. + + + ```typescript + const number = await vapi.phoneNumbers.create({ + name: "Support Line", + assistantId: assistant.id + }); + ``` + + + +## 3) Make your first calls + + + + Call the phone number you created. Your assistant will answer with the first message. + + + ```typescript + await vapi.calls.create({ + assistantId: assistant.id, + customer: { number: "+1234567890" } + }); + ``` + + + +## Next steps + +- **Add tools**: [Custom tools](/tools/custom-tools) +- **Tune speech**: [Speech configuration](/customization/speech-configuration) +- **Structure data**: [Structured outputs](/assistants/structured-outputs) +- **Move to multi-assistant**: [Squads](/squads) + diff --git a/fern/calls/call-dynamic-transfers.mdx b/fern/calls/call-dynamic-transfers.mdx index 81c256ac6..f3bcb323e 100644 --- a/fern/calls/call-dynamic-transfers.mdx +++ b/fern/calls/call-dynamic-transfers.mdx @@ -429,11 +429,11 @@ Dynamic transfers operate by leaving the destination unspecified initially, then Route customers to appropriate support tiers based on conversation analysis and customer data - +
- **Workflow-based routing** + **Squad-based routing** Direct tenant calls to the right department with automated verification
diff --git a/fern/docs.yml b/fern/docs.yml index d1ae8ee03..b074d0b42 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -118,6 +118,10 @@ navigation: - section: Assistants contents: + # Removed dedicated introduction; Quickstart is the landing + - page: Quickstart + path: assistants/quickstart.mdx + icon: fa-light fa-rocket - section: Core concepts icon: fa-light fa-brain contents: @@ -249,6 +253,12 @@ navigation: - section: Examples icon: fa-light fa-code contents: + - page: Appointment scheduling + path: assistants/examples/appointment-scheduling.mdx + icon: fa-light fa-calendar-check + - page: Lead qualification + path: assistants/examples/lead-qualification.mdx + icon: fa-light fa-phone - page: Inbound support path: assistants/examples/inbound-support.mdx icon: fa-light fa-phone-volume @@ -265,35 +275,28 @@ navigation: path: assistants/examples/multilingual-agent.mdx icon: fa-light fa-globe - - section: Workflows + - section: Squads contents: - page: Quickstart - path: workflows/quickstart.mdx - icon: fa-light fa-rocket + path: squads-example.mdx + icon: fa-light fa-bolt-lightning - page: Overview - path: workflows/overview.mdx + path: squads.mdx icon: fa-light fa-eye - section: Examples icon: fa-light fa-code contents: - - page: Appointment scheduling - path: workflows/examples/appointment-scheduling.mdx - icon: fa-light fa-calendar-check - - page: Lead qualification - path: workflows/examples/lead-qualification.mdx - icon: fa-light fa-money-bill-wave - - page: Medical triage - path: workflows/examples/clinic-triage-scheduling.mdx - icon: fa-light fa-stethoscope - - page: Order management - path: workflows/examples/ecommerce-order-management.mdx - icon: fa-light fa-shopping-cart - - page: Property management - path: workflows/examples/property-management.mdx - icon: fa-light fa-building + - page: Clinic triage & scheduling + path: squads/examples/clinic-triage-scheduling.mdx + - page: E-commerce order management + path: squads/examples/ecommerce-order-management.mdx + - page: Property management routing + path: squads/examples/property-management.mdx - page: Multilingual support - path: workflows/examples/multilingual-support.mdx - icon: fa-light fa-globe + path: squads/examples/multilingual-support.mdx + - page: Silent transfers + path: squads/silent-transfers.mdx + icon: fa-light fa-arrow-right-arrow-left - section: Best practices contents: @@ -405,17 +408,7 @@ navigation: - page: Call recording path: assistants/call-recording.mdx icon: fa-light fa-circle-dot - - section: Squads - collapsed: true - icon: fa-light fa-users - path: squads.mdx - contents: - - page: Quickstart - path: squads-example.mdx - icon: fa-light fa-bolt-lightning - - page: Silent transfers - path: squads/silent-transfers.mdx - icon: fa-light fa-arrow-right-arrow-left + # Squads moved to top-level section - section: Outbound Campaigns contents: @@ -463,6 +456,36 @@ navigation: - page: Server authentication path: server-url/server-authentication.mdx + - section: Workflows + contents: + - page: Quickstart + path: workflows/quickstart.mdx + icon: fa-light fa-rocket + - page: Overview + path: workflows/overview.mdx + icon: fa-light fa-eye + - section: Examples + icon: fa-light fa-code + contents: + - page: Appointment scheduling + path: workflows/examples/appointment-scheduling.mdx + icon: fa-light fa-calendar-check + - page: Lead qualification + path: workflows/examples/lead-qualification.mdx + icon: fa-light fa-money-bill-wave + - page: Medical triage + path: workflows/examples/clinic-triage-scheduling.mdx + icon: fa-light fa-stethoscope + - page: Order management + path: workflows/examples/ecommerce-order-management.mdx + icon: fa-light fa-shopping-cart + - page: Property management + path: workflows/examples/property-management.mdx + icon: fa-light fa-building + - page: Multilingual support + path: workflows/examples/multilingual-support.mdx + icon: fa-light fa-globe + - section: Resources collapsed: false contents: @@ -928,7 +951,7 @@ redirects: - source: /overview destination: /quickstart - source: /assistants - destination: /api-reference/assistants/create + destination: /assistants/quickstart - source: /examples/outbound-sales destination: /workflows/examples/lead-qualification - source: /workflows @@ -985,7 +1008,9 @@ redirects: - source: /docs/transcription destination: /customization/custom-transcriber - source: /docs/assistants - destination: /quickstart/introduction + destination: /assistants/quickstart + - source: /assistants/overview + destination: /assistants/quickstart - source: /docs/tools destination: /tools - source: /docs/squads diff --git a/fern/guides.mdx b/fern/guides.mdx index 7bf7da56a..c8bd960cf 100644 --- a/fern/guides.mdx +++ b/fern/guides.mdx @@ -1,6 +1,6 @@ --- title: Guides -subtitle: Explore real-world, cloneable examples to build voice agents with Vapi. Now including new Workflow-based guides! +subtitle: Explore real-world, cloneable examples to build voice agents with Assistants and Squads slug: guides --- @@ -9,51 +9,51 @@ slug: guides - +
-
Built with Workflows
+
Built with Assistants

Build an appointment scheduling assistant that can schedule appointments for a barbershop
- +
-
Built with Workflows
+
Built with Squads

Build a medical triage and scheduling assistant that can triage patients and schedule appointments for a clinic
- +
-
Built with Workflows
+
Built with Squads

Build an ecommerce order management assistant that can track orders and process returns
- +
-
Built with Workflows
+
Built with Squads

Build a call routing workflow that dynamically routes tenant calls based on verification and inquiry type
- +
-
Built with Workflows
+
Built with Assistants

Create an outbound sales agent that can schedule appointments automatically
- +
-
Built with Workflows
+
Built with Squads

Build a structured multilingual support workflow with language selection and dedicated conversation paths
diff --git a/fern/quickstart/introduction.mdx b/fern/quickstart/introduction.mdx index eb01c0e4f..99fc8e800 100644 --- a/fern/quickstart/introduction.mdx +++ b/fern/quickstart/introduction.mdx @@ -34,40 +34,40 @@ You have full control over each component, with dozens of providers and models t ## Two ways to build voice agents -Vapi offers two main primitives for building voice agents, each designed for different use cases: +Vapi offers two main primitives, designed for different use cases:
- **Best for:** Quick kickstart for simple conversations + **Best for:** Most use cases and fast iteration
- Assistants use a single system prompt to control behavior. Perfect for: - - Customer support chatbots - - Simple question-answering agents - - Getting started quickly with minimal setup + Assistants use a single system prompt plus tools and structured outputs. Perfect for: + - Customer support + - Lead qualification + - Booking and routing
- **Best for:** Complex logic and multi-step processes + **Best for:** Multi-assistant setups with specialization
- Workflows use visual decision trees and conditional logic. Perfect for: - - Appointment scheduling with availability checks - - Lead qualification with branching questions - - Complex customer service flows with escalation + Squads orchestrate multiple assistants with context-preserving transfers. Ideal for: + - Medical triage and scheduling + - E‑commerce orders, returns, VIP + - Property management routing
@@ -77,7 +77,7 @@ Vapi offers two main primitives for building voice agents, each designed for dif - **Phone integration:** Make and receive calls on any phone number - **Web integration:** Embed voice calls directly in your applications - **Tool integration:** Connect to your APIs, databases, and existing systems -- **Custom workflows:** Build complex multi-step processes with decision trees +- **Multi-assistant orchestration (Squads):** Compose specialized assistants with seamless transfers ## Choose your path @@ -120,7 +120,7 @@ Vapi offers two main primitives for building voice agents, each designed for dif The Vapi CLI brings the full power of the platform to your terminal: - + - - - **Project Integration:** Auto-detect and set up Vapi in any codebase - - **Webhook Forwarding:** Test webhooks on your local server - - **MCP Support:** Turn your IDE into a Vapi expert - - **Multi-account:** Switch between environments seamlessly - ## Popular use cases @@ -168,12 +158,12 @@ The Vapi CLI brings the full power of the platform to your terminal: title="Sales & Lead Qualification" icon="phone-office" iconType="solid" - href="/workflows/examples/lead-qualification" + href="/assistants/examples/lead-qualification" >
-
Built with Workflows
+
Built with Assistants
Make outbound sales calls, qualify leads, and schedule appointments with sophisticated branching logic.
@@ -181,12 +171,12 @@ The Vapi CLI brings the full power of the platform to your terminal: title="Appointment Scheduling" icon="calendar-check" iconType="solid" - href="/workflows/examples/appointment-scheduling" + href="/assistants/examples/appointment-scheduling" >
-
Built with Workflows
+
Built with Assistants
Handle booking requests, check availability, and confirm appointments with conditional routing.
@@ -194,12 +184,12 @@ The Vapi CLI brings the full power of the platform to your terminal: title="Medical Triage & Scheduling" icon="stethoscope" iconType="solid" - href="/workflows/examples/clinic-triage-scheduling" + href="/squads/examples/clinic-triage-scheduling" >
-
Built with Workflows
+
Built with Squads
Emergency routing and appointment scheduling for healthcare.
@@ -207,12 +197,12 @@ The Vapi CLI brings the full power of the platform to your terminal: title="E-commerce Order Management" icon="shopping-cart" iconType="solid" - href="/workflows/examples/ecommerce-order-management" + href="/squads/examples/ecommerce-order-management" >
-
Built with Workflows
+
Built with Squads
Order tracking, returns, and customer support workflows.
diff --git a/fern/quickstart/web.mdx b/fern/quickstart/web.mdx index c616563af..77f7b8de8 100644 --- a/fern/quickstart/web.mdx +++ b/fern/quickstart/web.mdx @@ -1260,7 +1260,7 @@ Now that you understand both client and server SDK capabilities: - **Explore use cases:** Check out our [examples section](/assistants/examples/inbound-support) for complete implementations - **Add tools:** Connect your voice agents to external APIs and databases with [custom tools](/tools/custom-tools) - **Configure models:** Try different [speech and language models](/assistants/speech-configuration) for better performance -- **Scale with workflows:** Use [Vapi workflows](/workflows/quickstart) for complex multi-step processes +- **Scale with squads:** Use [Squads](/squads) for multi-assistant setups and complex processes ## Resources diff --git a/fern/squads/examples/clinic-triage-scheduling.mdx b/fern/squads/examples/clinic-triage-scheduling.mdx new file mode 100644 index 000000000..79efa948e --- /dev/null +++ b/fern/squads/examples/clinic-triage-scheduling.mdx @@ -0,0 +1,183 @@ +--- +title: Clinic triage and scheduling squad +subtitle: Route patients between triage, emergency, and scheduler assistants with context-preserving transfers +slug: squads/examples/clinic-triage-scheduling +description: Build a multi-assistant clinic experience with specialized assistants for triage, emergency handling, and scheduling using Squads. +--- + +## Overview + +Compose multiple assistants into a Squad for safe, specialized healthcare flows: a triage assistant assesses symptoms, an emergency assistant handles urgent cases, and a scheduler books appointments. + +**Squad Capabilities:** +* Structured triage evaluation and safety gates +* Emergency detection → immediate handoff +* Provider matching and scheduling tools +* Transfers preserve full conversation context + +## 1. Define members + + +```json title="Example squad payload" +{ + "members": [ + { "assistant": { "name": "Triage", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Medical triage assistant. Identify red flags."}] }, "firstMessage": "Hello, how can I help you today?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Emergency", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Emergency protocol assistant. Keep interaction brief and connect immediately."}] } } }, + { "assistant": { "name": "Scheduler", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Clinic scheduler. Offer next available slots, then confirm."}] }, "toolIds": ["BOOK_TOOL_ID", "PROVIDER_LOOKUP_ID"] } } + ] +} +``` + + +## 2. Configure transfers + +- From Triage → Emergency when red flags detected +- From Triage → Scheduler for routine care +- Warm-transfer with a short summary for human escalation + +See: [Silent transfers](/squads/silent-transfers). + +## 3. Implement + + + + ```typescript title="create web call with transient squad" + import { VapiClient } from "@vapi-ai/server-sdk"; + + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + await vapi.calls.create({ + transport: { type: "web" }, + squad: { + members: [ + { + assistant: { + name: "Triage", + model: { + provider: "openai", + model: "gpt-4o", + messages: [{ role: "system", content: "Medical triage assistant. Identify red flags." }], + }, + firstMessage: "Hello, how can I help you today?", + firstMessageMode: "assistant-speaks-first", + }, + }, + { + assistant: { + name: "Emergency", + model: { + provider: "openai", + model: "gpt-4o", + messages: [{ role: "system", content: "Emergency protocol assistant. Keep interaction brief and connect immediately." }], + }, + }, + }, + { + assistant: { + name: "Scheduler", + model: { + provider: "openai", + model: "gpt-4o", + messages: [{ role: "system", content: "Clinic scheduler. Offer next available slots, then confirm." }], + }, + }, + }, + ], + }, + }); + ``` + + ```typescript title="create phone call with transient squad" + await vapi.calls.create({ + phoneNumberId: "YOUR_PHONE_NUMBER_ID", + customer: { number: "+15551234567" }, + squad: { /* same squad as above */ members: [] }, + }); + ``` + + ```typescript title="create and reuse a squad (optional)" + const squad = await vapi.squads.create({ + name: "Clinic Triage", + members: [ /* same members as above */ ], + }); + + await vapi.calls.create({ transport: { type: "web" }, squadId: squad.id }); + ``` + + + + ```python title="create web call with transient squad" + import os + from vapi import Vapi + + client = Vapi(token=os.getenv("VAPI_API_KEY")) + + client.calls.create( + transport={"type": "web"}, + squad={ + "members": [ + {"assistant": {"name": "Triage", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Medical triage assistant. Identify red flags."}]}, "first_message": "Hello, how can I help you today?", "first_message_mode": "assistant-speaks-first"}}, + {"assistant": {"name": "Emergency", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Emergency protocol assistant. Keep interaction brief and connect immediately."}]}}}, + {"assistant": {"name": "Scheduler", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Clinic scheduler. Offer next available slots, then confirm."}]}}}, + ] + }, + ) + ``` + + ```python title="create phone call with transient squad" + client.calls.create( + phone_number_id="YOUR_PHONE_NUMBER_ID", + customer={"number": "+15551234567"}, + squad={"members": []}, # same members as above + ) + ``` + + ```python title="create and reuse a squad (optional)" + squad = client.squads.create( + name="Clinic Triage", + members=[ /* same members as above */ ], + ) + client.calls.create(transport={"type": "web"}, squad_id=squad["id"]) + ``` + + + + ```bash title="create web call" + curl -X POST "https://api.vapi.ai/call/web" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "squad": { + "members": [ + { "assistant": { "name": "Triage", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Medical triage assistant. Identify red flags."}] }, "firstMessage": "Hello, how can I help you today?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Emergency", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Emergency protocol assistant. Keep interaction brief and connect immediately."}] } } }, + { "assistant": { "name": "Scheduler", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Clinic scheduler. Offer next available slots, then confirm."}] } } } + ] + } + }' + ``` + + + + ```bash title="create phone call" + curl -X POST "https://api.vapi.ai/call" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "phoneNumberId": "YOUR_PHONE_NUMBER_ID", + "customer": { "number": "+15551234567" }, + "squad": { "members": [] } + }' + ``` + + + +## 4. Test + +Attach a phone number to the Squad (or start with a Squad when creating a call) and test urgent vs routine scenarios. + +## Next steps + +- **Tools**: [Custom Tools](/tools/custom-tools) +- **Scheduling**: [Google Calendar](/tools/google-calendar) + diff --git a/fern/squads/examples/ecommerce-order-management.mdx b/fern/squads/examples/ecommerce-order-management.mdx new file mode 100644 index 000000000..eff0f659b --- /dev/null +++ b/fern/squads/examples/ecommerce-order-management.mdx @@ -0,0 +1,103 @@ +--- +title: E‑commerce order management squad +subtitle: Separate assistants for orders, returns, and VIP concierge with intelligent transfers +slug: squads/examples/ecommerce-order-management +description: Build a multi-assistant experience for order tracking, returns processing, and VIP handling using Squads. +--- + +## Overview + +Use Squads to split responsibilities: an Orders assistant handles tracking/status, a Returns assistant manages eligibility and labels, and a VIP assistant provides white‑glove support. + +**Squad Capabilities:** +* Order lookup and status updates +* Return eligibility and label creation +* VIP routing and concierge service +* Context‑preserving warm transfers + +## 1. Define members + + +```json title="Example squad payload" +{ + "members": [ + { "assistant": { "name": "Orders", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Orders specialist. Handle tracking and delivery questions."}] }, "toolIds": ["ORDER_LOOKUP_ID"], "firstMessage": "Hello, how can I help with your order?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Returns", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Returns specialist. Check eligibility and generate labels."}] }, "toolIds": ["RETURNS_TOOL_ID"] } }, + { "assistant": { "name": "VIP", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "VIP concierge. Prioritize premium customers and coordinate resolutions."}] } } } + ] +} +``` + + +## 2. Configure transfer rules + +- Orders → Returns for return requests +- Any → VIP for high‑value customers or sentiment issues +- Warm-transfer summary for human agents if needed + +## 3. Implement + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + await vapi.calls.create({ + transport: { type: "web" }, + squad: { + members: [ + { assistant: { name: "Orders", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Orders specialist. Handle tracking and delivery questions." }] }, firstMessage: "Hello, how can I help with your order?", firstMessageMode: "assistant-speaks-first" } }, + { assistant: { name: "Returns", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Returns specialist. Check eligibility and generate labels." }] } } }, + { assistant: { name: "VIP", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "VIP concierge. Prioritize premium customers and coordinate resolutions." }] } } } + ], + }, + }); + ``` + + + + ```python + import os + from vapi import Vapi + + client = Vapi(token=os.getenv("VAPI_API_KEY")) + client.calls.create( + transport={"type": "web"}, + squad={ + "members": [ + {"assistant": {"name": "Orders", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Orders specialist. Handle tracking and delivery questions."}]}, "first_message": "Hello, how can I help with your order?", "first_message_mode": "assistant-speaks-first"}}, + {"assistant": {"name": "Returns", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Returns specialist. Check eligibility and generate labels."}]}}}, + {"assistant": {"name": "VIP", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "VIP concierge. Prioritize premium customers and coordinate resolutions."}]}}}, + ] + }, + ) + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call/web" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "squad": { + "members": [ + { "assistant": { "name": "Orders", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Orders specialist. Handle tracking and delivery questions."}] }, "firstMessage": "Hello, how can I help with your order?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Returns", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Returns specialist. Check eligibility and generate labels."}] } } }, + { "assistant": { "name": "VIP", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "VIP concierge. Prioritize premium customers and coordinate resolutions."}] } } } + ] + } + }' + ``` + + + +## 4. Test and validate + +Attach a phone number to the Squad and simulate order, return, and VIP scenarios. + +## Next steps + +- **Custom Tools**: [Build tools](/tools/custom-tools) + diff --git a/fern/squads/examples/multilingual-support.mdx b/fern/squads/examples/multilingual-support.mdx new file mode 100644 index 000000000..e40c84e24 --- /dev/null +++ b/fern/squads/examples/multilingual-support.mdx @@ -0,0 +1,100 @@ +--- +title: Multilingual support squad +subtitle: Use language‑specific assistants with selection and seamless context handoff +slug: squads/examples/multilingual-support +description: Build a Squad with dedicated English, Spanish, and French assistants and a language selection entrance flow. +--- + +## Overview + +Provide structured multilingual support using a Squad: present a short language selection, then route to dedicated EN/ES/FR assistants with tuned prompts and voices. + +**Squad Capabilities:** +* Explicit language choice for clarity +* Language‑specific prompts and voices +* Seamless transfers while preserving context + +## 1. Define members + + +```json title="Example squad payload" +{ + "members": [ + { "assistant": { "name": "English Support", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "English support. Direct, friendly, professional."}] }, "voice": {"provider": "azure", "voiceId": "en-US-AriaNeural"}, "firstMessage": "Hello! How can I help you today?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Soporte Español", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Soporte en español. Cálido y respetuoso; usa 'usted' inicialmente."}] }, "voice": {"provider": "azure", "voiceId": "es-ES-ElviraNeural"} } }, + { "assistant": { "name": "Support Français", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Support français. Poli, courtois et formel."}] }, "voice": {"provider": "azure", "voiceId": "fr-FR-DeniseNeural"} } } + ] +} +``` + + +## 2. Entrance flow + +Start with a brief selection (EN/ES/FR). Route to the matching assistant. Optionally auto‑detect and confirm. + +## 3. Implement + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + await vapi.calls.create({ + transport: { type: "web" }, + squad: { + members: [ + { assistant: { name: "English Support", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "English support. Direct, friendly, professional." }] }, voice: { provider: "azure", voiceId: "en-US-AriaNeural" }, firstMessage: "Hello! How can I help you today?", firstMessageMode: "assistant-speaks-first" } }, + { assistant: { name: "Soporte Español", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Soporte en español. Cálido y respetuoso; usa 'usted' inicialmente." }] }, voice: { provider: "azure", voiceId: "es-ES-ElviraNeural" } } }, + { assistant: { name: "Support Français", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Support français. Poli, courtois et formel." }] }, voice: { provider: "azure", voiceId: "fr-FR-DeniseNeural" } } } + ], + }, + }); + ``` + + + + ```python + import os + from vapi import Vapi + + client = Vapi(token=os.getenv("VAPI_API_KEY")) + client.calls.create( + transport={"type": "web"}, + squad={ + "members": [ + {"assistant": {"name": "English Support", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "English support. Direct, friendly, professional."}]}, "voice": {"provider": "azure", "voiceId": "en-US-AriaNeural"}, "first_message": "Hello! How can I help you today?", "first_message_mode": "assistant-speaks-first"}}, + {"assistant": {"name": "Soporte Español", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Soporte en español. Cálido y respetuoso; usa 'usted' inicialmente."}]}, "voice": {"provider": "azure", "voiceId": "es-ES-ElviraNeural"}}}, + {"assistant": {"name": "Support Français", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Support français. Poli, courtois et formel."}]}, "voice": {"provider": "azure", "voiceId": "fr-FR-DeniseNeural"}}}, + ] + }, + ) + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call/web" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "squad": { + "members": [ + { "assistant": { "name": "English Support", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "English support. Direct, friendly, professional."}] }, "voice": {"provider": "azure", "voiceId": "en-US-AriaNeural"}, "firstMessage": "Hello! How can I help you today?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Soporte Español", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Soporte en español. Cálido y respetuoso; usa 'usted' inicialmente."}] }, "voice": {"provider": "azure", "voiceId": "es-ES-ElviraNeural" } } }, + { "assistant": { "name": "Support Français", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Support français. Poli, courtois et formel."}] }, "voice": {"provider": "azure", "voiceId": "fr-FR-DeniseNeural" } } } + ] + } + }' + ``` + + + +## 4. Test + +Create a phone number for the Squad and test each language path. + +## Next steps + +- **Assistant alternative**: [Multilingual agent](/assistants/examples/multilingual-agent) + diff --git a/fern/squads/examples/property-management.mdx b/fern/squads/examples/property-management.mdx new file mode 100644 index 000000000..3e6b93e30 --- /dev/null +++ b/fern/squads/examples/property-management.mdx @@ -0,0 +1,102 @@ +--- +title: Property management routing squad +subtitle: Route maintenance vs leasing with a router assistant and domain specialists +slug: squads/examples/property-management +description: Build a property management Squad with a router assistant plus maintenance and leasing specialists for accurate transfers. +--- + +## Overview + +Replace visual flows with a Squad: a Router assistant classifies the inquiry and transfers to Maintenance or Leasing specialists. Use a dynamic transfer tool for human escalation. + +**Squad Capabilities:** +* Tenant verification and inquiry classification +* Maintenance vs leasing specialist assistants +* Human transfer with warm summary when needed + +## 1. Define members + + +```json title="Example squad payload" +{ + "members": [ + { "assistant": { "name": "Router", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Classify tenant inquiries: emergency, maintenance, leasing, rent, general. Transfer accordingly."}] }, "toolIds": ["TENANT_LOOKUP_ID"], "firstMessage": "Thanks for calling. How can I help?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Maintenance", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Maintenance specialist. Collect details and prioritize emergencies."}] } } }, + { "assistant": { "name": "Leasing", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Leasing specialist. Answer leasing and rent questions."}] } } } + ] +} +``` + + +## 2. Transfers and escalation + +- Router → Maintenance for emergency/maintenance +- Router → Leasing for leasing/rent/general +- Dynamic transfer tool for human dispatch + +## 3. Implement + + + + ```typescript + import { VapiClient } from "@vapi-ai/server-sdk"; + const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + + await vapi.calls.create({ + transport: { type: "web" }, + squad: { + members: [ + { assistant: { name: "Router", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Classify tenant inquiries: emergency, maintenance, leasing, rent, general. Transfer accordingly." }] }, firstMessage: "Thanks for calling. How can I help?", firstMessageMode: "assistant-speaks-first" } }, + { assistant: { name: "Maintenance", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Maintenance specialist. Collect details and prioritize emergencies." }] } } }, + { assistant: { name: "Leasing", model: { provider: "openai", model: "gpt-4o", messages: [{ role: "system", content: "Leasing specialist. Answer leasing and rent questions." }] } } } + ], + }, + }); + ``` + + + + ```python + import os + from vapi import Vapi + + client = Vapi(token=os.getenv("VAPI_API_KEY")) + client.calls.create( + transport={"type": "web"}, + squad={ + "members": [ + {"assistant": {"name": "Router", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Classify tenant inquiries: emergency, maintenance, leasing, rent, general. Transfer accordingly."}]}, "first_message": "Thanks for calling. How can I help?", "first_message_mode": "assistant-speaks-first"}}, + {"assistant": {"name": "Maintenance", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Maintenance specialist. Collect details and prioritize emergencies."}]}}}, + {"assistant": {"name": "Leasing", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Leasing specialist. Answer leasing and rent questions."}]}}}, + ] + }, + ) + ``` + + + + ```bash + curl -X POST "https://api.vapi.ai/call/web" \ + -H "Authorization: Bearer $VAPI_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "squad": { + "members": [ + { "assistant": { "name": "Router", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Classify tenant inquiries: emergency, maintenance, leasing, rent, general. Transfer accordingly."}] }, "firstMessage": "Thanks for calling. How can I help?", "firstMessageMode": "assistant-speaks-first" } }, + { "assistant": { "name": "Maintenance", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Maintenance specialist. Collect details and prioritize emergencies."}] } } }, + { "assistant": { "name": "Leasing", "model": {"provider": "openai", "model": "gpt-4o", "messages": [{"role": "system", "content": "Leasing specialist. Answer leasing and rent questions."}] } } } + ] + } + }' + ``` + + + +## 4. Test + +Assign the Squad to a phone number and test each path. + +## Next steps + +- **Dynamic transfers**: [How to build](/calls/call-dynamic-transfers) + diff --git a/fern/workflows/examples/appointment-scheduling.mdx b/fern/workflows/examples/appointment-scheduling.mdx index 5d7459034..f5631c476 100644 --- a/fern/workflows/examples/appointment-scheduling.mdx +++ b/fern/workflows/examples/appointment-scheduling.mdx @@ -5,6 +5,10 @@ slug: workflows/examples/appointment-scheduling description: Build a voice AI appointment scheduling workflow with calendar integration, availability checking, and automated confirmations using Vapi's workflow builder. --- + +This example uses Workflows. For new builds, use **Assistants** or **Squads**. See the updated guides: [Assistant - Appointment Scheduling](/assistants/examples/appointment-scheduling) or [Squads](/squads). + + ## Overview Build an AI-powered appointment scheduling workflow that handles inbound calls for booking, rescheduling, and canceling appointments. The workflow uses visual nodes to create branching logic, integrates with calendar systems, checks availability in real-time, and sends confirmation messages. diff --git a/fern/workflows/examples/clinic-triage-scheduling.mdx b/fern/workflows/examples/clinic-triage-scheduling.mdx index 6d327871e..18004c1c8 100644 --- a/fern/workflows/examples/clinic-triage-scheduling.mdx +++ b/fern/workflows/examples/clinic-triage-scheduling.mdx @@ -5,6 +5,10 @@ slug: workflows/examples/clinic-triage-scheduling description: Build a voice AI clinic workflow with medical triage protocols, appointment booking, and emergency routing using Vapi's visual workflow builder. --- + +This example uses Workflows. For new builds, use **Squads** for multi-assistant triage and scheduling. See: [Squad - Clinic Triage & Scheduling](/squads/examples/clinic-triage-scheduling). + + ## Overview Build an AI-powered clinic receptionist workflow that handles patient triage, appointment scheduling, and emergency routing using Vapi workflows with medical protocol compliance and safety monitoring. diff --git a/fern/workflows/examples/ecommerce-order-management.mdx b/fern/workflows/examples/ecommerce-order-management.mdx index b48d2a86a..20cc50d4d 100644 --- a/fern/workflows/examples/ecommerce-order-management.mdx +++ b/fern/workflows/examples/ecommerce-order-management.mdx @@ -5,6 +5,10 @@ slug: workflows/examples/ecommerce-order-management description: Build a voice AI e-commerce workflow with order tracking, return processing, and customer support automation using Vapi's visual workflow builder. --- + +This example uses Workflows. For new builds, use **Squads** with specialized assistants for orders, returns, and VIP support. See: [Squad - E‑commerce Order Management](/squads/examples/ecommerce-order-management). + + ## Overview Build an AI-powered e-commerce customer service workflow that handles order inquiries, returns, and customer support using Vapi workflows with tier-based routing and global monitoring for comprehensive automation. diff --git a/fern/workflows/examples/lead-qualification.mdx b/fern/workflows/examples/lead-qualification.mdx index e7ad00a99..96cbd96d4 100644 --- a/fern/workflows/examples/lead-qualification.mdx +++ b/fern/workflows/examples/lead-qualification.mdx @@ -5,6 +5,10 @@ slug: workflows/examples/lead-qualification description: Build a voice AI outbound sales workflow with lead qualification, CRM integration, and automated follow-up using Vapi's visual workflow builder. --- + +This example uses Workflows. For new builds, use **Assistants** or **Squads**. See: [Assistant - Lead Qualification](/assistants/examples/lead-qualification) and [Squads](/squads). + + ## Overview Build an AI-powered outbound sales workflow that qualifies leads, handles objections, and schedules appointments using Vapi workflows with sophisticated branching logic and CRM integration. diff --git a/fern/workflows/examples/multilingual-support.mdx b/fern/workflows/examples/multilingual-support.mdx index fc31642bf..c30bab4b7 100644 --- a/fern/workflows/examples/multilingual-support.mdx +++ b/fern/workflows/examples/multilingual-support.mdx @@ -5,6 +5,10 @@ slug: workflows/examples/multilingual-support description: Build a multilingual voice AI customer support workflow with language selection, dedicated conversation nodes, and cultural context using Vapi's workflow builder. --- + +This example uses Workflows. For new builds, use a **Squad** with language‑specific assistants. See: [Squad - Multilingual Support](/squads/examples/multilingual-support). + + ## Overview Build a structured multilingual customer support workflow that guides customers through language selection at the start of the call, then routes them to dedicated conversation paths optimized for English, Spanish, and French support. diff --git a/fern/workflows/examples/property-management.mdx b/fern/workflows/examples/property-management.mdx index d93b84371..6b356b238 100644 --- a/fern/workflows/examples/property-management.mdx +++ b/fern/workflows/examples/property-management.mdx @@ -9,6 +9,10 @@ description: Build a voice AI property management system with dynamic call routi Property Management Workflow + +This example uses Workflows. For new builds, use **Squads** with a router assistant and domain specialists. See: [Squad - Property Management Routing](/squads/examples/property-management). + + ## Overview Build a property management call routing workflow that determines transfer destinations dynamically using tenant verification, inquiry type analysis, and real-time agent availability. This approach uses visual workflow nodes with API Request nodes for maximum routing flexibility. diff --git a/fern/workflows/overview.mdx b/fern/workflows/overview.mdx index c1263e763..156f4c0d4 100644 --- a/fern/workflows/overview.mdx +++ b/fern/workflows/overview.mdx @@ -4,6 +4,10 @@ subtitle: Learn to create robust, deterministic conversation flows with a visual slug: workflows/overview --- + +We no longer recommend Workflows for new builds. Prefer **Assistants** or **Squads** depending on complexity. See [Assistants](/assistants/dynamic-variables) and [Squads](/squads). This page is retained for legacy reference. + + ## Introduction Workflows is a visual builder designed for creating robust, deterministic conversation flows. It empowers developers and low-code builders to design agents through an intuitive interface representing interactions via nodes and edges. diff --git a/fern/workflows/quickstart.mdx b/fern/workflows/quickstart.mdx index 7bea279b5..8183f0dcb 100644 --- a/fern/workflows/quickstart.mdx +++ b/fern/workflows/quickstart.mdx @@ -5,6 +5,10 @@ slug: workflows/quickstart description: Build a simple agent that greets users and gathers basic information using Vapi workflows. --- + +We no longer recommend Workflows for new builds. Use **Assistants** for most cases or **Squads** for multi-assistant setups. See [Assistants](/assistants/dynamic-variables) and [Squads](/squads). Existing workflow content remains for reference. + + ## Overview Build a simple voice agent using Vapi's visual workflow builder that greets users, collects their information, and demonstrates core workflow concepts like variable extraction, conditional routing, and global nodes. From a44cb514c72c50c6e6282b58dd8f3b408d7919b7 Mon Sep 17 00:00:00 2001 From: Quantstruct Bot Date: Thu, 28 Aug 2025 14:07:05 -0700 Subject: [PATCH 003/171] Add changelog for 2025-08-28 (#652) --- fern/changelog/2025-08-28.mdx | 1 + 1 file changed, 1 insertion(+) create mode 100644 fern/changelog/2025-08-28.mdx diff --git a/fern/changelog/2025-08-28.mdx b/fern/changelog/2025-08-28.mdx new file mode 100644 index 000000000..6aeaa9540 --- /dev/null +++ b/fern/changelog/2025-08-28.mdx @@ -0,0 +1 @@ +1. **End AI call transfers after set timeout period**: You can now configure [AI-managed transfers](https://docs.vapi.ai/call-forwarding#7-assistant-based-warm-transfer-experimental) with a [Transfer Assistant](https://api.vapi.ai/api#:~:text=TransferAssistant) to automatically end the call after a specified period of silence with `silenceTimeoutSeconds` (default 30 seconds). This helps prevent idle calls from lingering and saves costs. From 9a86d33c20c1c2de7b6774e299cfea462ad05add Mon Sep 17 00:00:00 2001 From: arthurchi93 <152110249+arthurchi93@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:05:14 -0700 Subject: [PATCH 004/171] add docs on function parameter variable extraction (#653) --- fern/tools/handoff.mdx | 74 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/fern/tools/handoff.mdx b/fern/tools/handoff.mdx index 691d19fb2..b324dc204 100644 --- a/fern/tools/handoff.mdx +++ b/fern/tools/handoff.mdx @@ -321,7 +321,11 @@ Control what conversation history is passed to the next assistant: ## Variable Extraction -Extract and pass structured data during handoff: +Extract and pass structured data during handoff. Variables extracted by the handoff tool are available to all subsequent assistants in the conversation chain. +When a handoff extracts a variable with the same name as an existing one, the new value replaces the previous value. + +### 1. `variableExtractionPlan` in destinations +This extraction method will make an OpenAI structured output request to extract variables. Use this method if you have multiple destinations, each with different variables that need to be extracted. ```json { @@ -331,12 +335,8 @@ Extract and pass structured data during handoff: "destinations": [ { "type": "assistant", - "assistantId": "order-processing-assistant", + "assistantName": "order-processing-assistant", "description": "customer is ready to place an order", - "contextEngineeringPlan": { - "type": "lastNMessages", - "maxMessages": 5 - }, "variableExtractionPlan": { "schema": { "type": "object", @@ -377,6 +377,66 @@ Extract and pass structured data during handoff: } ``` +### 2. `tool.function` +We will also extract variables in the tool call parameters from the LLM tool call (in addition to sending these parameters to your server in a `handoff-destination-request` in a dynamic handoff). Be sure to include the `destination` parameter with the assistant names or IDs in `enum`, as that is how Vapi determines where to handoff the call to. The `destination` parameter will not be extracted as a variable. Also, remember to add `destination` and all other variables that are required to the JsonSchema's `required` array. + +```json +{ + "tools": [ + { + "type": "handoff", + "destinations": [ + { + "type": "assistant", + "assistantName": "order-processing-assistant", + "description": "customer is ready to place an order", + } + ], + "function": { + "name": "handoff_to_order_processing_assistant", + "parameters": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "The destination to handoff the call to.", + "enum": ["order-processing-assistant"] + }, + "customerName": { + "type": "string", + "description": "Full name of the customer" + }, + "email": { + "type": "string", + "format": "email", + "description": "Customer's email address" + }, + "productIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of product IDs customer wants to order" + }, + "shippingAddress": { + "type": "object", + "properties": { + "street": { "type": "string" }, + "city": { "type": "string" }, + "state": { "type": "string" }, + "zipCode": { "type": "string" } + } + } + }, + "required": ["destination", "customerName", "email"] + } + } + }, + ] +} +``` + + ## Custom Function Definitions Override the default function definition for more control. You can overwrite the function name for each tool to put into the system prompt or pass custom parameters in a dynamic handoff request. @@ -387,7 +447,7 @@ Override the default function definition for more control. You can overwrite the { "type": "handoff", "function": { - "name": "transfer_to_department", + "name": "handoff_to_department", "description": "Transfer the customer to the appropriate department based on their needs. Only use when explicitly requested or when the current assistant cannot help.", "parameters": { "type": "object", From be6ed78951507be00fbfb0623d716fd9a396e83d Mon Sep 17 00:00:00 2001 From: Dan Goosewin Date: Thu, 28 Aug 2025 17:44:49 -0700 Subject: [PATCH 005/171] fix(voiceWidget): disable voice widget (#655) --- fern/custom.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fern/custom.js b/fern/custom.js index 8666b5c7f..440e512dc 100644 --- a/fern/custom.js +++ b/fern/custom.js @@ -1,4 +1,5 @@ const WIDGET_TAG = 'vapi-voice-agent-widget'; +const ENABLE_VOICE_WIDGET = false; // Feature flag to enable/disable the floating voice widget const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; const WIDGET_SCRIPT_URL = isLocalhost ? 'http://localhost:9001/widget.js' @@ -46,13 +47,15 @@ function initializeHockeyStack() { hsscript.dataset.apikey = HOCKEYSTACK_API_KEY; hsscript.dataset.cookieless = 1; hsscript.dataset.autoIdentify = 1; - + document.getElementsByTagName('head')[0].append(hsscript); } function initializeAll() { initializeHockeyStack(); - injectVapiWidget(); + if (ENABLE_VOICE_WIDGET) { + injectVapiWidget(); + } } if (document.readyState === 'loading') { From 86be0d0f3e7c1499054266f612913582bdfb28d2 Mon Sep 17 00:00:00 2001 From: Quantstruct Bot Date: Fri, 29 Aug 2025 04:56:21 -0700 Subject: [PATCH 006/171] Add changelog for 2025-08-29 (#656) --- fern/changelog/2025-08-29.mdx | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 fern/changelog/2025-08-29.mdx diff --git a/fern/changelog/2025-08-29.mdx b/fern/changelog/2025-08-29.mdx new file mode 100644 index 000000000..8341591a7 --- /dev/null +++ b/fern/changelog/2025-08-29.mdx @@ -0,0 +1,5 @@ +1. **Per-Artifact Storage Routing in [Artifact Plans](https://api.vapi.ai/api#:~:text=ArtifactPlan)**: You can now override artifact storage behavior per assistant/call for SIP packet capture (PCAP), logging, and call recording artifacts: + +- `Assistant.artifactPlan.pcapUseCustomStorageEnabled` (default true): Use custom storage for SIP packet capture, which are stored in `Assistant.artifactPlan.pcapUrl`. +- `Assistant.artifactPlan.loggingUseCustomStorageEnabled` (default true): Determines whether to use your custom storage (S3 or GCP) for call logs when storage credentials are configured; set to false to store logs on Vapi's storage for this assistant, even if custom storage is set globally. +- `Assistant.artifactPlan.recordingUseCustomStorageEnabled` (default true): Determines whether to use your custom storage (S3 or GCP) for call recordings when storage credentials are configured; set to false to store recordings on Vapi's storage for this assistant, even if custom storage is set globally. From 17c861b8ad87265b768d7d00bfd189c6b8db1586 Mon Sep 17 00:00:00 2001 From: Sri Date: Fri, 29 Aug 2025 16:53:22 -0700 Subject: [PATCH 007/171] added docs for sms chat (#657) --- fern/chat/sms-chat.mdx | 126 +++++++++++++++++++++++++++++ fern/docs.yml | 3 + fern/phone-numbers/inbound-sms.mdx | 8 ++ 3 files changed, 137 insertions(+) create mode 100644 fern/chat/sms-chat.mdx diff --git a/fern/chat/sms-chat.mdx b/fern/chat/sms-chat.mdx new file mode 100644 index 000000000..4e8d729f0 --- /dev/null +++ b/fern/chat/sms-chat.mdx @@ -0,0 +1,126 @@ +--- +title: SMS chat +subtitle: Enable text-based conversations with assistants via SMS messaging +slug: chat/sms-chat +--- + +## Overview + +Let customers chat with your Vapi assistants through SMS text messages. Perfect for businesses that want to provide AI support through familiar messaging channels. + +**What You'll Enable:** +* Text-based conversations through SMS +* Automatic session management for each customer +* Context-aware responses across message exchanges + + +SMS chat requires a **10DLC-approved Twilio number**. Only customers can initiate conversations - assistants cannot send the first message. + + +## Prerequisites + +* A [Vapi account](https://dashboard.vapi.ai/) with an existing assistant +* A **10DLC-approved Twilio phone number** (required for assistant responses) +* Basic understanding of [phone number management](/phone-numbers) + +--- + +## Setup Steps + + + + Bring your approved Twilio number into Vapi so we can manage SMS messaging. + + + SMS is **enabled by default** when importing Twilio numbers. + + + See: [Import number from Twilio](/phone-numbers/import-twilio) and [Inbound SMS setup](/phone-numbers/inbound-sms) + + + Assign the assistant that will handle SMS conversations for this number. + + When customers text your number, they'll automatically start a chat session with this assistant. + + + Send a text message to your phone number to verify the assistant responds correctly. + + + + +View all SMS conversations in the [Session Logs](https://dashboard.vapi.ai/logs/session) page of your dashboard. Each SMS conversation creates a session where you can see the full message history and conversation flow. + + +--- + +## How It Works + +When a customer texts your number: + +1. **Session Creation**: Vapi automatically creates a chat session for the customer +2. **Context Management**: All messages maintain conversation context within the session +3. **Response Delivery**: Assistant responses are sent back as SMS messages +4. **Session Expiry**: Sessions expire after 24 hours of inactivity, then create fresh sessions for new conversations + +```mermaid +sequenceDiagram + participant Customer + participant Twilio + participant Vapi + participant Assistant + + Customer->>Twilio: "Hi, I need help" + Twilio->>Vapi: SMS webhook + Vapi->>Vapi: Create/find session + Vapi->>Assistant: Process message + Assistant->>Vapi: Generate response + Vapi->>Twilio: Send SMS response + Twilio->>Customer: "Hello! How can I help?" +``` + +--- + +## Session Management + +SMS conversations use automatic session management: + + + + * **New customers**: Get a fresh session on first text + * **Returning customers**: Continue existing session if under 24 hours + * **Session expiry**: After 24 hours, new session created automatically + * **Context preservation**: Full conversation history maintained within session + + + You cannot manually manage SMS sessions - they're handled automatically by Vapi's SMS infrastructure. + + For programmatic chat with manual session control, use the [Chat API](/chat/quickstart) directly. + + + +--- + +## Limitations + + +**Current SMS chat limitations:** +- **10DLC requirement**: Only 10DLC-approved Twilio numbers support assistant responses +- **Customer-initiated**: Assistants cannot send the first message to customers +- **Query tool**: Knowledge-base searches are not supported (same as Chat API) +- **Twilio only**: Other SMS providers are not currently supported + + +--- + +## Next Steps + +Enhance your SMS chat implementation: + +* **[Chat API](/chat/quickstart)** - Understand the underlying chat technology +* **[Session management](/chat/session-management)** - Learn how sessions work in detail +* **[Phone number management](/phone-numbers)** - Configure advanced telephony features +* **[Assistant configuration](/assistants/quickstart)** - Optimize your assistant for text conversations + + +For the best SMS experience, configure your assistant with concise responses and clear conversation flows. SMS users expect quick, direct answers. + diff --git a/fern/docs.yml b/fern/docs.yml index b074d0b42..12fb055b9 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -436,6 +436,9 @@ navigation: - page: Session management path: chat/session-management.mdx icon: fa-light fa-layer-group + - page: SMS chat + path: chat/sms-chat.mdx + icon: fa-light fa-comment-sms - page: Web widget path: chat/web-widget.mdx icon: fa-light fa-window-maximize diff --git a/fern/phone-numbers/inbound-sms.mdx b/fern/phone-numbers/inbound-sms.mdx index 5ee78d1d9..a1a75e05a 100644 --- a/fern/phone-numbers/inbound-sms.mdx +++ b/fern/phone-numbers/inbound-sms.mdx @@ -71,3 +71,11 @@ Update your number to set `smsEnabled: true` if it was previously disabled. For full endpoint details, see the [OpenAPI reference](/api-reference/openapi). +## Next steps + +Now that you have inbound SMS enabled: + +* **[SMS chat](/chat/sms-chat)** - Learn how customers can have full conversations with your assistants via SMS +* **[Session management](/chat/session-management)** - Understand how SMS conversations maintain context automatically +* **[Chat quickstart](/chat/quickstart)** - Explore the underlying chat technology powering SMS interactions + From d244e7e4806691c702d88065a15a3954f75c4c37 Mon Sep 17 00:00:00 2001 From: arthurchi93 <152110249+arthurchi93@users.noreply.github.com> Date: Fri, 29 Aug 2025 16:54:46 -0700 Subject: [PATCH 008/171] fix spacing for dynamic handoff (#658) --- fern/tools/handoff.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fern/tools/handoff.mdx b/fern/tools/handoff.mdx index b324dc204..1beb9c85e 100644 --- a/fern/tools/handoff.mdx +++ b/fern/tools/handoff.mdx @@ -213,8 +213,8 @@ destination: { "type": "object", "properties": { "name": { - "type": "string", - "description": "Name of the customer", + "type": "string", + "description": "Name of the customer", }, }, "required": ["name"], From cd56b803c00e5274123149a30721f9e6b6708347 Mon Sep 17 00:00:00 2001 From: Sri Date: Fri, 29 Aug 2025 17:05:58 -0700 Subject: [PATCH 009/171] updated sms chat docs --- fern/chat/sms-chat.mdx | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/fern/chat/sms-chat.mdx b/fern/chat/sms-chat.mdx index 4e8d729f0..7801812b0 100644 --- a/fern/chat/sms-chat.mdx +++ b/fern/chat/sms-chat.mdx @@ -84,19 +84,10 @@ sequenceDiagram SMS conversations use automatic session management: - - - * **New customers**: Get a fresh session on first text - * **Returning customers**: Continue existing session if under 24 hours - * **Session expiry**: After 24 hours, new session created automatically - * **Context preservation**: Full conversation history maintained within session - - - You cannot manually manage SMS sessions - they're handled automatically by Vapi's SMS infrastructure. - - For programmatic chat with manual session control, use the [Chat API](/chat/quickstart) directly. - - +* **New customers**: Get a fresh session on first text +* **Returning customers**: Continue existing session if under 24 hours +* **Session expiry**: After 24 hours, new session created automatically +* **Context preservation**: Full conversation history maintained within session --- From 02e562ad26f3f37af68e04dc1e507b64e744c8ff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Aug 2025 21:34:09 +0530 Subject: [PATCH 010/171] Update API specifications with fern api update (#661) Co-authored-by: github-actions --- fern/apis/api/openapi.json | 28638 ++++++++++++++++------------------- 1 file changed, 13358 insertions(+), 15280 deletions(-) diff --git a/fern/apis/api/openapi.json b/fern/apis/api/openapi.json index f24a120e3..9044bc121 100644 --- a/fern/apis/api/openapi.json +++ b/fern/apis/api/openapi.json @@ -1,17 +1,17 @@ { "openapi": "3.0.0", "paths": { - "/call": { + "/assistant": { "post": { - "operationId": "CallController_create", - "summary": "Create Call", + "operationId": "AssistantController_create", + "summary": "Create Assistant", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateCallDTO" + "$ref": "#/components/schemas/CreateAssistantDTO" } } } @@ -22,21 +22,14 @@ "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/Call" - }, - { - "$ref": "#/components/schemas/CallBatchResponse" - } - ] + "$ref": "#/components/schemas/Assistant" } } } } }, "tags": [ - "Calls" + "Assistants" ], "security": [ { @@ -45,36 +38,9 @@ ] }, "get": { - "operationId": "CallController_findAll", - "summary": "List Calls", + "operationId": "AssistantController_findAll", + "summary": "List Assistants", "parameters": [ - { - "name": "id", - "required": false, - "in": "query", - "description": "This is the unique identifier for the call.", - "schema": { - "type": "string" - } - }, - { - "name": "assistantId", - "required": false, - "in": "query", - "description": "This will return calls with the specified assistantId.", - "schema": { - "type": "string" - } - }, - { - "name": "phoneNumberId", - "required": false, - "in": "query", - "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "schema": { - "type": "string" - } - }, { "name": "limit", "required": false, @@ -175,7 +141,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/Call" + "$ref": "#/components/schemas/Assistant" } } } @@ -183,7 +149,7 @@ } }, "tags": [ - "Calls" + "Assistants" ], "security": [ { @@ -192,10 +158,10 @@ ] } }, - "/call/{id}": { + "/assistant/{id}": { "get": { - "operationId": "CallController_findOne", - "summary": "Get Call", + "operationId": "AssistantController_findOne", + "summary": "Get Assistant", "parameters": [ { "name": "id", @@ -212,14 +178,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Call" + "$ref": "#/components/schemas/Assistant" } } } } }, "tags": [ - "Calls" + "Assistants" ], "security": [ { @@ -228,8 +194,8 @@ ] }, "patch": { - "operationId": "CallController_update", - "summary": "Update Call", + "operationId": "AssistantController_update", + "summary": "Update Assistant", "parameters": [ { "name": "id", @@ -245,7 +211,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateCallDTO" + "$ref": "#/components/schemas/UpdateAssistantDTO" } } } @@ -256,14 +222,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Call" + "$ref": "#/components/schemas/Assistant" } } } } }, "tags": [ - "Calls" + "Assistants" ], "security": [ { @@ -272,8 +238,8 @@ ] }, "delete": { - "operationId": "CallController_deleteCallData", - "summary": "Delete Call Data", + "operationId": "AssistantController_remove", + "summary": "Delete Assistant", "parameters": [ { "name": "id", @@ -290,14 +256,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Call" + "$ref": "#/components/schemas/Assistant" } } } } }, "tags": [ - "Calls" + "Assistants" ], "security": [ { @@ -306,61 +272,46 @@ ] } }, - "/chat": { - "get": { - "operationId": "ChatController_listChats", - "summary": "List Chats", - "parameters": [ - { - "name": "assistantId", - "required": false, - "in": "query", - "description": "This is the unique identifier for the assistant that will be used for the chat.", - "schema": { - "type": "string" - } - }, - { - "name": "workflowId", - "required": false, - "in": "query", - "description": "This is the unique identifier for the workflow that will be used for the chat.", - "schema": { - "type": "string" - } - }, - { - "name": "sessionId", - "required": false, - "in": "query", - "description": "This is the unique identifier for the session that will be used for the chat.", - "schema": { - "type": "string" + "/squad": { + "post": { + "operationId": "SquadController_create", + "summary": "Create Squad", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSquadDTO" + } } - }, - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" + } + }, + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Squad" + } + } } - }, + } + }, + "tags": [ + "Squads" + ], + "security": [ { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "schema": { - "enum": [ - "ASC", - "DESC" - ], - "type": "string" - } - }, + "bearer": [] + } + ] + }, + "get": { + "operationId": "SquadController_findAll", + "summary": "List Squads", + "parameters": [ { "name": "limit", "required": false, @@ -459,79 +410,63 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ChatPaginatedResponse" + "type": "array", + "items": { + "$ref": "#/components/schemas/Squad" + } } } } } }, "tags": [ - "Chats" + "Squads" ], "security": [ { "bearer": [] } ] - }, - "post": { - "operationId": "ChatController_createChat", - "summary": "Create Chat", - "description": "Creates a new chat. Requires at least one of: assistantId/assistant, sessionId, or previousChatId. Note: sessionId and previousChatId are mutually exclusive.", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateChatDTO" - } + } + }, + "/squad/{id}": { + "get": { + "operationId": "SquadController_findOne", + "summary": "Get Squad", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" } } - }, + ], "responses": { "200": { - "description": "Chat response - either non-streaming chat or streaming", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/Chat" - }, - { - "$ref": "#/components/schemas/CreateChatStreamResponse" - } - ] - } - } - } - }, - "201": { "description": "", "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/Squad" } } } } }, "tags": [ - "Chats" + "Squads" ], "security": [ { "bearer": [] } ] - } - }, - "/chat/{id}": { - "get": { - "operationId": "ChatController_getChat", - "summary": "Get Chat", + }, + "patch": { + "operationId": "SquadController_update", + "summary": "Update Squad", "parameters": [ { "name": "id", @@ -542,20 +477,30 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSquadDTO" + } + } + } + }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Chat" + "$ref": "#/components/schemas/Squad" } } } } }, "tags": [ - "Chats" + "Squads" ], "security": [ { @@ -564,8 +509,8 @@ ] }, "delete": { - "operationId": "ChatController_deleteChat", - "summary": "Delete Chat", + "operationId": "SquadController_remove", + "summary": "Delete Squad", "parameters": [ { "name": "id", @@ -582,14 +527,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Chat" + "$ref": "#/components/schemas/Squad" } } } } }, "tags": [ - "Chats" + "Squads" ], "security": [ { @@ -598,98 +543,42 @@ ] } }, - "/chat/responses": { + "/call": { "post": { - "operationId": "ChatController_createOpenAIChat", - "summary": "Create Chat (OpenAI Compatible)", + "operationId": "CallController_create", + "summary": "Create Call", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/OpenAIResponsesRequest" + "$ref": "#/components/schemas/CreateCallDTO" } } } }, "responses": { - "200": { - "description": "OpenAI Responses API format - either non-streaming or streaming", + "201": { + "description": "", "content": { "application/json": { "schema": { "oneOf": [ { - "$ref": "#/components/schemas/ResponseObject" - }, - { - "$ref": "#/components/schemas/ResponseTextDeltaEvent" - }, - { - "$ref": "#/components/schemas/ResponseTextDoneEvent" - }, - { - "$ref": "#/components/schemas/ResponseCompletedEvent" + "$ref": "#/components/schemas/Call" }, { - "$ref": "#/components/schemas/ResponseErrorEvent" + "$ref": "#/components/schemas/CallBatchResponse" } ] } } } - }, - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Chats" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/campaign": { - "post": { - "operationId": "CampaignController_create", - "summary": "Create Campaign", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateCampaignDTO" - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Campaign" - } - } - } } }, "tags": [ - "Campaigns" + "Calls" ], "security": [ { @@ -698,50 +587,33 @@ ] }, "get": { - "operationId": "CampaignController_findAll", - "summary": "List Campaigns", + "operationId": "CallController_findAll", + "summary": "List Calls", "parameters": [ { "name": "id", "required": false, "in": "query", + "description": "This is the unique identifier for the call.", "schema": { "type": "string" } }, { - "name": "status", + "name": "assistantId", "required": false, "in": "query", + "description": "This will return calls with the specified assistantId.", "schema": { - "enum": [ - "scheduled", - "in-progress", - "ended" - ], "type": "string" } }, { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } - }, - { - "name": "sortOrder", + "name": "phoneNumberId", "required": false, "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", "schema": { - "enum": [ - "ASC", - "DESC" - ], "type": "string" } }, @@ -843,14 +715,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CampaignPaginatedResponse" + "type": "array", + "items": { + "$ref": "#/components/schemas/Call" + } } } } } }, "tags": [ - "Campaigns" + "Calls" ], "security": [ { @@ -859,10 +734,10 @@ ] } }, - "/campaign/{id}": { + "/call/{id}": { "get": { - "operationId": "CampaignController_findOne", - "summary": "Get Campaign", + "operationId": "CallController_findOne", + "summary": "Get Call", "parameters": [ { "name": "id", @@ -879,14 +754,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Campaign" + "$ref": "#/components/schemas/Call" } } } } }, "tags": [ - "Campaigns" + "Calls" ], "security": [ { @@ -895,8 +770,8 @@ ] }, "patch": { - "operationId": "CampaignController_update", - "summary": "Update Campaign", + "operationId": "CallController_update", + "summary": "Update Call", "parameters": [ { "name": "id", @@ -912,7 +787,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateCampaignDTO" + "$ref": "#/components/schemas/UpdateCallDTO" } } } @@ -923,14 +798,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Campaign" + "$ref": "#/components/schemas/Call" } } } } }, "tags": [ - "Campaigns" + "Calls" ], "security": [ { @@ -939,8 +814,8 @@ ] }, "delete": { - "operationId": "CampaignController_remove", - "summary": "Delete Campaign", + "operationId": "CallController_deleteCallData", + "summary": "Delete Call Data", "parameters": [ { "name": "id", @@ -957,14 +832,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Campaign" + "$ref": "#/components/schemas/Call" } } } } }, "tags": [ - "Campaigns" + "Calls" ], "security": [ { @@ -973,69 +848,34 @@ ] } }, - "/session": { - "post": { - "operationId": "SessionController_create", - "summary": "Create Session", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSessionDTO" - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Session" - } - } - } - } - }, - "tags": [ - "Sessions" - ], - "security": [ - { - "bearer": [] - } - ] - }, + "/chat": { "get": { - "operationId": "SessionController_findAllPaginated", - "summary": "List Sessions", + "operationId": "ChatController_listChats", + "summary": "List Chats", "parameters": [ { - "name": "name", + "name": "assistantId", "required": false, "in": "query", - "description": "This is the name of the session to filter by.", + "description": "This is the unique identifier for the assistant that will be used for the chat.", "schema": { "type": "string" } }, { - "name": "assistantId", + "name": "workflowId", "required": false, "in": "query", - "description": "This is the ID of the assistant to filter sessions by.", + "description": "This is the unique identifier for the workflow that will be used for the chat.", "schema": { "type": "string" } }, { - "name": "workflowId", + "name": "sessionId", "required": false, "in": "query", - "description": "This is the ID of the workflow to filter sessions by.", + "description": "This is the unique identifier for the session that will be used for the chat.", "schema": { "type": "string" } @@ -1161,14 +1001,67 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SessionPaginatedResponse" + "$ref": "#/components/schemas/ChatPaginatedResponse" } } } } }, "tags": [ - "Sessions" + "Chats" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "post": { + "operationId": "ChatController_createChat", + "summary": "Create Chat", + "description": "Creates a new chat. Requires at least one of: assistantId/assistant, sessionId, or previousChatId. Note: sessionId and previousChatId are mutually exclusive.", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateChatDTO" + } + } + } + }, + "responses": { + "200": { + "description": "Chat response - either non-streaming chat or streaming", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/Chat" + }, + { + "$ref": "#/components/schemas/CreateChatStreamResponse" + } + ] + } + } + } + }, + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Chats" ], "security": [ { @@ -1177,10 +1070,10 @@ ] } }, - "/session/{id}": { + "/chat/{id}": { "get": { - "operationId": "SessionController_findOne", - "summary": "Get Session", + "operationId": "ChatController_getChat", + "summary": "Get Chat", "parameters": [ { "name": "id", @@ -1197,14 +1090,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Session" + "$ref": "#/components/schemas/Chat" } } } } }, "tags": [ - "Sessions" + "Chats" ], "security": [ { @@ -1212,9 +1105,9 @@ } ] }, - "patch": { - "operationId": "SessionController_update", - "summary": "Update Session", + "delete": { + "operationId": "ChatController_deleteChat", + "summary": "Delete Chat", "parameters": [ { "name": "id", @@ -1225,64 +1118,83 @@ } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSessionDTO" - } - } - } - }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Session" + "$ref": "#/components/schemas/Chat" } } } } }, "tags": [ - "Sessions" + "Chats" ], "security": [ { "bearer": [] } ] - }, - "delete": { - "operationId": "SessionController_remove", - "summary": "Delete Session", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" + } + }, + "/chat/responses": { + "post": { + "operationId": "ChatController_createOpenAIChat", + "summary": "Create Chat (OpenAI Compatible)", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OpenAIResponsesRequest" + } } } - ], + }, "responses": { "200": { + "description": "OpenAI Responses API format - either non-streaming or streaming", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/ResponseObject" + }, + { + "$ref": "#/components/schemas/ResponseTextDeltaEvent" + }, + { + "$ref": "#/components/schemas/ResponseTextDoneEvent" + }, + { + "$ref": "#/components/schemas/ResponseCompletedEvent" + }, + { + "$ref": "#/components/schemas/ResponseErrorEvent" + } + ] + } + } + } + }, + "201": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Session" + "type": "object" } } } } }, "tags": [ - "Sessions" + "Chats" ], "security": [ { @@ -1291,17 +1203,17 @@ ] } }, - "/assistant": { + "/campaign": { "post": { - "operationId": "AssistantController_create", - "summary": "Create Assistant", + "operationId": "CampaignController_create", + "summary": "Create Campaign", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateAssistantDTO" + "$ref": "#/components/schemas/CreateCampaignDTO" } } } @@ -1312,14 +1224,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Assistant" + "$ref": "#/components/schemas/Campaign" } } } } }, "tags": [ - "Assistants" + "Campaigns" ], "security": [ { @@ -1328,9 +1240,53 @@ ] }, "get": { - "operationId": "AssistantController_findAll", - "summary": "List Assistants", + "operationId": "CampaignController_findAll", + "summary": "List Campaigns", "parameters": [ + { + "name": "id", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "status", + "required": false, + "in": "query", + "schema": { + "enum": [ + "scheduled", + "in-progress", + "ended" + ], + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "description": "This is the page number to return. Defaults to 1.", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "sortOrder", + "required": false, + "in": "query", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "schema": { + "enum": [ + "ASC", + "DESC" + ], + "type": "string" + } + }, { "name": "limit", "required": false, @@ -1429,17 +1385,14 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Assistant" - } + "$ref": "#/components/schemas/CampaignPaginatedResponse" } } } } }, "tags": [ - "Assistants" + "Campaigns" ], "security": [ { @@ -1448,10 +1401,10 @@ ] } }, - "/assistant/{id}": { + "/campaign/{id}": { "get": { - "operationId": "AssistantController_findOne", - "summary": "Get Assistant", + "operationId": "CampaignController_findOne", + "summary": "Get Campaign", "parameters": [ { "name": "id", @@ -1468,14 +1421,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Assistant" + "$ref": "#/components/schemas/Campaign" } } } } }, "tags": [ - "Assistants" + "Campaigns" ], "security": [ { @@ -1484,8 +1437,8 @@ ] }, "patch": { - "operationId": "AssistantController_update", - "summary": "Update Assistant", + "operationId": "CampaignController_update", + "summary": "Update Campaign", "parameters": [ { "name": "id", @@ -1501,7 +1454,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateAssistantDTO" + "$ref": "#/components/schemas/UpdateCampaignDTO" } } } @@ -1512,14 +1465,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Assistant" + "$ref": "#/components/schemas/Campaign" } } } } }, "tags": [ - "Assistants" + "Campaigns" ], "security": [ { @@ -1528,8 +1481,8 @@ ] }, "delete": { - "operationId": "AssistantController_remove", - "summary": "Delete Assistant", + "operationId": "CampaignController_remove", + "summary": "Delete Campaign", "parameters": [ { "name": "id", @@ -1546,14 +1499,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Assistant" + "$ref": "#/components/schemas/Campaign" } } } } }, "tags": [ - "Assistants" + "Campaigns" ], "security": [ { @@ -1562,48 +1515,17 @@ ] } }, - "/phone-number": { + "/session": { "post": { - "operationId": "PhoneNumberController_create", - "summary": "Create Phone Number", + "operationId": "SessionController_create", + "summary": "Create Session", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/CreateByoPhoneNumberDTO", - "title": "ByoPhoneNumber" - }, - { - "$ref": "#/components/schemas/CreateTwilioPhoneNumberDTO", - "title": "TwilioPhoneNumber" - }, - { - "$ref": "#/components/schemas/CreateVonagePhoneNumberDTO", - "title": "VonagePhoneNumber" - }, - { - "$ref": "#/components/schemas/CreateVapiPhoneNumberDTO", - "title": "VapiPhoneNumber" - }, - { - "$ref": "#/components/schemas/CreateTelnyxPhoneNumberDTO", - "title": "TelnyxPhoneNumber" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "byo-phone-number": "#/components/schemas/CreateByoPhoneNumberDTO", - "twilio": "#/components/schemas/CreateTwilioPhoneNumberDTO", - "vonage": "#/components/schemas/CreateVonagePhoneNumberDTO", - "vapi": "#/components/schemas/CreateVapiPhoneNumberDTO", - "telnyx": "#/components/schemas/CreateTelnyxPhoneNumberDTO" - } - } + "$ref": "#/components/schemas/CreateSessionDTO" } } } @@ -1614,46 +1536,14 @@ "content": { "application/json": { "schema": { - "title": "PhoneNumber", - "oneOf": [ - { - "$ref": "#/components/schemas/ByoPhoneNumber", - "title": "ByoPhoneNumber" - }, - { - "$ref": "#/components/schemas/TwilioPhoneNumber", - "title": "TwilioPhoneNumber" - }, - { - "$ref": "#/components/schemas/VonagePhoneNumber", - "title": "VonagePhoneNumber" - }, - { - "$ref": "#/components/schemas/VapiPhoneNumber", - "title": "VapiPhoneNumber" - }, - { - "$ref": "#/components/schemas/TelnyxPhoneNumber", - "title": "TelnyxPhoneNumber" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "byo-phone-number": "#/components/schemas/ByoPhoneNumber", - "twilio": "#/components/schemas/TwilioPhoneNumber", - "vonage": "#/components/schemas/VonagePhoneNumber", - "vapi": "#/components/schemas/VapiPhoneNumber", - "telnyx": "#/components/schemas/TelnyxPhoneNumber" - } - } + "$ref": "#/components/schemas/Session" } } } } }, "tags": [ - "Phone Numbers" + "Sessions" ], "security": [ { @@ -1662,9 +1552,59 @@ ] }, "get": { - "operationId": "PhoneNumberController_findAll", - "summary": "List Phone Numbers", + "operationId": "SessionController_findAllPaginated", + "summary": "List Sessions", "parameters": [ + { + "name": "name", + "required": false, + "in": "query", + "description": "This is the name of the session to filter by.", + "schema": { + "type": "string" + } + }, + { + "name": "assistantId", + "required": false, + "in": "query", + "description": "This is the ID of the assistant to filter sessions by.", + "schema": { + "type": "string" + } + }, + { + "name": "workflowId", + "required": false, + "in": "query", + "description": "This is the ID of the workflow to filter sessions by.", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "description": "This is the page number to return. Defaults to 1.", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "sortOrder", + "required": false, + "in": "query", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "schema": { + "enum": [ + "ASC", + "DESC" + ], + "type": "string" + } + }, { "name": "limit", "required": false, @@ -1763,49 +1703,14 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "title": "PhoneNumber", - "oneOf": [ - { - "$ref": "#/components/schemas/ByoPhoneNumber", - "title": "ByoPhoneNumber" - }, - { - "$ref": "#/components/schemas/TwilioPhoneNumber", - "title": "TwilioPhoneNumber" - }, - { - "$ref": "#/components/schemas/VonagePhoneNumber", - "title": "VonagePhoneNumber" - }, - { - "$ref": "#/components/schemas/VapiPhoneNumber", - "title": "VapiPhoneNumber" - }, - { - "$ref": "#/components/schemas/TelnyxPhoneNumber", - "title": "TelnyxPhoneNumber" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "byo-phone-number": "#/components/schemas/ByoPhoneNumber", - "twilio": "#/components/schemas/TwilioPhoneNumber", - "vonage": "#/components/schemas/VonagePhoneNumber", - "vapi": "#/components/schemas/VapiPhoneNumber", - "telnyx": "#/components/schemas/TelnyxPhoneNumber" - } - } - } + "$ref": "#/components/schemas/SessionPaginatedResponse" } } } } }, "tags": [ - "Phone Numbers" + "Sessions" ], "security": [ { @@ -1814,10 +1719,10 @@ ] } }, - "/phone-number/{id}": { + "/session/{id}": { "get": { - "operationId": "PhoneNumberController_findOne", - "summary": "Get Phone Number", + "operationId": "SessionController_findOne", + "summary": "Get Session", "parameters": [ { "name": "id", @@ -1834,46 +1739,14 @@ "content": { "application/json": { "schema": { - "title": "PhoneNumber", - "oneOf": [ - { - "$ref": "#/components/schemas/ByoPhoneNumber", - "title": "ByoPhoneNumber" - }, - { - "$ref": "#/components/schemas/TwilioPhoneNumber", - "title": "TwilioPhoneNumber" - }, - { - "$ref": "#/components/schemas/VonagePhoneNumber", - "title": "VonagePhoneNumber" - }, - { - "$ref": "#/components/schemas/VapiPhoneNumber", - "title": "VapiPhoneNumber" - }, - { - "$ref": "#/components/schemas/TelnyxPhoneNumber", - "title": "TelnyxPhoneNumber" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "byo-phone-number": "#/components/schemas/ByoPhoneNumber", - "twilio": "#/components/schemas/TwilioPhoneNumber", - "vonage": "#/components/schemas/VonagePhoneNumber", - "vapi": "#/components/schemas/VapiPhoneNumber", - "telnyx": "#/components/schemas/TelnyxPhoneNumber" - } - } + "$ref": "#/components/schemas/Session" } } } } }, "tags": [ - "Phone Numbers" + "Sessions" ], "security": [ { @@ -1882,8 +1755,8 @@ ] }, "patch": { - "operationId": "PhoneNumberController_update", - "summary": "Update Phone Number", + "operationId": "SessionController_update", + "summary": "Update Session", "parameters": [ { "name": "id", @@ -1899,38 +1772,7 @@ "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/UpdateByoPhoneNumberDTO", - "title": "ByoPhoneNumber" - }, - { - "$ref": "#/components/schemas/UpdateTwilioPhoneNumberDTO", - "title": "TwilioPhoneNumber" - }, - { - "$ref": "#/components/schemas/UpdateVonagePhoneNumberDTO", - "title": "VonagePhoneNumber" - }, - { - "$ref": "#/components/schemas/UpdateVapiPhoneNumberDTO", - "title": "VapiPhoneNumber" - }, - { - "$ref": "#/components/schemas/UpdateTelnyxPhoneNumberDTO", - "title": "TelnyxPhoneNumber" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "byo-phone-number": "#/components/schemas/UpdateByoPhoneNumberDTO", - "twilio": "#/components/schemas/UpdateTwilioPhoneNumberDTO", - "vonage": "#/components/schemas/UpdateVonagePhoneNumberDTO", - "vapi": "#/components/schemas/UpdateVapiPhoneNumberDTO", - "telnyx": "#/components/schemas/UpdateTelnyxPhoneNumberDTO" - } - } + "$ref": "#/components/schemas/UpdateSessionDTO" } } } @@ -1941,32 +1783,461 @@ "content": { "application/json": { "schema": { - "title": "PhoneNumber", - "oneOf": [ - { - "$ref": "#/components/schemas/ByoPhoneNumber", - "title": "ByoPhoneNumber" - }, - { - "$ref": "#/components/schemas/TwilioPhoneNumber", - "title": "TwilioPhoneNumber" - }, - { - "$ref": "#/components/schemas/VonagePhoneNumber", - "title": "VonagePhoneNumber" - }, - { - "$ref": "#/components/schemas/VapiPhoneNumber", - "title": "VapiPhoneNumber" - }, - { - "$ref": "#/components/schemas/TelnyxPhoneNumber", - "title": "TelnyxPhoneNumber" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { + "$ref": "#/components/schemas/Session" + } + } + } + } + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "delete": { + "operationId": "SessionController_remove", + "summary": "Delete Session", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Session" + } + } + } + } + }, + "tags": [ + "Sessions" + ], + "security": [ + { + "bearer": [] + } + ] + } + }, + "/phone-number": { + "post": { + "operationId": "PhoneNumberController_create", + "summary": "Create Phone Number", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/CreateByoPhoneNumberDTO", + "title": "ByoPhoneNumber" + }, + { + "$ref": "#/components/schemas/CreateTwilioPhoneNumberDTO", + "title": "TwilioPhoneNumber" + }, + { + "$ref": "#/components/schemas/CreateVonagePhoneNumberDTO", + "title": "VonagePhoneNumber" + }, + { + "$ref": "#/components/schemas/CreateVapiPhoneNumberDTO", + "title": "VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/CreateTelnyxPhoneNumberDTO", + "title": "TelnyxPhoneNumber" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "byo-phone-number": "#/components/schemas/CreateByoPhoneNumberDTO", + "twilio": "#/components/schemas/CreateTwilioPhoneNumberDTO", + "vonage": "#/components/schemas/CreateVonagePhoneNumberDTO", + "vapi": "#/components/schemas/CreateVapiPhoneNumberDTO", + "telnyx": "#/components/schemas/CreateTelnyxPhoneNumberDTO" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "title": "PhoneNumber", + "oneOf": [ + { + "$ref": "#/components/schemas/ByoPhoneNumber", + "title": "ByoPhoneNumber" + }, + { + "$ref": "#/components/schemas/TwilioPhoneNumber", + "title": "TwilioPhoneNumber" + }, + { + "$ref": "#/components/schemas/VonagePhoneNumber", + "title": "VonagePhoneNumber" + }, + { + "$ref": "#/components/schemas/VapiPhoneNumber", + "title": "VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/TelnyxPhoneNumber", + "title": "TelnyxPhoneNumber" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "byo-phone-number": "#/components/schemas/ByoPhoneNumber", + "twilio": "#/components/schemas/TwilioPhoneNumber", + "vonage": "#/components/schemas/VonagePhoneNumber", + "vapi": "#/components/schemas/VapiPhoneNumber", + "telnyx": "#/components/schemas/TelnyxPhoneNumber" + } + } + } + } + } + } + }, + "tags": [ + "Phone Numbers" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "get": { + "operationId": "PhoneNumberController_findAll", + "summary": "List Phone Numbers", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "This is the maximum number of items to return. Defaults to 100.", + "schema": { + "minimum": 0, + "maximum": 1000, + "type": "number" + } + }, + { + "name": "createdAtGt", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is greater than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtLt", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is less than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtGe", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is greater than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtLe", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is less than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtGt", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is greater than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtLt", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is less than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtGe", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is greater than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtLe", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is less than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "title": "PhoneNumber", + "oneOf": [ + { + "$ref": "#/components/schemas/ByoPhoneNumber", + "title": "ByoPhoneNumber" + }, + { + "$ref": "#/components/schemas/TwilioPhoneNumber", + "title": "TwilioPhoneNumber" + }, + { + "$ref": "#/components/schemas/VonagePhoneNumber", + "title": "VonagePhoneNumber" + }, + { + "$ref": "#/components/schemas/VapiPhoneNumber", + "title": "VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/TelnyxPhoneNumber", + "title": "TelnyxPhoneNumber" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "byo-phone-number": "#/components/schemas/ByoPhoneNumber", + "twilio": "#/components/schemas/TwilioPhoneNumber", + "vonage": "#/components/schemas/VonagePhoneNumber", + "vapi": "#/components/schemas/VapiPhoneNumber", + "telnyx": "#/components/schemas/TelnyxPhoneNumber" + } + } + } + } + } + } + } + }, + "tags": [ + "Phone Numbers" + ], + "security": [ + { + "bearer": [] + } + ] + } + }, + "/phone-number/{id}": { + "get": { + "operationId": "PhoneNumberController_findOne", + "summary": "Get Phone Number", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "title": "PhoneNumber", + "oneOf": [ + { + "$ref": "#/components/schemas/ByoPhoneNumber", + "title": "ByoPhoneNumber" + }, + { + "$ref": "#/components/schemas/TwilioPhoneNumber", + "title": "TwilioPhoneNumber" + }, + { + "$ref": "#/components/schemas/VonagePhoneNumber", + "title": "VonagePhoneNumber" + }, + { + "$ref": "#/components/schemas/VapiPhoneNumber", + "title": "VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/TelnyxPhoneNumber", + "title": "TelnyxPhoneNumber" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "byo-phone-number": "#/components/schemas/ByoPhoneNumber", + "twilio": "#/components/schemas/TwilioPhoneNumber", + "vonage": "#/components/schemas/VonagePhoneNumber", + "vapi": "#/components/schemas/VapiPhoneNumber", + "telnyx": "#/components/schemas/TelnyxPhoneNumber" + } + } + } + } + } + } + }, + "tags": [ + "Phone Numbers" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "patch": { + "operationId": "PhoneNumberController_update", + "summary": "Update Phone Number", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/UpdateByoPhoneNumberDTO", + "title": "ByoPhoneNumber" + }, + { + "$ref": "#/components/schemas/UpdateTwilioPhoneNumberDTO", + "title": "TwilioPhoneNumber" + }, + { + "$ref": "#/components/schemas/UpdateVonagePhoneNumberDTO", + "title": "VonagePhoneNumber" + }, + { + "$ref": "#/components/schemas/UpdateVapiPhoneNumberDTO", + "title": "VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/UpdateTelnyxPhoneNumberDTO", + "title": "TelnyxPhoneNumber" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "byo-phone-number": "#/components/schemas/UpdateByoPhoneNumberDTO", + "twilio": "#/components/schemas/UpdateTwilioPhoneNumberDTO", + "vonage": "#/components/schemas/UpdateVonagePhoneNumberDTO", + "vapi": "#/components/schemas/UpdateVapiPhoneNumberDTO", + "telnyx": "#/components/schemas/UpdateTelnyxPhoneNumberDTO" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "title": "PhoneNumber", + "oneOf": [ + { + "$ref": "#/components/schemas/ByoPhoneNumber", + "title": "ByoPhoneNumber" + }, + { + "$ref": "#/components/schemas/TwilioPhoneNumber", + "title": "TwilioPhoneNumber" + }, + { + "$ref": "#/components/schemas/VonagePhoneNumber", + "title": "VonagePhoneNumber" + }, + { + "$ref": "#/components/schemas/VapiPhoneNumber", + "title": "VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/TelnyxPhoneNumber", + "title": "TelnyxPhoneNumber" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { "byo-phone-number": "#/components/schemas/ByoPhoneNumber", "twilio": "#/components/schemas/TwilioPhoneNumber", "vonage": "#/components/schemas/VonagePhoneNumber", @@ -3270,78 +3541,52 @@ ] } }, - "/knowledge-base": { - "post": { - "operationId": "KnowledgeBaseController_create", - "summary": "Create Knowledge Base", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/CreateTrieveKnowledgeBaseDTO", - "title": "TrieveKnowledgeBaseDTO" - }, - { - "$ref": "#/components/schemas/CreateCustomKnowledgeBaseDTO", - "title": "CustomKnowledgeBaseDTO" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/CreateTrieveKnowledgeBaseDTO", - "custom-knowledge-base": "#/components/schemas/CreateCustomKnowledgeBaseDTO" - } - } - } + "/structured-output": { + "get": { + "operationId": "StructuredOutputController_findAll", + "summary": "List Structured Outputs", + "parameters": [ + { + "name": "id", + "required": false, + "in": "query", + "description": "This will return structured outputs where the id matches the specified value.", + "schema": { + "type": "string" } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBase", - "title": "TrieveKnowledgeBase" - }, - { - "$ref": "#/components/schemas/CustomKnowledgeBase", - "title": "CustomKnowledgeBase" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/TrieveKnowledgeBase", - "custom-knowledge-base": "#/components/schemas/CustomKnowledgeBase" - } - } - } - } + }, + { + "name": "name", + "required": false, + "in": "query", + "description": "This will return structured outputs where the name matches the specified value.", + "schema": { + "type": "string" } - } - }, - "tags": [ - "Knowledge Base" - ], - "security": [ + }, { - "bearer": [] - } - ] - }, - "get": { - "operationId": "KnowledgeBaseController_findAll", - "summary": "List Knowledge Bases", - "parameters": [ + "name": "page", + "required": false, + "in": "query", + "description": "This is the page number to return. Defaults to 1.", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "sortOrder", + "required": false, + "in": "query", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "schema": { + "enum": [ + "ASC", + "DESC" + ], + "type": "string" + } + }, { "name": "limit", "required": false, @@ -3440,95 +3685,61 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBase", - "title": "TrieveKnowledgeBase" - }, - { - "$ref": "#/components/schemas/CustomKnowledgeBase", - "title": "CustomKnowledgeBase" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/TrieveKnowledgeBase", - "custom-knowledge-base": "#/components/schemas/CustomKnowledgeBase" - } - } - } + "$ref": "#/components/schemas/StructuredOutputPaginatedResponse" } } } } }, "tags": [ - "Knowledge Base" + "Structured Outputs" ], "security": [ { "bearer": [] } ] - } - }, - "/knowledge-base/{id}": { - "get": { - "operationId": "KnowledgeBaseController_findOne", - "summary": "Get Knowledge Base", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" + }, + "post": { + "operationId": "StructuredOutputController_create", + "summary": "Create Structured Output", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStructuredOutputDTO" + } } } - ], + }, "responses": { - "200": { + "201": { "description": "", "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBase", - "title": "TrieveKnowledgeBase" - }, - { - "$ref": "#/components/schemas/CustomKnowledgeBase", - "title": "CustomKnowledgeBase" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/TrieveKnowledgeBase", - "custom-knowledge-base": "#/components/schemas/CustomKnowledgeBase" - } - } + "$ref": "#/components/schemas/StructuredOutput" } } } } }, "tags": [ - "Knowledge Base" + "Structured Outputs" ], "security": [ { "bearer": [] } ] - }, - "patch": { - "operationId": "KnowledgeBaseController_update", - "summary": "Update Knowledge Base", + } + }, + "/structured-output/{id}": { + "get": { + "operationId": "StructuredOutputController_findOne", + "summary": "Get Structured Output", "parameters": [ { "name": "id", @@ -3539,62 +3750,20 @@ } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/UpdateTrieveKnowledgeBaseDTO", - "title": "UpdateTrieveKnowledgeBaseDTO" - }, - { - "$ref": "#/components/schemas/UpdateCustomKnowledgeBaseDTO", - "title": "UpdateCustomKnowledgeBaseDTO" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/UpdateTrieveKnowledgeBaseDTO", - "custom-knowledge-base": "#/components/schemas/UpdateCustomKnowledgeBaseDTO" - } - } - } - } - } - }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBase", - "title": "TrieveKnowledgeBase" - }, - { - "$ref": "#/components/schemas/CustomKnowledgeBase", - "title": "CustomKnowledgeBase" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/TrieveKnowledgeBase", - "custom-knowledge-base": "#/components/schemas/CustomKnowledgeBase" - } - } + "$ref": "#/components/schemas/StructuredOutput" } } } } }, "tags": [ - "Knowledge Base" + "Structured Outputs" ], "security": [ { @@ -3602,9 +3771,9 @@ } ] }, - "delete": { - "operationId": "KnowledgeBaseController_remove", - "summary": "Delete Knowledge Base", + "patch": { + "operationId": "StructuredOutputController_update", + "summary": "Update Structured Output", "parameters": [ { "name": "id", @@ -3613,115 +3782,50 @@ "schema": { "type": "string" } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBase", - "title": "TrieveKnowledgeBase" - }, - { - "$ref": "#/components/schemas/CustomKnowledgeBase", - "title": "CustomKnowledgeBase" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "trieve": "#/components/schemas/TrieveKnowledgeBase", - "custom-knowledge-base": "#/components/schemas/CustomKnowledgeBase" - } - } - } - } - } - } - }, - "tags": [ - "Knowledge Base" - ], - "security": [ + }, { - "bearer": [] - } - ] - } - }, - "/workflow": { - "get": { - "operationId": "WorkflowController_findAll", - "summary": "Get Workflows", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Workflow" - } - } - } + "name": "schemaOverride", + "required": true, + "in": "query", + "schema": { + "type": "string" } } - }, - "tags": [ - "Workflow" ], - "security": [ - { - "bearer": [] - } - ] - }, - "post": { - "operationId": "WorkflowController_create", - "summary": "Create Workflow", - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateWorkflowDTO" + "$ref": "#/components/schemas/UpdateStructuredOutputDTO" } } } }, "responses": { - "201": { + "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Workflow" + "$ref": "#/components/schemas/StructuredOutput" } } } } }, "tags": [ - "Workflow" + "Structured Outputs" ], "security": [ { "bearer": [] } ] - } - }, - "/workflow/{id}": { - "get": { - "operationId": "WorkflowController_findOne", - "summary": "Get Workflow", + }, + "delete": { + "operationId": "StructuredOutputController_remove", + "summary": "Delete Structured Output", "parameters": [ { "name": "id", @@ -3738,48 +3842,74 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Workflow" + "$ref": "#/components/schemas/StructuredOutput" } } } } }, "tags": [ - "Workflow" + "Structured Outputs" ], "security": [ { "bearer": [] } ] - }, - "delete": { - "operationId": "WorkflowController_delete", - "summary": "Delete Workflow", + } + }, + "/provider/{provider}/{resourceName}": { + "post": { + "operationId": "ProviderResourceController_createProviderResource", + "summary": "Create Provider Resource", "parameters": [ { - "name": "id", + "name": "content-type", + "required": true, + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "provider", "required": true, "in": "path", + "description": "The provider (e.g., 11labs)", + "schema": { + "enum": [ + "11labs" + ], + "type": "string" + } + }, + { + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", "schema": { + "enum": [ + "pronunciation-dictionary" + ], "type": "string" } } ], "responses": { - "200": { - "description": "", + "201": { + "description": "Successfully created provider resource", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Workflow" + "$ref": "#/components/schemas/ProviderResource" } } } } }, "tags": [ - "Workflow" + "Provider Resources" ], "security": [ { @@ -3787,91 +3917,73 @@ } ] }, - "patch": { - "operationId": "WorkflowController_update", - "summary": "Update Workflow", + "get": { + "operationId": "ProviderResourceController_getProviderResourcesPaginated", + "summary": "List Provider Resources", "parameters": [ { - "name": "id", + "name": "provider", "required": true, "in": "path", + "description": "The provider (e.g., 11labs)", "schema": { + "enum": [ + "11labs" + ], "type": "string" } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateWorkflowDTO" - } + }, + { + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", + "schema": { + "enum": [ + "pronunciation-dictionary" + ], + "type": "string" } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Workflow" - } - } + }, + { + "name": "id", + "required": false, + "in": "query", + "schema": { + "type": "string" } - } - }, - "tags": [ - "Workflow" - ], - "security": [ + }, { - "bearer": [] - } - ] - } - }, - "/squad": { - "post": { - "operationId": "SquadController_create", - "summary": "Create Squad", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSquadDTO" - } + "name": "resourceId", + "required": false, + "in": "query", + "schema": { + "type": "string" } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Squad" - } - } + }, + { + "name": "page", + "required": false, + "in": "query", + "description": "This is the page number to return. Defaults to 1.", + "schema": { + "minimum": 1, + "type": "number" } - } - }, - "tags": [ - "Squads" - ], - "security": [ + }, { - "bearer": [] - } - ] - }, - "get": { - "operationId": "SquadController_findAll", - "summary": "List Squads", - "parameters": [ + "name": "sortOrder", + "required": false, + "in": "query", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "schema": { + "enum": [ + "ASC", + "DESC" + ], + "type": "string" + } + }, { "name": "limit", "required": false, @@ -3966,21 +4078,18 @@ ], "responses": { "200": { - "description": "", + "description": "List of provider resources", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Squad" - } + "$ref": "#/components/schemas/ProviderResourcePaginatedResponse" } } } } }, "tags": [ - "Squads" + "Provider Resources" ], "security": [ { @@ -3989,34 +4098,62 @@ ] } }, - "/squad/{id}": { + "/provider/{provider}/{resourceName}/{id}": { "get": { - "operationId": "SquadController_findOne", - "summary": "Get Squad", + "operationId": "ProviderResourceController_getProviderResource", + "summary": "Get Provider Resource", "parameters": [ + { + "name": "provider", + "required": true, + "in": "path", + "description": "The provider (e.g., 11labs)", + "schema": { + "enum": [ + "11labs" + ], + "type": "string" + } + }, + { + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", + "schema": { + "enum": [ + "pronunciation-dictionary" + ], + "type": "string" + } + }, { "name": "id", "required": true, "in": "path", "schema": { + "format": "uuid", "type": "string" } } ], "responses": { "200": { - "description": "", + "description": "Successfully retrieved provider resource", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Squad" + "$ref": "#/components/schemas/ProviderResource" } } } + }, + "404": { + "description": "Provider resource not found" } }, "tags": [ - "Squads" + "Provider Resources" ], "security": [ { @@ -4024,43 +4161,61 @@ } ] }, - "patch": { - "operationId": "SquadController_update", - "summary": "Update Squad", + "delete": { + "operationId": "ProviderResourceController_deleteProviderResource", + "summary": "Delete Provider Resource", "parameters": [ + { + "name": "provider", + "required": true, + "in": "path", + "description": "The provider (e.g., 11labs)", + "schema": { + "enum": [ + "11labs" + ], + "type": "string" + } + }, + { + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", + "schema": { + "enum": [ + "pronunciation-dictionary" + ], + "type": "string" + } + }, { "name": "id", "required": true, "in": "path", "schema": { + "format": "uuid", "type": "string" } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSquadDTO" - } - } - } - }, "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Squad" + "$ref": "#/components/schemas/ProviderResource" } } } + }, + "404": { + "description": "Provider resource not found" } }, "tags": [ - "Squads" + "Provider Resources" ], "security": [ { @@ -4068,157 +4223,40 @@ } ] }, - "delete": { - "operationId": "SquadController_remove", - "summary": "Delete Squad", + "patch": { + "operationId": "ProviderResourceController_updateProviderResource", + "summary": "Update Provider Resource", "parameters": [ { - "name": "id", + "name": "provider", "required": true, "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Squad" - } - } - } - } - }, - "tags": [ - "Squads" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/test-suite": { - "get": { - "operationId": "TestSuiteController_findAllPaginated", - "summary": "List Test Suites", - "parameters": [ - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } - }, - { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "description": "The provider (e.g., 11labs)", "schema": { "enum": [ - "ASC", - "DESC" + "11labs" ], "type": "string" } }, { - "name": "limit", - "required": false, - "in": "query", - "description": "This is the maximum number of items to return. Defaults to 100.", - "schema": { - "minimum": 0, - "maximum": 1000, - "type": "number" - } - }, - { - "name": "createdAtGt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtLt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtGe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtLe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtGt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtLt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtGe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than or equal to the specified value.", + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", "schema": { - "format": "date-time", + "enum": [ + "pronunciation-dictionary" + ], "type": "string" } }, { - "name": "updatedAtLe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than or equal to the specified value.", + "name": "id", + "required": true, + "in": "path", "schema": { - "format": "date-time", + "format": "uuid", "type": "string" } } @@ -4229,49 +4267,60 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestSuitesPaginatedResponse" + "$ref": "#/components/schemas/ProviderResource" } } } + }, + "404": { + "description": "Provider resource not found" } }, "tags": [ - "Test Suites" + "Provider Resources" ], "security": [ { "bearer": [] } ] - }, + } + }, + "/analytics": { "post": { - "operationId": "TestSuiteController_create", - "summary": "Create Test Suite", + "operationId": "AnalyticsController_query", + "summary": "Create Analytics Queries", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTestSuiteDto" + "$ref": "#/components/schemas/AnalyticsQueryDTO" } } } }, "responses": { - "201": { + "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestSuite" + "type": "array", + "items": { + "$ref": "#/components/schemas/AnalyticsQueryResult" + } } } } + }, + "201": { + "description": "" } }, "tags": [ - "Test Suites" + "Analytics" ], "security": [ { @@ -4279,2629 +4328,1953 @@ } ] } + } + }, + "info": { + "title": "Vapi API", + "description": "Voice AI for developers.", + "version": "1.0", + "contact": {} + }, + "tags": [], + "servers": [ + { + "url": "https://api.vapi.ai" + } + ], + "components": { + "securitySchemes": { + "bearer": { + "scheme": "bearer", + "bearerFormat": "Bearer", + "type": "http", + "description": "Retrieve your API Key from [Dashboard](dashboard.vapi.ai)." + } }, - "/test-suite/{id}": { - "get": { - "operationId": "TestSuiteController_findOne", - "summary": "Get Test Suite", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuite" - } - } - } - } - }, - "tags": [ - "Test Suites" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "patch": { - "operationId": "TestSuiteController_update", - "summary": "Update Test Suite", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTestSuiteDto" - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuite" + "schemas": { + "FallbackTranscriberPlan": { + "type": "object", + "properties": { + "transcribers": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/FallbackAssemblyAITranscriber", + "title": "AssemblyAI" + }, + { + "$ref": "#/components/schemas/FallbackAzureSpeechTranscriber", + "title": "Azure" + }, + { + "$ref": "#/components/schemas/FallbackCustomTranscriber", + "title": "Custom" + }, + { + "$ref": "#/components/schemas/FallbackDeepgramTranscriber", + "title": "Deepgram" + }, + { + "$ref": "#/components/schemas/FallbackElevenLabsTranscriber", + "title": "ElevenLabs" + }, + { + "$ref": "#/components/schemas/FallbackGladiaTranscriber", + "title": "Gladia" + }, + { + "$ref": "#/components/schemas/FallbackGoogleTranscriber", + "title": "Google" + }, + { + "$ref": "#/components/schemas/FallbackTalkscriberTranscriber", + "title": "Talkscriber" + }, + { + "$ref": "#/components/schemas/FallbackSpeechmaticsTranscriber", + "title": "Speechmatics" + }, + { + "$ref": "#/components/schemas/FallbackOpenAITranscriber", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/FallbackCartesiaTranscriber", + "title": "Cartesia" } - } + ] } } }, - "tags": [ - "Test Suites" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "transcribers" ] }, - "delete": { - "operationId": "TestSuiteController_remove", - "summary": "Delete Test Suite", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuite" - } - } - } - } - }, - "tags": [ - "Test Suites" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/test-suite/{testSuiteId}/test": { - "get": { - "operationId": "TestSuiteTestController_findAllPaginated", - "summary": "List Tests", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "AssemblyAITranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "assembly-ai" + ] }, - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } + "language": { + "type": "string", + "description": "This is the language that will be set for the transcription.", + "enum": [ + "en" + ] }, - { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "schema": { - "enum": [ - "ASC", - "DESC" - ], - "type": "string" - } + "confidenceThreshold": { + "type": "number", + "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", + "minimum": 0, + "maximum": 1, + "example": 0.4 }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "This is the maximum number of items to return. Defaults to 100.", - "schema": { - "minimum": 0, - "maximum": 1000, - "type": "number" - } + "formatTurns": { + "type": "boolean", + "description": "This enables formatting of transcripts.\n\n@default true", + "example": true }, - { - "name": "createdAtGt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "endOfTurnConfidenceThreshold": { + "type": "number", + "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\n\n@min 0\n@max 1\n@default 0.7", + "minimum": 0, + "maximum": 1, + "example": 0.7 }, - { - "name": "createdAtLt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "minEndOfTurnSilenceWhenConfident": { + "type": "number", + "description": "This is the minimum end of turn silence when confident in milliseconds.\n\n@default 160", + "minimum": 0, + "example": 160 }, - { - "name": "createdAtGe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "wordFinalizationMaxWaitTime": { + "type": "number", + "description": "This is the maximum wait time for word finalization in milliseconds.\n\n@default 160", + "minimum": 0, + "example": 160 }, - { - "name": "createdAtLe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "maxTurnSilence": { + "type": "number", + "description": "This is the maximum turn silence time in milliseconds.\n\n@default 400", + "minimum": 0, + "example": 400 }, - { - "name": "updatedAtGt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "realtimeUrl": { + "type": "string", + "description": "The WebSocket URL that the transcriber connects to." }, - { - "name": "updatedAtLt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" + "wordBoost": { + "description": "Add up to 2500 characters of custom vocabulary.", + "type": "array", + "items": { + "type": "string", + "maxLength": 2500 } }, - { - "name": "updatedAtGe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "endUtteranceSilenceThreshold": { + "type": "number", + "description": "The duration of the end utterance silence threshold in milliseconds." }, - { - "name": "updatedAtLe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuiteTestsPaginatedResponse" - } - } - } - } - }, - "tags": [ - "Test Suite Tests" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "post": { - "operationId": "TestSuiteTestController_create", - "summary": "Create Test", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/CreateTestSuiteTestVoiceDto", - "title": "TestSuiteTestVoice" - }, - { - "$ref": "#/components/schemas/CreateTestSuiteTestChatDto", - "title": "TestSuiteTestChat" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "voice": "#/components/schemas/CreateTestSuiteTestVoiceDto", - "chat": "#/components/schemas/CreateTestSuiteTestChatDto" - } - } - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteTestVoice", - "title": "Voice" - }, - { - "$ref": "#/components/schemas/TestSuiteTestChat", - "title": "Chat" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "voice": "#/components/schemas/TestSuiteTestVoice", - "chat": "#/components/schemas/TestSuiteTestChat" - } - } - } - } - } - } - }, - "tags": [ - "Test Suite Tests" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/test-suite/{testSuiteId}/test/{id}": { - "get": { - "operationId": "TestSuiteTestController_findOne", - "summary": "Get Test", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "disablePartialTranscripts": { + "type": "boolean", + "description": "Disable partial transcripts.\nSet to `true` to not receive partial transcripts. Defaults to `false`." }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteTestVoice", - "title": "Voice" - }, - { - "$ref": "#/components/schemas/TestSuiteTestChat", - "title": "Chat" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "voice": "#/components/schemas/TestSuiteTestVoice", - "chat": "#/components/schemas/TestSuiteTestChat" - } - } - } + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Test Suite Tests" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] }, - "patch": { - "operationId": "TestSuiteTestController_update", - "summary": "Update Test", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "AzureSpeechTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "azure" + ] }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/UpdateTestSuiteTestVoiceDto", - "title": "TestSuiteTestVoice" - }, - { - "$ref": "#/components/schemas/UpdateTestSuiteTestChatDto", - "title": "TestSuiteTestChat" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "voice": "#/components/schemas/UpdateTestSuiteTestVoiceDto", - "chat": "#/components/schemas/UpdateTestSuiteTestChatDto" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteTestVoice", - "title": "Voice" - }, - { - "$ref": "#/components/schemas/TestSuiteTestChat", - "title": "Chat" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "voice": "#/components/schemas/TestSuiteTestVoice", - "chat": "#/components/schemas/TestSuiteTestChat" - } - } - } - } - } - } - }, - "tags": [ - "Test Suite Tests" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "delete": { - "operationId": "TestSuiteTestController_remove", - "summary": "Delete Test", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "language": { + "type": "string", + "description": "This is the language that will be set for the transcription. The list of languages Azure supports can be found here: https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=stt", + "enum": [ + "af-ZA", + "am-ET", + "ar-AE", + "ar-BH", + "ar-DZ", + "ar-EG", + "ar-IL", + "ar-IQ", + "ar-JO", + "ar-KW", + "ar-LB", + "ar-LY", + "ar-MA", + "ar-OM", + "ar-PS", + "ar-QA", + "ar-SA", + "ar-SY", + "ar-TN", + "ar-YE", + "az-AZ", + "bg-BG", + "bn-IN", + "bs-BA", + "ca-ES", + "cs-CZ", + "cy-GB", + "da-DK", + "de-AT", + "de-CH", + "de-DE", + "el-GR", + "en-AU", + "en-CA", + "en-GB", + "en-GH", + "en-HK", + "en-IE", + "en-IN", + "en-KE", + "en-NG", + "en-NZ", + "en-PH", + "en-SG", + "en-TZ", + "en-US", + "en-ZA", + "es-AR", + "es-BO", + "es-CL", + "es-CO", + "es-CR", + "es-CU", + "es-DO", + "es-EC", + "es-ES", + "es-GQ", + "es-GT", + "es-HN", + "es-MX", + "es-NI", + "es-PA", + "es-PE", + "es-PR", + "es-PY", + "es-SV", + "es-US", + "es-UY", + "es-VE", + "et-EE", + "eu-ES", + "fa-IR", + "fi-FI", + "fil-PH", + "fr-BE", + "fr-CA", + "fr-CH", + "fr-FR", + "ga-IE", + "gl-ES", + "gu-IN", + "he-IL", + "hi-IN", + "hr-HR", + "hu-HU", + "hy-AM", + "id-ID", + "is-IS", + "it-CH", + "it-IT", + "ja-JP", + "jv-ID", + "ka-GE", + "kk-KZ", + "km-KH", + "kn-IN", + "ko-KR", + "lo-LA", + "lt-LT", + "lv-LV", + "mk-MK", + "ml-IN", + "mn-MN", + "mr-IN", + "ms-MY", + "mt-MT", + "my-MM", + "nb-NO", + "ne-NP", + "nl-BE", + "nl-NL", + "pa-IN", + "pl-PL", + "ps-AF", + "pt-BR", + "pt-PT", + "ro-RO", + "ru-RU", + "si-LK", + "sk-SK", + "sl-SI", + "so-SO", + "sq-AL", + "sr-RS", + "sv-SE", + "sw-KE", + "sw-TZ", + "ta-IN", + "te-IN", + "th-TH", + "tr-TR", + "uk-UA", + "ur-IN", + "uz-UZ", + "vi-VN", + "wuu-CN", + "yue-CN", + "zh-CN", + "zh-CN-shandong", + "zh-CN-sichuan", + "zh-HK", + "zh-TW", + "zu-ZA" + ] }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteTestVoice", - "title": "Voice" - }, - { - "$ref": "#/components/schemas/TestSuiteTestChat", - "title": "Chat" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "voice": "#/components/schemas/TestSuiteTestVoice", - "chat": "#/components/schemas/TestSuiteTestChat" - } - } - } + "segmentationStrategy": { + "type": "string", + "description": "Controls how phrase boundaries are detected, enabling either simple time/silence heuristics or more advanced semantic segmentation.", + "enum": [ + "Default", + "Time", + "Semantic" + ] + }, + "segmentationSilenceTimeoutMs": { + "type": "number", + "description": "Duration of detected silence after which the service finalizes a phrase. Configure to adjust sensitivity to pauses in speech.", + "minimum": 100, + "maximum": 5000 + }, + "segmentationMaximumTimeMs": { + "type": "number", + "description": "Maximum duration a segment can reach before being cut off when using time-based segmentation.", + "minimum": 20000, + "maximum": 70000 + }, + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Test Suite Tests" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] - } - }, - "/test-suite/{testSuiteId}/run": { - "get": { - "operationId": "TestSuiteRunController_findAllPaginated", - "summary": "List Test Suite Runs", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } - }, - { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "schema": { - "enum": [ - "ASC", - "DESC" - ], - "type": "string" - } - }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "This is the maximum number of items to return. Defaults to 100.", - "schema": { - "minimum": 0, - "maximum": 1000, - "type": "number" - } + }, + "CartesiaTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "cartesia" + ] }, - { - "name": "createdAtGt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "model": { + "type": "string", + "enum": [ + "ink-whisper" + ] }, - { - "name": "createdAtLt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtGe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtLe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtGt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtLt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtGe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "language": { + "type": "string", + "enum": [ + "aa", + "ab", + "ae", + "af", + "ak", + "am", + "an", + "ar", + "as", + "av", + "ay", + "az", + "ba", + "be", + "bg", + "bh", + "bi", + "bm", + "bn", + "bo", + "br", + "bs", + "ca", + "ce", + "ch", + "co", + "cr", + "cs", + "cu", + "cv", + "cy", + "da", + "de", + "dv", + "dz", + "ee", + "el", + "en", + "eo", + "es", + "et", + "eu", + "fa", + "ff", + "fi", + "fj", + "fo", + "fr", + "fy", + "ga", + "gd", + "gl", + "gn", + "gu", + "gv", + "ha", + "he", + "hi", + "ho", + "hr", + "ht", + "hu", + "hy", + "hz", + "ia", + "id", + "ie", + "ig", + "ii", + "ik", + "io", + "is", + "it", + "iu", + "ja", + "jv", + "ka", + "kg", + "ki", + "kj", + "kk", + "kl", + "km", + "kn", + "ko", + "kr", + "ks", + "ku", + "kv", + "kw", + "ky", + "la", + "lb", + "lg", + "li", + "ln", + "lo", + "lt", + "lu", + "lv", + "mg", + "mh", + "mi", + "mk", + "ml", + "mn", + "mr", + "ms", + "mt", + "my", + "na", + "nb", + "nd", + "ne", + "ng", + "nl", + "nn", + "no", + "nr", + "nv", + "ny", + "oc", + "oj", + "om", + "or", + "os", + "pa", + "pi", + "pl", + "ps", + "pt", + "qu", + "rm", + "rn", + "ro", + "ru", + "rw", + "sa", + "sc", + "sd", + "se", + "sg", + "si", + "sk", + "sl", + "sm", + "sn", + "so", + "sq", + "sr", + "ss", + "st", + "su", + "sv", + "sw", + "ta", + "te", + "tg", + "th", + "ti", + "tk", + "tl", + "tn", + "to", + "tr", + "ts", + "tt", + "tw", + "ty", + "ug", + "uk", + "ur", + "uz", + "ve", + "vi", + "vo", + "wa", + "wo", + "xh", + "yi", + "yue", + "yo", + "za", + "zh", + "zu" + ] }, - { - "name": "updatedAtLe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuiteRunsPaginatedResponse" - } + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Test Suite Runs" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] }, - "post": { - "operationId": "TestSuiteRunController_create", - "summary": "Create Test Suite Run", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTestSuiteRunDto" - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuiteRun" - } - } + "BackoffPlan": { + "type": "object", + "properties": { + "type": { + "type": "object", + "description": "This is the type of backoff plan to use. Defaults to fixed.\n\n@default fixed", + "enum": [ + "fixed", + "exponential" + ], + "example": "fixed" + }, + "maxRetries": { + "type": "number", + "description": "This is the maximum number of retries to attempt if the request fails. Defaults to 0 (no retries).\n\n@default 0", + "minimum": 0, + "maximum": 10, + "example": 0 + }, + "baseDelaySeconds": { + "type": "number", + "description": "This is the base delay in seconds. For linear backoff, this is the delay between each retry. For exponential backoff, this is the initial delay.", + "minimum": 0, + "maximum": 10, + "example": 1 + }, + "excludedStatusCodes": { + "description": "This is the excluded status codes. If the response status code is in this list, the request will not be retried.\nBy default, the request will be retried for any non-2xx status code.", + "example": [ + 400, + 401, + 403, + 404 + ], + "type": "array", + "items": { + "type": "object" } } }, - "tags": [ - "Test Suite Runs" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "type", + "maxRetries", + "baseDelaySeconds" ] - } - }, - "/test-suite/{testSuiteId}/run/{id}": { - "get": { - "operationId": "TestSuiteRunController_findOne", - "summary": "Get Test Suite Run", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + }, + "Server": { + "type": "object", + "properties": { + "timeoutSeconds": { + "type": "number", + "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20", + "minimum": 1, + "maximum": 300, + "example": 20 }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuiteRun" - } + "credentialId": { + "type": "string", + "description": "The credential ID for server authentication", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "url": { + "type": "string", + "description": "This is where the request will be sent." + }, + "headers": { + "type": "object", + "description": "These are the headers to include in the request.\n\nEach key-value pair represents a header name and its value." + }, + "backoffPlan": { + "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)", + "allOf": [ + { + "$ref": "#/components/schemas/BackoffPlan" } - } - } - }, - "tags": [ - "Test Suite Runs" - ], - "security": [ - { - "bearer": [] + ] } - ] + } }, - "patch": { - "operationId": "TestSuiteRunController_update", - "summary": "Update Test Suite Run", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "CustomTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used. Use `custom-transcriber` for providers that are not natively supported.", + "enum": [ + "custom-transcriber" + ] }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTestSuiteRunDto" + "server": { + "description": "This is where the transcription request will be sent.\n\nUsage:\n1. Vapi will initiate a websocket connection with `server.url`.\n\n2. Vapi will send an initial text frame with the sample rate. Format:\n```\n {\n \"type\": \"start\",\n \"encoding\": \"linear16\", // 16-bit raw PCM format\n \"container\": \"raw\",\n \"sampleRate\": {{sampleRate}},\n \"channels\": 2 // customer is channel 0, assistant is channel 1\n }\n```\n\n3. Vapi will send the audio data in 16-bit raw PCM format as binary frames.\n\n4. You can read the messages something like this:\n```\nws.on('message', (data, isBinary) => {\n if (isBinary) {\n pcmBuffer = Buffer.concat([pcmBuffer, data]);\n console.log(`Received PCM data, buffer size: ${pcmBuffer.length}`);\n } else {\n console.log('Received message:', JSON.parse(data.toString()));\n }\n});\n```\n\n5. You will respond with transcriptions as you have them. Format:\n```\n {\n \"type\": \"transcriber-response\",\n \"transcription\": \"Hello, world!\",\n \"channel\": \"customer\" | \"assistant\"\n }\n```", + "allOf": [ + { + "$ref": "#/components/schemas/Server" } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuiteRun" - } + ] + }, + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Test Suite Runs" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider", + "server" ] }, - "delete": { - "operationId": "TestSuiteRunController_remove", - "summary": "Delete Test Suite Run", - "parameters": [ - { - "name": "testSuiteId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "DeepgramTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "deepgram" + ] }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestSuiteRun" - } - } - } - } - }, - "tags": [ - "Test Suite Runs" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/analytics": { - "post": { - "operationId": "AnalyticsController_query", - "summary": "Create Analytics Queries", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AnalyticsQueryDTO" - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnalyticsQueryResult" - } - } + "model": { + "description": "This is the Deepgram model that will be used. A list of models can be found here: https://developers.deepgram.com/docs/models-languages-overview", + "oneOf": [ + { + "type": "string", + "enum": [ + "nova-3", + "nova-3-general", + "nova-3-medical", + "nova-2", + "nova-2-general", + "nova-2-meeting", + "nova-2-phonecall", + "nova-2-finance", + "nova-2-conversationalai", + "nova-2-voicemail", + "nova-2-video", + "nova-2-medical", + "nova-2-drivethru", + "nova-2-automotive", + "nova", + "nova-general", + "nova-phonecall", + "nova-medical", + "enhanced", + "enhanced-general", + "enhanced-meeting", + "enhanced-phonecall", + "enhanced-finance", + "base", + "base-general", + "base-meeting", + "base-phonecall", + "base-finance", + "base-conversationalai", + "base-voicemail", + "base-video", + "whisper" + ] + }, + { + "type": "string" } - } - }, - "201": { - "description": "" - } - }, - "tags": [ - "Analytics" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/logs": { - "get": { - "operationId": "LoggingController_logsQuery", - "summary": "Get Logs", - "deprecated": true, - "parameters": [ - { - "name": "type", - "required": false, - "in": "query", - "description": "This is the type of the log.", - "schema": { - "enum": [ - "API", - "Webhook", - "Call", - "Provider" - ], - "type": "string" - } - }, - { - "name": "webhookType", - "required": false, - "in": "query", - "description": "This is the type of the webhook, given the log is from a webhook.", - "schema": { - "type": "string" - } - }, - { - "name": "assistantId", - "required": false, - "in": "query", - "description": "This is the ID of the assistant.", - "schema": { - "type": "string" - } - }, - { - "name": "phoneNumberId", - "required": false, - "in": "query", - "description": "This is the ID of the phone number.", - "schema": { - "type": "string" - } - }, - { - "name": "customerId", - "required": false, - "in": "query", - "description": "This is the ID of the customer.", - "schema": { - "type": "string" - } - }, - { - "name": "squadId", - "required": false, - "in": "query", - "description": "This is the ID of the squad.", - "schema": { - "type": "string" - } - }, - { - "name": "callId", - "required": false, - "in": "query", - "description": "This is the ID of the call.", - "schema": { - "type": "string" - } - }, - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } - }, - { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "schema": { - "enum": [ - "ASC", - "DESC" - ], - "type": "string" - } + ] }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "This is the maximum number of items to return. Defaults to 100.", - "schema": { - "minimum": 0, - "maximum": 1000, - "type": "number" - } + "language": { + "type": "string", + "description": "This is the language that will be set for the transcription. The list of languages Deepgram supports can be found here: https://developers.deepgram.com/docs/models-languages-overview", + "enum": [ + "ar", + "az", + "ba", + "bg", + "br", + "ca", + "cs", + "da", + "da-DK", + "de", + "de-CH", + "el", + "en", + "en-AU", + "en-CA", + "en-GB", + "en-IE", + "en-IN", + "en-NZ", + "en-US", + "es", + "es-419", + "es-LATAM", + "et", + "eu", + "fi", + "fr", + "fr-CA", + "ha", + "haw", + "he", + "hi", + "hi-Latn", + "hu", + "id", + "is", + "it", + "ja", + "jw", + "kn", + "ko", + "ko-KR", + "ln", + "lt", + "lv", + "mk", + "ms", + "multi", + "nl", + "nl-BE", + "no", + "pl", + "pt", + "pt-BR", + "ro", + "ru", + "sk", + "sl", + "sn", + "so", + "sr", + "su", + "sv", + "sv-SE", + "ta", + "taq", + "th", + "th-TH", + "tr", + "tt", + "uk", + "ur", + "vi", + "yo", + "zh", + "zh-CN", + "zh-HK", + "zh-Hans", + "zh-Hant", + "zh-TW" + ] }, - { - "name": "createdAtGt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "smartFormat": { + "type": "boolean", + "description": "This will be use smart format option provided by Deepgram. It's default disabled because it can sometimes format numbers as times but it's getting better.", + "example": false }, - { - "name": "createdAtLt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "mipOptOut": { + "type": "boolean", + "description": "If set to true, this will add mip_opt_out=true as a query parameter of all API requests. See https://developers.deepgram.com/docs/the-deepgram-model-improvement-partnership-program#want-to-opt-out\n\nThis will only be used if you are using your own Deepgram API key.\n\n@default false", + "example": false, + "default": false }, - { - "name": "createdAtGe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "numerals": { + "type": "boolean", + "description": "If set to true, this will cause deepgram to convert spoken numbers to literal numerals. For example, \"my phone number is nine-seven-two...\" would become \"my phone number is 972...\"\n\n@default false", + "example": false }, - { - "name": "createdAtLe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "confidenceThreshold": { + "type": "number", + "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", + "minimum": 0, + "maximum": 1, + "example": 0.4 }, - { - "name": "updatedAtGt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" + "keywords": { + "description": "These keywords are passed to the transcription model to help it pick up use-case specific words. Anything that may not be a common word, like your company name, should be added here.", + "type": "array", + "items": { + "type": "string", + "pattern": "/^\\p{L}[\\p{L}\\d]*(?::[+-]?\\d+)?$/u" } }, - { - "name": "updatedAtLt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than the specified value.", - "schema": { - "format": "date-time", + "keyterm": { + "description": "Keyterm Prompting allows you improve Keyword Recall Rate (KRR) for important keyterms or phrases up to 90%.", + "type": "array", + "items": { "type": "string" } }, - { - "name": "updatedAtGe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "endpointing": { + "type": "number", + "description": "This is the timeout after which Deepgram will send transcription on user silence. You can read in-depth documentation here: https://developers.deepgram.com/docs/endpointing.\n\nHere are the most important bits:\n- Defaults to 10. This is recommended for most use cases to optimize for latency.\n- 10 can cause some missing transcriptions since because of the shorter context. This mostly happens for one-word utterances. For those uses cases, it's recommended to try 300. It will add a bit of latency but the quality and reliability of the experience will be better.\n- If neither 10 nor 300 work, contact support@vapi.ai and we'll find another solution.\n\n@default 10", + "minimum": 10, + "maximum": 500 }, - { - "name": "updatedAtLe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/LogsPaginatedResponse" - } + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Logs" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] }, - "delete": { - "operationId": "LoggingController_logsDeleteQuery", - "summary": "Delete Logs", - "deprecated": true, - "parameters": [ - { - "name": "type", - "required": false, - "in": "query", - "description": "This is the type of the log.", - "schema": { - "enum": [ - "API", - "Webhook", - "Call", - "Provider" - ], - "type": "string" - } - }, - { - "name": "assistantId", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "phoneNumberId", - "required": false, - "in": "query", - "description": "This is the ID of the phone number.", - "schema": { - "type": "string" - } - }, - { - "name": "customerId", - "required": false, - "in": "query", - "description": "This is the ID of the customer.", - "schema": { - "type": "string" - } - }, - { - "name": "squadId", - "required": false, - "in": "query", - "description": "This is the ID of the squad.", - "schema": { - "type": "string" - } - }, - { - "name": "callId", - "required": false, - "in": "query", - "description": "This is the ID of the call.", - "schema": { - "type": "string" - } - } - ], - "responses": { - "202": { - "description": "" - } - }, - "tags": [ - "Logs" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/structured-output": { - "get": { - "operationId": "StructuredOutputController_findAll", - "summary": "List Structured Outputs", - "parameters": [ - { - "name": "id", - "required": false, - "in": "query", - "description": "This will return structured outputs where the id matches the specified value.", - "schema": { - "type": "string" - } - }, - { - "name": "name", - "required": false, - "in": "query", - "description": "This will return structured outputs where the name matches the specified value.", - "schema": { - "type": "string" - } + "ElevenLabsTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "11labs" + ] }, - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } + "model": { + "type": "string", + "description": "This is the model that will be used for the transcription.", + "enum": [ + "scribe_v1" + ] }, - { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "schema": { - "enum": [ - "ASC", - "DESC" - ], - "type": "string" - } - }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "This is the maximum number of items to return. Defaults to 100.", - "schema": { - "minimum": 0, - "maximum": 1000, - "type": "number" - } - }, - { - "name": "createdAtGt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtLt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtGe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "createdAtLe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtGt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtLt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - }, - { - "name": "updatedAtGe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "language": { + "type": "string", + "enum": [ + "aa", + "ab", + "ae", + "af", + "ak", + "am", + "an", + "ar", + "as", + "av", + "ay", + "az", + "ba", + "be", + "bg", + "bh", + "bi", + "bm", + "bn", + "bo", + "br", + "bs", + "ca", + "ce", + "ch", + "co", + "cr", + "cs", + "cu", + "cv", + "cy", + "da", + "de", + "dv", + "dz", + "ee", + "el", + "en", + "eo", + "es", + "et", + "eu", + "fa", + "ff", + "fi", + "fj", + "fo", + "fr", + "fy", + "ga", + "gd", + "gl", + "gn", + "gu", + "gv", + "ha", + "he", + "hi", + "ho", + "hr", + "ht", + "hu", + "hy", + "hz", + "ia", + "id", + "ie", + "ig", + "ii", + "ik", + "io", + "is", + "it", + "iu", + "ja", + "jv", + "ka", + "kg", + "ki", + "kj", + "kk", + "kl", + "km", + "kn", + "ko", + "kr", + "ks", + "ku", + "kv", + "kw", + "ky", + "la", + "lb", + "lg", + "li", + "ln", + "lo", + "lt", + "lu", + "lv", + "mg", + "mh", + "mi", + "mk", + "ml", + "mn", + "mr", + "ms", + "mt", + "my", + "na", + "nb", + "nd", + "ne", + "ng", + "nl", + "nn", + "no", + "nr", + "nv", + "ny", + "oc", + "oj", + "om", + "or", + "os", + "pa", + "pi", + "pl", + "ps", + "pt", + "qu", + "rm", + "rn", + "ro", + "ru", + "rw", + "sa", + "sc", + "sd", + "se", + "sg", + "si", + "sk", + "sl", + "sm", + "sn", + "so", + "sq", + "sr", + "ss", + "st", + "su", + "sv", + "sw", + "ta", + "te", + "tg", + "th", + "ti", + "tk", + "tl", + "tn", + "to", + "tr", + "ts", + "tt", + "tw", + "ty", + "ug", + "uk", + "ur", + "uz", + "ve", + "vi", + "vo", + "wa", + "wo", + "xh", + "yi", + "yue", + "yo", + "za", + "zh", + "zu" + ] }, - { - "name": "updatedAtLe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StructuredOutputPaginatedResponse" - } + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Structured Outputs" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] }, - "post": { - "operationId": "StructuredOutputController_create", - "summary": "Create Structured Output", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStructuredOutputDTO" - } - } - } - }, - "responses": { - "201": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StructuredOutput" - } - } - } - } - }, - "tags": [ - "Structured Outputs" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/structured-output/{id}": { - "get": { - "operationId": "StructuredOutputController_findOne", - "summary": "Get Structured Output", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StructuredOutput" + "GladiaCustomVocabularyConfigDTO": { + "type": "object", + "properties": { + "vocabulary": { + "type": "array", + "description": "Array of vocabulary items (strings or objects with value, pronunciations, intensity, language)", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/GladiaVocabularyItemDTO" } - } + ] } + }, + "defaultIntensity": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Default intensity for vocabulary items (0.0 to 1.0)", + "default": 0.5 } }, - "tags": [ - "Structured Outputs" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "vocabulary" ] }, - "patch": { - "operationId": "StructuredOutputController_update", - "summary": "Update Structured Output", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "GladiaTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "gladia" + ] }, - { - "name": "schemaOverride", - "required": true, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStructuredOutputDTO" - } - } - } - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StructuredOutput" - } + "model": { + "description": "This is the Gladia model that will be used. Default is 'fast'", + "oneOf": [ + { + "enum": [ + "fast", + "accurate", + "solaria-1" + ] } - } - } - }, - "tags": [ - "Structured Outputs" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "delete": { - "operationId": "StructuredOutputController_remove", - "summary": "Delete Structured Output", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StructuredOutput" - } + ] + }, + "languageBehaviour": { + "description": "Defines how the transcription model detects the audio language. Default value is 'automatic single language'.", + "oneOf": [ + { + "type": "string", + "enum": [ + "manual", + "automatic single language", + "automatic multiple languages" + ] } - } - } - }, - "tags": [ - "Structured Outputs" - ], - "security": [ - { - "bearer": [] - } - ] - } - }, - "/provider/{provider}/{resourceName}": { - "post": { - "operationId": "ProviderResourceController_createProviderResource", - "summary": "Create Provider Resource", - "parameters": [ - { - "name": "content-type", - "required": true, - "in": "header", - "schema": { - "type": "string" - } - }, - { - "name": "provider", - "required": true, - "in": "path", - "description": "The provider (e.g., 11labs)", - "schema": { - "enum": [ - "11labs" - ], - "type": "string" - } - }, - { - "name": "resourceName", - "required": true, - "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", - "schema": { - "enum": [ - "pronunciation-dictionary" - ], - "type": "string" - } - } - ], - "responses": { - "201": { - "description": "Successfully created provider resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderResource" - } - } - } - } - }, - "tags": [ - "Provider Resources" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "get": { - "operationId": "ProviderResourceController_getProviderResourcesPaginated", - "summary": "List Provider Resources", - "parameters": [ - { - "name": "provider", - "required": true, - "in": "path", - "description": "The provider (e.g., 11labs)", - "schema": { - "enum": [ - "11labs" - ], - "type": "string" - } - }, - { - "name": "resourceName", - "required": true, - "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", - "schema": { - "enum": [ - "pronunciation-dictionary" - ], - "type": "string" - } - }, - { - "name": "id", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "resourceId", - "required": false, - "in": "query", - "schema": { - "type": "string" - } + ] }, - { - "name": "page", - "required": false, - "in": "query", - "description": "This is the page number to return. Defaults to 1.", - "schema": { - "minimum": 1, - "type": "number" - } + "language": { + "type": "string", + "description": "Defines the language to use for the transcription. Required when languageBehaviour is 'manual'.", + "enum": [ + "af", + "sq", + "am", + "ar", + "hy", + "as", + "az", + "ba", + "eu", + "be", + "bn", + "bs", + "br", + "bg", + "ca", + "zh", + "hr", + "cs", + "da", + "nl", + "en", + "et", + "fo", + "fi", + "fr", + "gl", + "ka", + "de", + "el", + "gu", + "ht", + "ha", + "haw", + "he", + "hi", + "hu", + "is", + "id", + "it", + "ja", + "jv", + "kn", + "kk", + "km", + "ko", + "lo", + "la", + "lv", + "ln", + "lt", + "lb", + "mk", + "mg", + "ms", + "ml", + "mt", + "mi", + "mr", + "mn", + "my", + "ne", + "no", + "nn", + "oc", + "ps", + "fa", + "pl", + "pt", + "pa", + "ro", + "ru", + "sa", + "sr", + "sn", + "sd", + "si", + "sk", + "sl", + "so", + "es", + "su", + "sw", + "sv", + "tl", + "tg", + "ta", + "tt", + "te", + "th", + "bo", + "tr", + "tk", + "uk", + "ur", + "uz", + "vi", + "cy", + "yi", + "yo" + ] }, - { - "name": "sortOrder", - "required": false, - "in": "query", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "schema": { - "enum": [ - "ASC", - "DESC" - ], - "type": "string" - } + "languages": { + "type": "string", + "description": "Defines the languages to use for the transcription. Required when languageBehaviour is 'manual'.", + "enum": [ + "af", + "sq", + "am", + "ar", + "hy", + "as", + "az", + "ba", + "eu", + "be", + "bn", + "bs", + "br", + "bg", + "ca", + "zh", + "hr", + "cs", + "da", + "nl", + "en", + "et", + "fo", + "fi", + "fr", + "gl", + "ka", + "de", + "el", + "gu", + "ht", + "ha", + "haw", + "he", + "hi", + "hu", + "is", + "id", + "it", + "ja", + "jv", + "kn", + "kk", + "km", + "ko", + "lo", + "la", + "lv", + "ln", + "lt", + "lb", + "mk", + "mg", + "ms", + "ml", + "mt", + "mi", + "mr", + "mn", + "my", + "ne", + "no", + "nn", + "oc", + "ps", + "fa", + "pl", + "pt", + "pa", + "ro", + "ru", + "sa", + "sr", + "sn", + "sd", + "si", + "sk", + "sl", + "so", + "es", + "su", + "sw", + "sv", + "tl", + "tg", + "ta", + "tt", + "te", + "th", + "bo", + "tr", + "tk", + "uk", + "ur", + "uz", + "vi", + "cy", + "yi", + "yo" + ] }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "This is the maximum number of items to return. Defaults to 100.", - "schema": { - "minimum": 0, - "maximum": 1000, - "type": "number" - } + "transcriptionHint": { + "type": "string", + "description": "Provides a custom vocabulary to the model to improve accuracy of transcribing context specific words, technical terms, names, etc. If empty, this argument is ignored.\n⚠️ Warning ⚠️: Please be aware that the transcription_hint field has a character limit of 600. If you provide a transcription_hint longer than 600 characters, it will be automatically truncated to meet this limit.", + "maxLength": 600, + "example": "custom vocabulary" }, - { - "name": "createdAtGt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "prosody": { + "type": "boolean", + "description": "If prosody is true, you will get a transcription that can contain prosodies i.e. (laugh) (giggles) (malefic laugh) (toss) (music)… Default value is false.", + "example": false }, - { - "name": "createdAtLt", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "audioEnhancer": { + "type": "boolean", + "description": "If true, audio will be pre-processed to improve accuracy but latency will increase. Default value is false.", + "example": false }, - { - "name": "createdAtGe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "confidenceThreshold": { + "type": "number", + "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", + "minimum": 0, + "maximum": 1, + "example": 0.4 }, - { - "name": "createdAtLe", - "required": false, - "in": "query", - "description": "This will return items where the createdAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "endpointing": { + "type": "number", + "minimum": 0.01, + "maximum": 10, + "example": 0.05, + "description": "Endpointing time in seconds - time to wait before considering speech ended" }, - { - "name": "updatedAtGt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "speechThreshold": { + "type": "number", + "minimum": 0, + "maximum": 1, + "example": 0.6, + "description": "Speech threshold - sensitivity configuration for speech detection (0.0 to 1.0)" }, - { - "name": "updatedAtLt", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "customVocabularyEnabled": { + "type": "boolean", + "example": false, + "description": "Enable custom vocabulary for improved accuracy" }, - { - "name": "updatedAtGe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is greater than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } + "customVocabularyConfig": { + "description": "Custom vocabulary configuration", + "allOf": [ + { + "$ref": "#/components/schemas/GladiaCustomVocabularyConfigDTO" + } + ] }, - { - "name": "updatedAtLe", - "required": false, - "in": "query", - "description": "This will return items where the updatedAt is less than or equal to the specified value.", - "schema": { - "format": "date-time", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "List of provider resources", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderResourcePaginatedResponse" - } + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } + ] } }, - "tags": [ - "Provider Resources" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] - } - }, - "/provider/{provider}/{resourceName}/{id}": { - "get": { - "operationId": "ProviderResourceController_getProviderResource", - "summary": "Get Provider Resource", - "parameters": [ - { - "name": "provider", - "required": true, - "in": "path", - "description": "The provider (e.g., 11labs)", - "schema": { - "enum": [ - "11labs" - ], - "type": "string" - } + }, + "SpeechmaticsTranscriber": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "speechmatics" + ] }, - { - "name": "resourceName", - "required": true, - "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", - "schema": { - "enum": [ - "pronunciation-dictionary" - ], - "type": "string" - } - }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Successfully retrieved provider resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderResource" - } - } - } - }, - "404": { - "description": "Provider resource not found" - } - }, - "tags": [ - "Provider Resources" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "delete": { - "operationId": "ProviderResourceController_deleteProviderResource", - "summary": "Delete Provider Resource", - "parameters": [ - { - "name": "provider", - "required": true, - "in": "path", - "description": "The provider (e.g., 11labs)", - "schema": { - "enum": [ - "11labs" - ], - "type": "string" - } - }, - { - "name": "resourceName", - "required": true, - "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", - "schema": { - "enum": [ - "pronunciation-dictionary" - ], - "type": "string" - } - }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderResource" - } - } - } - }, - "404": { - "description": "Provider resource not found" - } - }, - "tags": [ - "Provider Resources" - ], - "security": [ - { - "bearer": [] - } - ] - }, - "patch": { - "operationId": "ProviderResourceController_updateProviderResource", - "summary": "Update Provider Resource", - "parameters": [ - { - "name": "provider", - "required": true, - "in": "path", - "description": "The provider (e.g., 11labs)", - "schema": { - "enum": [ - "11labs" - ], - "type": "string" - } + "model": { + "type": "string", + "description": "This is the model that will be used for the transcription.", + "enum": [ + "default" + ] }, - { - "name": "resourceName", - "required": true, - "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", - "schema": { - "enum": [ - "pronunciation-dictionary" - ], - "type": "string" - } + "language": { + "type": "string", + "enum": [ + "auto", + "ar", + "ba", + "eu", + "be", + "bn", + "bg", + "yue", + "ca", + "hr", + "cs", + "da", + "nl", + "en", + "eo", + "et", + "fi", + "fr", + "gl", + "de", + "el", + "he", + "hi", + "hu", + "id", + "ia", + "ga", + "it", + "ja", + "ko", + "lv", + "lt", + "ms", + "mt", + "cmn", + "mr", + "mn", + "no", + "fa", + "pl", + "pt", + "ro", + "ru", + "sk", + "sl", + "es", + "sw", + "sv", + "ta", + "th", + "tr", + "uk", + "ur", + "ug", + "vi", + "cy" + ] }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProviderResource" - } + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackTranscriberPlan" } - } - }, - "404": { - "description": "Provider resource not found" + ] } }, - "tags": [ - "Provider Resources" - ], - "security": [ - { - "bearer": [] - } + "required": [ + "provider" ] - } - } - }, - "info": { - "title": "Vapi API", - "description": "Voice AI for developers.", - "version": "1.0", - "contact": {} - }, - "tags": [], - "servers": [ - { - "url": "https://api.vapi.ai" - } - ], - "components": { - "securitySchemes": { - "bearer": { - "scheme": "bearer", - "bearerFormat": "Bearer", - "type": "http", - "description": "Retrieve your API Key from [Dashboard](dashboard.vapi.ai)." - } - }, - "schemas": { - "AnalysisCostBreakdown": { - "type": "object", - "properties": { - "summary": { - "type": "number", - "description": "This is the cost to summarize the call." - }, - "summaryPromptTokens": { - "type": "number", - "description": "This is the number of prompt tokens used to summarize the call." - }, - "summaryCompletionTokens": { - "type": "number", - "description": "This is the number of completion tokens used to summarize the call." - }, - "structuredData": { - "type": "number", - "description": "This is the cost to extract structured data from the call." - }, - "structuredDataPromptTokens": { - "type": "number", - "description": "This is the number of prompt tokens used to extract structured data from the call." - }, - "structuredDataCompletionTokens": { - "type": "number", - "description": "This is the number of completion tokens used to extract structured data from the call." - }, - "successEvaluation": { - "type": "number", - "description": "This is the cost to evaluate if the call was successful." - }, - "successEvaluationPromptTokens": { - "type": "number", - "description": "This is the number of prompt tokens used to evaluate if the call was successful." - }, - "successEvaluationCompletionTokens": { - "type": "number", - "description": "This is the number of completion tokens used to evaluate if the call was successful." - }, - "structuredOutput": { - "type": "number", - "description": "This is the cost to evaluate structuredOutputs from the call." - }, - "structuredOutputPromptTokens": { - "type": "number", - "description": "This is the number of prompt tokens used to evaluate structuredOutputs from the call." - }, - "structuredOutputCompletionTokens": { - "type": "number", - "description": "This is the number of completion tokens used to evaluate structuredOutputs from the call." - } - } }, - "CostBreakdown": { + "TalkscriberTranscriber": { "type": "object", "properties": { - "transport": { - "type": "number", - "description": "This is the cost of the transport provider, like Twilio or Vonage." - }, - "stt": { - "type": "number", - "description": "This is the cost of the speech-to-text service." - }, - "llm": { - "type": "number", - "description": "This is the cost of the language model." - }, - "tts": { - "type": "number", - "description": "This is the cost of the text-to-speech service." - }, - "vapi": { - "type": "number", - "description": "This is the cost of Vapi." - }, - "chat": { - "type": "number", - "description": "This is the cost of chat interactions." - }, - "total": { - "type": "number", - "description": "This is the total cost of the call." - }, - "llmPromptTokens": { - "type": "number", - "description": "This is the LLM prompt tokens used for the call." + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "talkscriber" + ] }, - "llmCompletionTokens": { - "type": "number", - "description": "This is the LLM completion tokens used for the call." + "model": { + "type": "string", + "description": "This is the model that will be used for the transcription.", + "enum": [ + "whisper" + ] }, - "ttsCharacters": { - "type": "number", - "description": "This is the TTS characters used for the call." + "language": { + "type": "string", + "description": "This is the language that will be set for the transcription. The list of languages Whisper supports can be found here: https://github.com/openai/whisper/blob/main/whisper/tokenizer.py", + "enum": [ + "en", + "zh", + "de", + "es", + "ru", + "ko", + "fr", + "ja", + "pt", + "tr", + "pl", + "ca", + "nl", + "ar", + "sv", + "it", + "id", + "hi", + "fi", + "vi", + "he", + "uk", + "el", + "ms", + "cs", + "ro", + "da", + "hu", + "ta", + "no", + "th", + "ur", + "hr", + "bg", + "lt", + "la", + "mi", + "ml", + "cy", + "sk", + "te", + "fa", + "lv", + "bn", + "sr", + "az", + "sl", + "kn", + "et", + "mk", + "br", + "eu", + "is", + "hy", + "ne", + "mn", + "bs", + "kk", + "sq", + "sw", + "gl", + "mr", + "pa", + "si", + "km", + "sn", + "yo", + "so", + "af", + "oc", + "ka", + "be", + "tg", + "sd", + "gu", + "am", + "yi", + "lo", + "uz", + "fo", + "ht", + "ps", + "tk", + "nn", + "mt", + "sa", + "lb", + "my", + "bo", + "tl", + "mg", + "as", + "tt", + "haw", + "ln", + "ha", + "ba", + "jw", + "su", + "yue" + ] }, - "analysisCostBreakdown": { - "description": "This is the cost of the analysis.", + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", "allOf": [ { - "$ref": "#/components/schemas/AnalysisCostBreakdown" + "$ref": "#/components/schemas/FallbackTranscriberPlan" } ] } - } - }, - "TranscriptPlan": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "description": "This determines whether the transcript is stored in `call.artifact.transcript`. Defaults to true.\n\n@default true", - "example": true - }, - "assistantName": { - "type": "string", - "description": "This is the name of the assistant in the transcript. Defaults to 'AI'.\n\nUsage:\n- If you want to change the name of the assistant in the transcript, set this. Example, here is what the transcript would look like with `assistantName` set to 'Buyer':\n```\nUser: Hello, how are you?\nBuyer: I'm fine.\nUser: Do you want to buy a car?\nBuyer: No.\n```\n\n@default 'AI'" - }, - "userName": { - "type": "string", - "description": "This is the name of the user in the transcript. Defaults to 'User'.\n\nUsage:\n- If you want to change the name of the user in the transcript, set this. Example, here is what the transcript would look like with `userName` set to 'Seller':\n```\nSeller: Hello, how are you?\nAI: I'm fine.\nSeller: Do you want to buy a car?\nAI: No.\n```\n\n@default 'User'" - } - } + }, + "required": [ + "provider" + ] }, - "ArtifactPlan": { + "GoogleTranscriber": { "type": "object", "properties": { - "recordingEnabled": { - "type": "boolean", - "description": "This determines whether assistant's calls are recorded. Defaults to true.\n\nUsage:\n- If you don't want to record the calls, set this to false.\n- If you want to record the calls when `assistant.hipaaEnabled` (deprecated) or `assistant.compliancePlan.hipaaEnabled` explicity set this to true and make sure to provide S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nYou can find the recording at `call.artifact.recordingUrl` and `call.artifact.stereoRecordingUrl` after the call is ended.\n\n@default true", - "example": true - }, - "recordingFormat": { + "provider": { "type": "string", - "description": "This determines the format of the recording. Defaults to `wav;l16`.\n\n@default 'wav;l16'", + "description": "This is the transcription provider that will be used.", "enum": [ - "wav;l16", - "mp3" + "google" ] }, - "videoRecordingEnabled": { - "type": "boolean", - "description": "This determines whether the video is recorded during the call. Defaults to false. Only relevant for `webCall` type.\n\nYou can find the video recording at `call.artifact.videoRecordingUrl` after the call is ended.\n\n@default false", - "example": false - }, - "pcapEnabled": { - "type": "boolean", - "description": "This determines whether the SIP packet capture is enabled. Defaults to true. Only relevant for `phone` type calls where phone number's provider is `vapi` or `byo-phone-number`.\n\nYou can find the packet capture at `call.artifact.pcapUrl` after the call is ended.\n\n@default true", - "example": true - }, - "pcapS3PathPrefix": { + "model": { "type": "string", - "description": "This is the path where the SIP packet capture will be uploaded. This is only used if you have provided S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nIf credential.s3PathPrefix or credential.bucketPlan.path is set, this will append to it.\n\nUsage:\n- If you want to upload the packet capture to a specific path, set this to the path. Example: `/my-assistant-captures`.\n- If you want to upload the packet capture to the root of the bucket, set this to `/`.\n\n@default '/'", - "example": "/pcaps" + "description": "This is the model that will be used for the transcription.", + "enum": [ + "gemini-2.5-pro", + "gemini-2.5-flash", + "gemini-2.5-flash-lite", + "gemini-2.0-flash-thinking-exp", + "gemini-2.0-pro-exp-02-05", + "gemini-2.0-flash", + "gemini-2.0-flash-lite", + "gemini-2.0-flash-exp", + "gemini-2.0-flash-realtime-exp", + "gemini-1.5-flash", + "gemini-1.5-flash-002", + "gemini-1.5-pro", + "gemini-1.5-pro-002", + "gemini-1.0-pro" + ] }, - "loggingEnabled": { - "type": "boolean", - "description": "This determines whether the call logs are enabled. Defaults to true.\n\n@default true", - "example": true + "language": { + "type": "string", + "description": "This is the language that will be set for the transcription.", + "enum": [ + "Multilingual", + "Arabic", + "Bengali", + "Bulgarian", + "Chinese", + "Croatian", + "Czech", + "Danish", + "Dutch", + "English", + "Estonian", + "Finnish", + "French", + "German", + "Greek", + "Hebrew", + "Hindi", + "Hungarian", + "Indonesian", + "Italian", + "Japanese", + "Korean", + "Latvian", + "Lithuanian", + "Norwegian", + "Polish", + "Portuguese", + "Romanian", + "Russian", + "Serbian", + "Slovak", + "Slovenian", + "Spanish", + "Swahili", + "Swedish", + "Thai", + "Turkish", + "Ukrainian", + "Vietnamese" + ] }, - "transcriptPlan": { - "description": "This is the plan for `call.artifact.transcript`. To disable, set `transcriptPlan.enabled` to false.", + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", "allOf": [ { - "$ref": "#/components/schemas/TranscriptPlan" + "$ref": "#/components/schemas/FallbackTranscriberPlan" } ] - }, - "recordingPath": { - "type": "string", - "description": "This is the path where the recording will be uploaded. This is only used if you have provided S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nIf credential.s3PathPrefix or credential.bucketPlan.path is set, this will append to it.\n\nUsage:\n- If you want to upload the recording to a specific path, set this to the path. Example: `/my-assistant-recordings`.\n- If you want to upload the recording to the root of the bucket, set this to `/`.\n\n@default '/'" - }, - "structuredOutputIds": { - "description": "This is an array of structured output IDs to be calculated during the call.\nThe outputs will be extracted and stored in `call.artifact.structuredOutputs` after the call is ended.", - "type": "array", - "items": { - "type": "string" - } - }, - "loggingPath": { - "type": "string", - "description": "This is the path where the call logs will be uploaded. This is only used if you have provided S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nIf credential.s3PathPrefix or credential.bucketPlan.path is set, this will append to it.\n\nUsage:\n- If you want to upload the call logs to a specific path, set this to the path. Example: `/my-assistant-logs`.\n- If you want to upload the call logs to the root of the bucket, set this to `/`.\n\n@default '/'" - } - } - }, - "Analysis": { - "type": "object", - "properties": { - "summary": { - "type": "string", - "description": "This is the summary of the call. Customize by setting `assistant.analysisPlan.summaryPrompt`." - }, - "structuredData": { - "type": "object", - "description": "This is the structured data extracted from the call. Customize by setting `assistant.analysisPlan.structuredDataPrompt` and/or `assistant.analysisPlan.structuredDataSchema`." - }, - "structuredDataMulti": { - "description": "This is the structured data catalog of the call. Customize by setting `assistant.analysisPlan.structuredDataMultiPlan`.", - "type": "array", - "items": { - "type": "object" - } - }, - "successEvaluation": { - "type": "string", - "description": "This is the evaluation of the call. Customize by setting `assistant.analysisPlan.successEvaluationPrompt` and/or `assistant.analysisPlan.successEvaluationRubric`." - } - } - }, - "Monitor": { - "type": "object", - "properties": { - "listenUrl": { - "type": "string", - "description": "This is the URL where the assistant's calls can be listened to in real-time. To enable, set `assistant.monitorPlan.listenEnabled` to `true`." - }, - "controlUrl": { - "type": "string", - "description": "This is the URL where the assistant's calls can be controlled in real-time. To enable, set `assistant.monitorPlan.controlEnabled` to `true`." - } - } - }, - "OpenAIMessage": { - "type": "object", - "properties": { - "content": { - "type": "string", - "nullable": true, - "maxLength": 100000000 - }, - "role": { - "type": "string", - "enum": [ - "assistant", - "function", - "user", - "system", - "tool" - ] } }, "required": [ - "content", - "role" + "provider" ] }, - "Mono": { + "OpenAITranscriber": { "type": "object", "properties": { - "combinedUrl": { - "type": "string", - "description": "This is the combined recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`." - }, - "assistantUrl": { + "provider": { "type": "string", - "description": "This is the mono recording url for the assistant. To enable, set `assistant.artifactPlan.recordingEnabled`." + "description": "This is the transcription provider that will be used.", + "enum": [ + "openai" + ] }, - "customerUrl": { - "type": "string", - "description": "This is the mono recording url for the customer. To enable, set `assistant.artifactPlan.recordingEnabled`." - } - } - }, - "Recording": { - "type": "object", - "properties": { - "stereoUrl": { + "model": { "type": "string", - "description": "This is the stereo recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`." + "description": "This is the model that will be used for the transcription.", + "enum": [ + "gpt-4o-transcribe", + "gpt-4o-mini-transcribe" + ] }, - "videoUrl": { + "language": { "type": "string", - "description": "This is the video recording url for the call. To enable, set `assistant.artifactPlan.videoRecordingEnabled`." - }, - "videoRecordingStartDelaySeconds": { - "type": "number", - "description": "This is video recording start delay in ms. To enable, set `assistant.artifactPlan.videoRecordingEnabled`. This can be used to align the playback of the recording with artifact.messages timestamps." + "description": "This is the language that will be set for the transcription.", + "enum": [ + "af", + "ar", + "hy", + "az", + "be", + "bs", + "bg", + "ca", + "zh", + "hr", + "cs", + "da", + "nl", + "en", + "et", + "fi", + "fr", + "gl", + "de", + "el", + "he", + "hi", + "hu", + "is", + "id", + "it", + "ja", + "kn", + "kk", + "ko", + "lv", + "lt", + "mk", + "ms", + "mr", + "mi", + "ne", + "no", + "fa", + "pl", + "pt", + "ro", + "ru", + "sr", + "sk", + "sl", + "es", + "sw", + "sv", + "tl", + "ta", + "th", + "tr", + "uk", + "ur", + "vi", + "cy" + ] }, - "mono": { - "description": "This is the mono recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", + "fallbackPlan": { + "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", "allOf": [ { - "$ref": "#/components/schemas/Mono" + "$ref": "#/components/schemas/FallbackTranscriberPlan" } ] } - } + }, + "required": [ + "provider", + "model" + ] }, - "NodeArtifact": { + "FallbackAssemblyAITranscriber": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that were spoken during the node.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/BotMessage", - "title": "BotMessage" - }, - { - "$ref": "#/components/schemas/ToolCallMessage", - "title": "ToolCallMessage" - }, - { - "$ref": "#/components/schemas/ToolCallResultMessage", - "title": "ToolCallResultMessage" - } - ] - } + "provider": { + "type": "string", + "description": "This is the transcription provider that will be used.", + "enum": [ + "assembly-ai" + ] }, - "nodeName": { + "language": { "type": "string", - "description": "This is the node name." + "description": "This is the language that will be set for the transcription.", + "enum": [ + "en" + ] }, - "variableValues": { - "type": "object", - "description": "These are the variable values that were extracted from the node." - } - } - }, - "TurnLatency": { - "type": "object", - "properties": { - "modelLatency": { + "confidenceThreshold": { "type": "number", - "description": "This is the model latency for the first token." + "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", + "minimum": 0, + "maximum": 1, + "example": 0.4 }, - "voiceLatency": { - "type": "number", - "description": "This is the voice latency from the model output." + "formatTurns": { + "type": "boolean", + "description": "This enables formatting of transcripts.\n\n@default true", + "example": true }, - "transcriberLatency": { + "endOfTurnConfidenceThreshold": { "type": "number", - "description": "This is the transcriber latency from the user speech." + "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\n\n@min 0\n@max 1\n@default 0.7", + "minimum": 0, + "maximum": 1, + "example": 0.7 }, - "endpointingLatency": { + "minEndOfTurnSilenceWhenConfident": { "type": "number", - "description": "This is the endpointing latency." + "description": "This is the minimum end of turn silence when confident in milliseconds.\n\n@default 160", + "minimum": 0, + "example": 160 }, - "turnLatency": { + "wordFinalizationMaxWaitTime": { "type": "number", - "description": "This is the latency for the whole turn." - } - } - }, - "PerformanceMetrics": { - "type": "object", - "properties": { - "turnLatencies": { - "description": "These are the individual latencies for each turn.", - "type": "array", - "items": { - "$ref": "#/components/schemas/TurnLatency" - } + "description": "This is the maximum wait time for word finalization in milliseconds.\n\n@default 160", + "minimum": 0, + "example": 160 }, - "modelLatencyAverage": { + "maxTurnSilence": { "type": "number", - "description": "This is the average latency for the model to output the first token." + "description": "This is the maximum turn silence time in milliseconds.\n\n@default 400", + "minimum": 0, + "example": 400 }, - "voiceLatencyAverage": { - "type": "number", - "description": "This is the average latency for the text to speech." + "realtimeUrl": { + "type": "string", + "description": "The WebSocket URL that the transcriber connects to." }, - "transcriberLatencyAverage": { - "type": "number", - "description": "This is the average latency for the transcriber." + "wordBoost": { + "description": "Add up to 2500 characters of custom vocabulary.", + "type": "array", + "items": { + "type": "string", + "maxLength": 2500 + } }, - "endpointingLatencyAverage": { + "endUtteranceSilenceThreshold": { "type": "number", - "description": "This is the average latency for the endpointing." + "description": "The duration of the end utterance silence threshold in milliseconds." }, - "turnLatencyAverage": { - "type": "number", - "description": "This is the average latency for complete turns." + "disablePartialTranscripts": { + "type": "boolean", + "description": "Disable partial transcripts.\nSet to `true` to not receive partial transcripts. Defaults to `false`." } - } + }, + "required": [ + "provider" + ] }, - "Artifact": { + "FallbackAzureSpeechTranscriber": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that were spoken during the call.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/BotMessage", - "title": "BotMessage" - }, - { - "$ref": "#/components/schemas/ToolCallMessage", - "title": "ToolCallMessage" - }, - { - "$ref": "#/components/schemas/ToolCallResultMessage", - "title": "ToolCallResultMessage" - } - ] - } - }, - "messagesOpenAIFormatted": { - "description": "These are the messages that were spoken during the call, formatted for OpenAI.", - "type": "array", - "items": { - "$ref": "#/components/schemas/OpenAIMessage" - } - }, - "recordingUrl": { - "type": "string", - "description": "This is the recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", - "deprecated": true - }, - "stereoRecordingUrl": { - "type": "string", - "description": "This is the stereo recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", - "deprecated": true - }, - "videoRecordingUrl": { + "provider": { "type": "string", - "description": "This is video recording url for the call. To enable, set `assistant.artifactPlan.videoRecordingEnabled`.", - "deprecated": true - }, - "videoRecordingStartDelaySeconds": { - "type": "number", - "description": "This is video recording start delay in ms. To enable, set `assistant.artifactPlan.videoRecordingEnabled`. This can be used to align the playback of the recording with artifact.messages timestamps.", - "deprecated": true - }, - "recording": { - "description": "This is the recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", - "allOf": [ - { - "$ref": "#/components/schemas/Recording" - } + "description": "This is the transcription provider that will be used.", + "enum": [ + "azure" ] }, - "transcript": { - "type": "string", - "description": "This is the transcript of the call. This is derived from `artifact.messages` but provided for convenience." - }, - "pcapUrl": { - "type": "string", - "description": "This is the packet capture url for the call. This is only available for `phone` type calls where phone number's provider is `vapi` or `byo-phone-number`." - }, - "logUrl": { - "type": "string", - "description": "This is the url for the call logs. This includes all logging output during the call for debugging purposes." - }, - "nodes": { - "description": "This is the history of workflow nodes that were executed during the call.", - "type": "array", - "items": { - "$ref": "#/components/schemas/NodeArtifact" - } - }, - "variableValues": { - "type": "object", - "description": "These are the variable values at the end of the workflow execution." - }, - "performanceMetrics": { - "description": "This is the performance metrics for the call. It contains the turn latency, broken down by component.", - "allOf": [ - { - "$ref": "#/components/schemas/PerformanceMetrics" - } - ] - }, - "structuredOutputs": { - "type": "object", - "description": "These are the structured outputs that will be extracted from the call.\nTo enable, set `assistant.artifactPlan.structuredOutputIds` with the IDs of the structured outputs you want to extract." - } - } - }, - "FallbackTranscriberPlan": { - "type": "object", - "properties": { - "transcribers": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/FallbackAssemblyAITranscriber", - "title": "AssemblyAI" - }, - { - "$ref": "#/components/schemas/FallbackAzureSpeechTranscriber", - "title": "Azure" - }, - { - "$ref": "#/components/schemas/FallbackCustomTranscriber", - "title": "Custom" - }, - { - "$ref": "#/components/schemas/FallbackDeepgramTranscriber", - "title": "Deepgram" - }, - { - "$ref": "#/components/schemas/FallbackElevenLabsTranscriber", - "title": "ElevenLabs" - }, - { - "$ref": "#/components/schemas/FallbackGladiaTranscriber", - "title": "Gladia" - }, - { - "$ref": "#/components/schemas/FallbackGoogleTranscriber", - "title": "Google" - }, - { - "$ref": "#/components/schemas/FallbackTalkscriberTranscriber", - "title": "Talkscriber" - }, - { - "$ref": "#/components/schemas/FallbackSpeechmaticsTranscriber", - "title": "Speechmatics" - }, - { - "$ref": "#/components/schemas/FallbackOpenAITranscriber", - "title": "OpenAI" - }, - { - "$ref": "#/components/schemas/FallbackCartesiaTranscriber", - "title": "Cartesia" - } - ] - } - } - }, - "required": [ - "transcribers" - ] - }, - "AssemblyAITranscriber": { - "type": "object", - "properties": { - "provider": { - "type": "string", - "description": "This is the transcription provider that will be used.", - "enum": [ - "assembly-ai" - ] - }, - "language": { - "type": "string", - "description": "This is the language that will be set for the transcription.", - "enum": [ - "en" - ] - }, - "confidenceThreshold": { - "type": "number", - "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", - "minimum": 0, - "maximum": 1, - "example": 0.4 - }, - "formatTurns": { - "type": "boolean", - "description": "This enables formatting of transcripts.\n\n@default true", - "example": true - }, - "endOfTurnConfidenceThreshold": { - "type": "number", - "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\n\n@min 0\n@max 1\n@default 0.7", - "minimum": 0, - "maximum": 1, - "example": 0.7 - }, - "minEndOfTurnSilenceWhenConfident": { - "type": "number", - "description": "This is the minimum end of turn silence when confident in milliseconds.\n\n@default 160", - "minimum": 0, - "example": 160 - }, - "wordFinalizationMaxWaitTime": { - "type": "number", - "description": "This is the maximum wait time for word finalization in milliseconds.\n\n@default 160", - "minimum": 0, - "example": 160 - }, - "maxTurnSilence": { - "type": "number", - "description": "This is the maximum turn silence time in milliseconds.\n\n@default 400", - "minimum": 0, - "example": 400 - }, - "realtimeUrl": { - "type": "string", - "description": "The WebSocket URL that the transcriber connects to." - }, - "wordBoost": { - "description": "Add up to 2500 characters of custom vocabulary.", - "type": "array", - "items": { - "type": "string", - "maxLength": 2500 - } - }, - "endUtteranceSilenceThreshold": { - "type": "number", - "description": "The duration of the end utterance silence threshold in milliseconds." - }, - "disablePartialTranscripts": { - "type": "boolean", - "description": "Disable partial transcripts.\nSet to `true` to not receive partial transcripts. Defaults to `false`." - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] - } - }, - "required": [ - "provider" - ] - }, - "AzureSpeechTranscriber": { - "type": "object", - "properties": { - "provider": { - "type": "string", - "description": "This is the transcription provider that will be used.", - "enum": [ - "azure" - ] - }, - "language": { + "language": { "type": "string", "description": "This is the language that will be set for the transcription. The list of languages Azure supports can be found here: https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=stt", "enum": [ @@ -7070,21 +6443,13 @@ "description": "Maximum duration a segment can reach before being cut off when using time-based segmentation.", "minimum": 20000, "maximum": 70000 - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "CartesiaTranscriber": { + "FallbackCartesiaTranscriber": { "type": "object", "properties": { "provider": { @@ -7288,95 +6653,13 @@ "zh", "zu" ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "BackoffPlan": { - "type": "object", - "properties": { - "type": { - "type": "object", - "description": "This is the type of backoff plan to use. Defaults to fixed.\n\n@default fixed", - "enum": [ - "fixed", - "exponential" - ], - "example": "fixed" - }, - "maxRetries": { - "type": "number", - "description": "This is the maximum number of retries to attempt if the request fails. Defaults to 0 (no retries).\n\n@default 0", - "minimum": 0, - "maximum": 10, - "example": 0 - }, - "baseDelaySeconds": { - "type": "number", - "description": "This is the base delay in seconds. For linear backoff, this is the delay between each retry. For exponential backoff, this is the initial delay.", - "minimum": 0, - "maximum": 10, - "example": 1 - }, - "excludedStatusCodes": { - "description": "This is the excluded status codes. If the response status code is in this list, the request will not be retried.\nBy default, the request will be retried for any non-2xx status code.", - "example": [ - 400, - 401, - 403, - 404 - ], - "type": "array", - "items": { - "type": "object" - } - } - }, - "required": [ - "type", - "maxRetries", - "baseDelaySeconds" - ] - }, - "Server": { - "type": "object", - "properties": { - "timeoutSeconds": { - "type": "number", - "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20", - "minimum": 1, - "maximum": 300, - "example": 20 - }, - "url": { - "type": "string", - "description": "This is where the request will be sent." - }, - "headers": { - "type": "object", - "description": "These are the headers to include in the request.\n\nEach key-value pair represents a header name and its value." - }, - "backoffPlan": { - "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)", - "allOf": [ - { - "$ref": "#/components/schemas/BackoffPlan" - } - ] - } - } - }, - "CustomTranscriber": { + "FallbackCustomTranscriber": { "type": "object", "properties": { "provider": { @@ -7393,14 +6676,6 @@ "$ref": "#/components/schemas/Server" } ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ @@ -7408,7 +6683,7 @@ "server" ] }, - "DeepgramTranscriber": { + "FallbackDeepgramTranscriber": { "type": "object", "properties": { "provider": { @@ -7592,21 +6867,13 @@ "description": "This is the timeout after which Deepgram will send transcription on user silence. You can read in-depth documentation here: https://developers.deepgram.com/docs/endpointing.\n\nHere are the most important bits:\n- Defaults to 10. This is recommended for most use cases to optimize for latency.\n- 10 can cause some missing transcriptions since because of the shorter context. This mostly happens for one-word utterances. For those uses cases, it's recommended to try 300. It will add a bit of latency but the quality and reliability of the experience will be better.\n- If neither 10 nor 300 work, contact support@vapi.ai and we'll find another solution.\n\n@default 10", "minimum": 10, "maximum": 500 - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "ElevenLabsTranscriber": { + "FallbackElevenLabsTranscriber": { "type": "object", "properties": { "provider": { @@ -7812,50 +7079,42 @@ "zh", "zu" ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "GladiaCustomVocabularyConfigDTO": { + "GladiaVocabularyItemDTO": { "type": "object", "properties": { - "vocabulary": { + "value": { + "type": "string", + "description": "The vocabulary word or phrase" + }, + "pronunciations": { + "description": "Alternative pronunciations for the vocabulary item", "type": "array", - "description": "Array of vocabulary items (strings or objects with value, pronunciations, intensity, language)", "items": { - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/GladiaVocabularyItemDTO" - } - ] + "type": "string" } }, - "defaultIntensity": { + "intensity": { "type": "number", "minimum": 0, "maximum": 1, - "description": "Default intensity for vocabulary items (0.0 to 1.0)", - "default": 0.5 + "description": "Intensity for this specific vocabulary item (0.0 to 1.0)" + }, + "language": { + "type": "string", + "description": "Language code for this vocabulary item (ISO 639-1)" } }, "required": [ - "vocabulary" + "value" ] }, - "GladiaTranscriber": { + "FallbackGladiaTranscriber": { "type": "object", "properties": { "provider": { @@ -8149,21 +7408,13 @@ "$ref": "#/components/schemas/GladiaCustomVocabularyConfigDTO" } ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "SpeechmaticsTranscriber": { + "FallbackSpeechmaticsTranscriber": { "type": "object", "properties": { "provider": { @@ -8240,21 +7491,13 @@ "vi", "cy" ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "TalkscriberTranscriber": { + "FallbackTalkscriberTranscriber": { "type": "object", "properties": { "provider": { @@ -8376,21 +7619,13 @@ "su", "yue" ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "GoogleTranscriber": { + "FallbackGoogleTranscriber": { "type": "object", "properties": { "provider": { @@ -8464,21 +7699,13 @@ "Ukrainian", "Vietnamese" ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ "provider" ] }, - "OpenAITranscriber": { + "FallbackOpenAITranscriber": { "type": "object", "properties": { "provider": { @@ -8558,14 +7785,6 @@ "vi", "cy" ] - }, - "fallbackPlan": { - "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", - "allOf": [ - { - "$ref": "#/components/schemas/FallbackTranscriberPlan" - } - ] } }, "required": [ @@ -8573,284 +7792,43 @@ "model" ] }, - "FallbackAssemblyAITranscriber": { + "LangfuseObservabilityPlan": { "type": "object", "properties": { "provider": { "type": "string", - "description": "This is the transcription provider that will be used.", - "enum": [ - "assembly-ai" - ] - }, - "language": { - "type": "string", - "description": "This is the language that will be set for the transcription.", "enum": [ - "en" + "langfuse" ] }, - "confidenceThreshold": { - "type": "number", - "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", - "minimum": 0, - "maximum": 1, - "example": 0.4 - }, - "formatTurns": { - "type": "boolean", - "description": "This enables formatting of transcripts.\n\n@default true", - "example": true - }, - "endOfTurnConfidenceThreshold": { - "type": "number", - "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\n\n@min 0\n@max 1\n@default 0.7", - "minimum": 0, - "maximum": 1, - "example": 0.7 - }, - "minEndOfTurnSilenceWhenConfident": { - "type": "number", - "description": "This is the minimum end of turn silence when confident in milliseconds.\n\n@default 160", - "minimum": 0, - "example": 160 - }, - "wordFinalizationMaxWaitTime": { - "type": "number", - "description": "This is the maximum wait time for word finalization in milliseconds.\n\n@default 160", - "minimum": 0, - "example": 160 - }, - "maxTurnSilence": { - "type": "number", - "description": "This is the maximum turn silence time in milliseconds.\n\n@default 400", - "minimum": 0, - "example": 400 - }, - "realtimeUrl": { - "type": "string", - "description": "The WebSocket URL that the transcriber connects to." - }, - "wordBoost": { - "description": "Add up to 2500 characters of custom vocabulary.", + "tags": { + "description": "This is an array of tags to be added to the Langfuse trace. Tags allow you to categorize and filter traces. https://langfuse.com/docs/tracing-features/tags", "type": "array", "items": { - "type": "string", - "maxLength": 2500 + "type": "string" } }, - "endUtteranceSilenceThreshold": { - "type": "number", - "description": "The duration of the end utterance silence threshold in milliseconds." - }, - "disablePartialTranscripts": { - "type": "boolean", - "description": "Disable partial transcripts.\nSet to `true` to not receive partial transcripts. Defaults to `false`." - } - }, - "required": [ - "provider" - ] - }, - "FallbackAzureSpeechTranscriber": { - "type": "object", - "properties": { - "provider": { - "type": "string", - "description": "This is the transcription provider that will be used.", - "enum": [ - "azure" - ] - }, - "language": { - "type": "string", - "description": "This is the language that will be set for the transcription. The list of languages Azure supports can be found here: https://learn.microsoft.com/en-us/azure/ai-services/speech-service/language-support?tabs=stt", - "enum": [ - "af-ZA", - "am-ET", - "ar-AE", - "ar-BH", - "ar-DZ", - "ar-EG", - "ar-IL", - "ar-IQ", - "ar-JO", - "ar-KW", - "ar-LB", - "ar-LY", - "ar-MA", - "ar-OM", - "ar-PS", - "ar-QA", - "ar-SA", - "ar-SY", - "ar-TN", - "ar-YE", - "az-AZ", - "bg-BG", - "bn-IN", - "bs-BA", - "ca-ES", - "cs-CZ", - "cy-GB", - "da-DK", - "de-AT", - "de-CH", - "de-DE", - "el-GR", - "en-AU", - "en-CA", - "en-GB", - "en-GH", - "en-HK", - "en-IE", - "en-IN", - "en-KE", - "en-NG", - "en-NZ", - "en-PH", - "en-SG", - "en-TZ", - "en-US", - "en-ZA", - "es-AR", - "es-BO", - "es-CL", - "es-CO", - "es-CR", - "es-CU", - "es-DO", - "es-EC", - "es-ES", - "es-GQ", - "es-GT", - "es-HN", - "es-MX", - "es-NI", - "es-PA", - "es-PE", - "es-PR", - "es-PY", - "es-SV", - "es-US", - "es-UY", - "es-VE", - "et-EE", - "eu-ES", - "fa-IR", - "fi-FI", - "fil-PH", - "fr-BE", - "fr-CA", - "fr-CH", - "fr-FR", - "ga-IE", - "gl-ES", - "gu-IN", - "he-IL", - "hi-IN", - "hr-HR", - "hu-HU", - "hy-AM", - "id-ID", - "is-IS", - "it-CH", - "it-IT", - "ja-JP", - "jv-ID", - "ka-GE", - "kk-KZ", - "km-KH", - "kn-IN", - "ko-KR", - "lo-LA", - "lt-LT", - "lv-LV", - "mk-MK", - "ml-IN", - "mn-MN", - "mr-IN", - "ms-MY", - "mt-MT", - "my-MM", - "nb-NO", - "ne-NP", - "nl-BE", - "nl-NL", - "pa-IN", - "pl-PL", - "ps-AF", - "pt-BR", - "pt-PT", - "ro-RO", - "ru-RU", - "si-LK", - "sk-SK", - "sl-SI", - "so-SO", - "sq-AL", - "sr-RS", - "sv-SE", - "sw-KE", - "sw-TZ", - "ta-IN", - "te-IN", - "th-TH", - "tr-TR", - "uk-UA", - "ur-IN", - "uz-UZ", - "vi-VN", - "wuu-CN", - "yue-CN", - "zh-CN", - "zh-CN-shandong", - "zh-CN-sichuan", - "zh-HK", - "zh-TW", - "zu-ZA" - ] - }, - "segmentationStrategy": { - "type": "string", - "description": "Controls how phrase boundaries are detected, enabling either simple time/silence heuristics or more advanced semantic segmentation.", - "enum": [ - "Default", - "Time", - "Semantic" - ] - }, - "segmentationSilenceTimeoutMs": { - "type": "number", - "description": "Duration of detected silence after which the service finalizes a phrase. Configure to adjust sensitivity to pauses in speech.", - "minimum": 100, - "maximum": 5000 - }, - "segmentationMaximumTimeMs": { - "type": "number", - "description": "Maximum duration a segment can reach before being cut off when using time-based segmentation.", - "minimum": 20000, - "maximum": 70000 + "metadata": { + "type": "object", + "description": "This is a JSON object that will be added to the Langfuse trace. Traces can be enriched with metadata to better understand your users, application, and experiments. https://langfuse.com/docs/tracing-features/metadata\nBy default it includes the call metadata, assistant metadata, and assistant overrides." } }, "required": [ - "provider" + "provider", + "tags" ] }, - "FallbackCartesiaTranscriber": { + "TextContent": { "type": "object", "properties": { - "provider": { + "type": { "type": "string", "enum": [ - "cartesia" + "text" ] }, - "model": { - "type": "string", - "enum": [ - "ink-whisper" - ] + "text": { + "type": "string" }, "language": { "type": "string", @@ -9044,1420 +8022,772 @@ } }, "required": [ - "provider" + "type", + "text", + "language" ] }, - "FallbackCustomTranscriber": { + "Condition": { "type": "object", "properties": { - "provider": { + "operator": { "type": "string", - "description": "This is the transcription provider that will be used. Use `custom-transcriber` for providers that are not natively supported.", + "description": "This is the operator you want to use to compare the parameter and value.", "enum": [ - "custom-transcriber" + "eq", + "neq", + "gt", + "gte", + "lt", + "lte" ] }, - "server": { - "description": "This is where the transcription request will be sent.\n\nUsage:\n1. Vapi will initiate a websocket connection with `server.url`.\n\n2. Vapi will send an initial text frame with the sample rate. Format:\n```\n {\n \"type\": \"start\",\n \"encoding\": \"linear16\", // 16-bit raw PCM format\n \"container\": \"raw\",\n \"sampleRate\": {{sampleRate}},\n \"channels\": 2 // customer is channel 0, assistant is channel 1\n }\n```\n\n3. Vapi will send the audio data in 16-bit raw PCM format as binary frames.\n\n4. You can read the messages something like this:\n```\nws.on('message', (data, isBinary) => {\n if (isBinary) {\n pcmBuffer = Buffer.concat([pcmBuffer, data]);\n console.log(`Received PCM data, buffer size: ${pcmBuffer.length}`);\n } else {\n console.log('Received message:', JSON.parse(data.toString()));\n }\n});\n```\n\n5. You will respond with transcriptions as you have them. Format:\n```\n {\n \"type\": \"transcriber-response\",\n \"transcription\": \"Hello, world!\",\n \"channel\": \"customer\" | \"assistant\"\n }\n```", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "param": { + "type": "string", + "description": "This is the name of the parameter that you want to check.", + "maxLength": 1000 + }, + "value": { + "type": "string", + "description": "This is the value you want to compare against the parameter.", + "maxLength": 1000 } }, "required": [ - "provider", - "server" + "operator", + "param", + "value" ] }, - "FallbackDeepgramTranscriber": { + "ToolMessageStart": { "type": "object", "properties": { - "provider": { - "type": "string", - "description": "This is the transcription provider that will be used.", - "enum": [ - "deepgram" - ] - }, - "model": { - "description": "This is the Deepgram model that will be used. A list of models can be found here: https://developers.deepgram.com/docs/models-languages-overview", - "oneOf": [ - { - "type": "string", - "enum": [ - "nova-3", - "nova-3-general", - "nova-3-medical", - "nova-2", - "nova-2-general", - "nova-2-meeting", - "nova-2-phonecall", - "nova-2-finance", - "nova-2-conversationalai", - "nova-2-voicemail", - "nova-2-video", - "nova-2-medical", - "nova-2-drivethru", - "nova-2-automotive", - "nova", - "nova-general", - "nova-phonecall", - "nova-medical", - "enhanced", - "enhanced-general", - "enhanced-meeting", - "enhanced-phonecall", - "enhanced-finance", - "base", - "base-general", - "base-meeting", - "base-phonecall", - "base-finance", - "base-conversationalai", - "base-voicemail", - "base-video", - "whisper" - ] - }, - { - "type": "string" - } - ] + "contents": { + "type": "array", + "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/TextContent", + "title": "Text" + } + ] + } }, - "language": { + "type": { "type": "string", - "description": "This is the language that will be set for the transcription. The list of languages Deepgram supports can be found here: https://developers.deepgram.com/docs/models-languages-overview", "enum": [ - "ar", - "az", - "ba", - "bg", - "br", - "ca", - "cs", - "da", - "da-DK", - "de", - "de-CH", - "el", - "en", - "en-AU", - "en-CA", - "en-GB", - "en-IE", - "en-IN", - "en-NZ", - "en-US", - "es", - "es-419", - "es-LATAM", - "et", - "eu", - "fi", - "fr", - "fr-CA", - "ha", - "haw", - "he", - "hi", - "hi-Latn", - "hu", - "id", - "is", - "it", - "ja", - "jw", - "kn", - "ko", - "ko-KR", - "ln", - "lt", - "lv", - "mk", - "ms", - "multi", - "nl", - "nl-BE", - "no", - "pl", - "pt", - "pt-BR", - "ro", - "ru", - "sk", - "sl", - "sn", - "so", - "sr", - "su", - "sv", - "sv-SE", - "ta", - "taq", - "th", - "th-TH", - "tr", - "tt", - "uk", - "ur", - "vi", - "yo", - "zh", - "zh-CN", - "zh-HK", - "zh-Hans", - "zh-Hant", - "zh-TW" - ] - }, - "smartFormat": { - "type": "boolean", - "description": "This will be use smart format option provided by Deepgram. It's default disabled because it can sometimes format numbers as times but it's getting better.", - "example": false + "request-start" + ], + "description": "This message is triggered when the tool call starts.\n\nThis message is never triggered for async tools.\n\nIf this message is not provided, one of the default filler messages \"Hold on a sec\", \"One moment\", \"Just a sec\", \"Give me a moment\" or \"This'll just take a sec\" will be used." }, - "mipOptOut": { + "blocking": { "type": "boolean", - "description": "If set to true, this will add mip_opt_out=true as a query parameter of all API requests. See https://developers.deepgram.com/docs/the-deepgram-model-improvement-partnership-program#want-to-opt-out\n\nThis will only be used if you are using your own Deepgram API key.\n\n@default false", + "description": "This is an optional boolean that if true, the tool call will only trigger after the message is spoken. Default is false.\n\n@default false", "example": false, "default": false }, - "numerals": { - "type": "boolean", - "description": "If set to true, this will cause deepgram to convert spoken numbers to literal numerals. For example, \"my phone number is nine-seven-two...\" would become \"my phone number is 972...\"\n\n@default false", - "example": false - }, - "confidenceThreshold": { - "type": "number", - "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", - "minimum": 0, - "maximum": 1, - "example": 0.4 - }, - "keywords": { - "description": "These keywords are passed to the transcription model to help it pick up use-case specific words. Anything that may not be a common word, like your company name, should be added here.", - "type": "array", - "items": { - "type": "string", - "pattern": "/^\\p{L}[\\p{L}\\d]*(?::[+-]?\\d+)?$/u" - } + "content": { + "type": "string", + "description": "This is the content that the assistant says when this message is triggered.", + "maxLength": 1000 }, - "keyterm": { - "description": "Keyterm Prompting allows you improve Keyword Recall Rate (KRR) for important keyterms or phrases up to 90%.", + "conditions": { + "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/Condition" } - }, - "endpointing": { - "type": "number", - "description": "This is the timeout after which Deepgram will send transcription on user silence. You can read in-depth documentation here: https://developers.deepgram.com/docs/endpointing.\n\nHere are the most important bits:\n- Defaults to 10. This is recommended for most use cases to optimize for latency.\n- 10 can cause some missing transcriptions since because of the shorter context. This mostly happens for one-word utterances. For those uses cases, it's recommended to try 300. It will add a bit of latency but the quality and reliability of the experience will be better.\n- If neither 10 nor 300 work, contact support@vapi.ai and we'll find another solution.\n\n@default 10", - "minimum": 10, - "maximum": 500 } }, "required": [ - "provider" + "type" ] }, - "FallbackElevenLabsTranscriber": { + "ToolMessageComplete": { "type": "object", "properties": { - "provider": { + "contents": { + "type": "array", + "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/TextContent", + "title": "Text" + } + ] + } + }, + "type": { "type": "string", - "description": "This is the transcription provider that will be used.", + "description": "This message is triggered when the tool call is complete.\n\nThis message is triggered immediately without waiting for your server to respond for async tool calls.\n\nIf this message is not provided, the model will be requested to respond.\n\nIf this message is provided, only this message will be spoken and the model will not be requested to come up with a response. It's an exclusive OR.", "enum": [ - "11labs" + "request-complete" ] }, - "model": { + "role": { "type": "string", - "description": "This is the model that will be used for the transcription.", + "description": "This is optional and defaults to \"assistant\".\n\nWhen role=assistant, `content` is said out loud.\n\nWhen role=system, `content` is passed to the model in a system message. Example:\n system: default one\n assistant:\n user:\n assistant:\n user:\n assistant:\n user:\n assistant: tool called\n tool: your server response\n <--- system prompt as hint\n ---> model generates response which is spoken\nThis is useful when you want to provide a hint to the model about what to say next.", "enum": [ - "scribe_v1" + "assistant", + "system" ] }, - "language": { + "endCallAfterSpokenEnabled": { + "type": "boolean", + "description": "This is an optional boolean that if true, the call will end after the message is spoken. Default is false.\n\nThis is ignored if `role` is set to `system`.\n\n@default false", + "example": false + }, + "content": { "type": "string", - "enum": [ - "aa", - "ab", - "ae", - "af", - "ak", - "am", - "an", - "ar", - "as", - "av", - "ay", - "az", - "ba", - "be", - "bg", - "bh", - "bi", - "bm", - "bn", - "bo", - "br", - "bs", - "ca", - "ce", - "ch", - "co", - "cr", - "cs", - "cu", - "cv", - "cy", - "da", - "de", - "dv", - "dz", - "ee", - "el", - "en", - "eo", - "es", - "et", - "eu", - "fa", - "ff", - "fi", - "fj", - "fo", - "fr", - "fy", - "ga", - "gd", - "gl", - "gn", - "gu", - "gv", - "ha", - "he", - "hi", - "ho", - "hr", - "ht", - "hu", - "hy", - "hz", - "ia", - "id", - "ie", - "ig", - "ii", - "ik", - "io", - "is", - "it", - "iu", - "ja", - "jv", - "ka", - "kg", - "ki", - "kj", - "kk", - "kl", - "km", - "kn", - "ko", - "kr", - "ks", - "ku", - "kv", - "kw", - "ky", - "la", - "lb", - "lg", - "li", - "ln", - "lo", - "lt", - "lu", - "lv", - "mg", - "mh", - "mi", - "mk", - "ml", - "mn", - "mr", - "ms", - "mt", - "my", - "na", - "nb", - "nd", - "ne", - "ng", - "nl", - "nn", - "no", - "nr", - "nv", - "ny", - "oc", - "oj", - "om", - "or", - "os", - "pa", - "pi", - "pl", - "ps", - "pt", - "qu", - "rm", - "rn", - "ro", - "ru", - "rw", - "sa", - "sc", - "sd", - "se", - "sg", - "si", - "sk", - "sl", - "sm", - "sn", - "so", - "sq", - "sr", - "ss", - "st", - "su", - "sv", - "sw", - "ta", - "te", - "tg", - "th", - "ti", - "tk", - "tl", - "tn", - "to", - "tr", - "ts", - "tt", - "tw", - "ty", - "ug", - "uk", - "ur", - "uz", - "ve", - "vi", - "vo", - "wa", - "wo", - "xh", - "yi", - "yue", - "yo", - "za", - "zh", - "zu" - ] + "description": "This is the content that the assistant says when this message is triggered.", + "maxLength": 1000 + }, + "conditions": { + "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Condition" + } } }, "required": [ - "provider" + "type" ] }, - "GladiaVocabularyItemDTO": { + "ToolMessageFailed": { "type": "object", "properties": { - "value": { - "type": "string", - "description": "The vocabulary word or phrase" - }, - "pronunciations": { - "description": "Alternative pronunciations for the vocabulary item", + "contents": { "type": "array", + "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", "items": { - "type": "string" + "oneOf": [ + { + "$ref": "#/components/schemas/TextContent", + "title": "Text" + } + ] } }, - "intensity": { - "type": "number", - "minimum": 0, - "maximum": 1, - "description": "Intensity for this specific vocabulary item (0.0 to 1.0)" + "type": { + "type": "string", + "description": "This message is triggered when the tool call fails.\n\nThis message is never triggered for async tool calls.\n\nIf this message is not provided, the model will be requested to respond.\n\nIf this message is provided, only this message will be spoken and the model will not be requested to come up with a response. It's an exclusive OR.", + "enum": [ + "request-failed" + ] }, - "language": { + "endCallAfterSpokenEnabled": { + "type": "boolean", + "description": "This is an optional boolean that if true, the call will end after the message is spoken. Default is false.\n\n@default false", + "example": false + }, + "content": { "type": "string", - "description": "Language code for this vocabulary item (ISO 639-1)" + "description": "This is the content that the assistant says when this message is triggered.", + "maxLength": 1000 + }, + "conditions": { + "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Condition" + } } }, "required": [ - "value" + "type" ] }, - "FallbackGladiaTranscriber": { + "ToolMessageDelayed": { "type": "object", "properties": { - "provider": { + "contents": { + "type": "array", + "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/TextContent", + "title": "Text" + } + ] + } + }, + "type": { "type": "string", - "description": "This is the transcription provider that will be used.", + "description": "This message is triggered when the tool call is delayed.\n\nThere are the two things that can trigger this message:\n1. The user talks with the assistant while your server is processing the request. Default is \"Sorry, a few more seconds.\"\n2. The server doesn't respond within `timingMilliseconds`.\n\nThis message is never triggered for async tool calls.", "enum": [ - "gladia" + "request-response-delayed" ] }, - "model": { - "description": "This is the Gladia model that will be used. Default is 'fast'", - "oneOf": [ - { - "enum": [ - "fast", - "accurate", - "solaria-1" - ] - } - ] + "timingMilliseconds": { + "type": "number", + "minimum": 100, + "maximum": 120000, + "example": 1000, + "description": "The number of milliseconds to wait for the server response before saying this message." }, - "languageBehaviour": { - "description": "Defines how the transcription model detects the audio language. Default value is 'automatic single language'.", - "oneOf": [ - { - "type": "string", - "enum": [ - "manual", - "automatic single language", - "automatic multiple languages" - ] - } - ] + "content": { + "type": "string", + "description": "This is the content that the assistant says when this message is triggered.", + "maxLength": 1000 }, - "language": { + "conditions": { + "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Condition" + } + } + }, + "required": [ + "type" + ] + }, + "MessageTarget": { + "type": "object", + "properties": { + "role": { "type": "string", - "description": "Defines the language to use for the transcription. Required when languageBehaviour is 'manual'.", + "description": "This is the role of the message to target.\n\nIf not specified, will find the position in the message history ignoring role (effectively `any`).", + "example": "user", "enum": [ - "af", - "sq", - "am", - "ar", - "hy", - "as", - "az", - "ba", - "eu", - "be", - "bn", - "bs", - "br", - "bg", - "ca", - "zh", - "hr", - "cs", - "da", - "nl", - "en", - "et", - "fo", - "fi", - "fr", - "gl", - "ka", - "de", - "el", - "gu", - "ht", - "ha", - "haw", - "he", - "hi", - "hu", - "is", - "id", - "it", - "ja", - "jv", - "kn", - "kk", - "km", - "ko", - "lo", - "la", - "lv", - "ln", - "lt", - "lb", - "mk", - "mg", - "ms", - "ml", - "mt", - "mi", - "mr", - "mn", - "my", - "ne", - "no", - "nn", - "oc", - "ps", - "fa", - "pl", - "pt", - "pa", - "ro", - "ru", - "sa", - "sr", - "sn", - "sd", - "si", - "sk", - "sl", - "so", - "es", - "su", - "sw", - "sv", - "tl", - "tg", - "ta", - "tt", - "te", - "th", - "bo", - "tr", - "tk", - "uk", - "ur", - "uz", - "vi", - "cy", - "yi", - "yo" + "user", + "assistant" ] }, - "languages": { + "position": { + "type": "number", + "description": "This is the position of the message to target.\n- Negative numbers: Count from end (-1 = most recent, -2 = second most recent)\n- 0: First/oldest message in history\n- Positive numbers: Specific position (0-indexed from start)\n\n@default -1 (most recent message)", + "example": -1 + } + } + }, + "RegexCondition": { + "type": "object", + "properties": { + "type": { "type": "string", - "description": "Defines the languages to use for the transcription. Required when languageBehaviour is 'manual'.", + "description": "This is the type discriminator for regex condition", + "example": "regex", "enum": [ - "af", - "sq", - "am", - "ar", - "hy", - "as", - "az", - "ba", - "eu", - "be", - "bn", - "bs", - "br", - "bg", - "ca", - "zh", - "hr", - "cs", - "da", - "nl", - "en", - "et", - "fo", - "fi", - "fr", - "gl", - "ka", - "de", - "el", - "gu", - "ht", - "ha", - "haw", - "he", - "hi", - "hu", - "is", - "id", - "it", - "ja", - "jv", - "kn", - "kk", - "km", - "ko", - "lo", - "la", - "lv", - "ln", - "lt", - "lb", - "mk", - "mg", - "ms", - "ml", - "mt", - "mi", - "mr", - "mn", - "my", - "ne", - "no", - "nn", - "oc", - "ps", - "fa", - "pl", - "pt", - "pa", - "ro", - "ru", - "sa", - "sr", - "sn", - "sd", - "si", - "sk", - "sl", - "so", - "es", - "su", - "sw", - "sv", - "tl", - "tg", - "ta", - "tt", - "te", - "th", - "bo", - "tr", - "tk", - "uk", - "ur", - "uz", - "vi", - "cy", - "yi", - "yo" + "regex" ] }, - "transcriptionHint": { + "regex": { "type": "string", - "description": "Provides a custom vocabulary to the model to improve accuracy of transcribing context specific words, technical terms, names, etc. If empty, this argument is ignored.\n⚠️ Warning ⚠️: Please be aware that the transcription_hint field has a character limit of 600. If you provide a transcription_hint longer than 600 characters, it will be automatically truncated to meet this limit.", - "maxLength": 600, - "example": "custom vocabulary" - }, - "prosody": { - "type": "boolean", - "description": "If prosody is true, you will get a transcription that can contain prosodies i.e. (laugh) (giggles) (malefic laugh) (toss) (music)… Default value is false.", - "example": false - }, - "audioEnhancer": { - "type": "boolean", - "description": "If true, audio will be pre-processed to improve accuracy but latency will increase. Default value is false.", - "example": false - }, - "confidenceThreshold": { - "type": "number", - "description": "Transcripts below this confidence threshold will be discarded.\n\n@default 0.4", - "minimum": 0, - "maximum": 1, - "example": 0.4 - }, - "endpointing": { - "type": "number", - "minimum": 0.01, - "maximum": 10, - "example": 0.05, - "description": "Endpointing time in seconds - time to wait before considering speech ended" - }, - "speechThreshold": { - "type": "number", - "minimum": 0, - "maximum": 1, - "example": 0.6, - "description": "Speech threshold - sensitivity configuration for speech detection (0.0 to 1.0)" - }, - "customVocabularyEnabled": { - "type": "boolean", - "example": false, - "description": "Enable custom vocabulary for improved accuracy" + "description": "This is the regular expression pattern to match against message content.\n\nNote:\n- This works by using the RegExp.test method in Node.JS. Eg. /hello/.test(\"hello there\") will return true.\n\nHot tips:\n- In JavaScript, escape \\ when sending the regex pattern. Eg. \"hello\\sthere\" will be sent over the wire as \"hellosthere\". Send \"hello\\\\sthere\" instead.\n- RegExp.test does substring matching, so /cat/.test(\"I love cats\") will return true. To do full string matching, use anchors: /^cat$/ will only match exactly \"cat\".\n- Word boundaries \\b are useful for matching whole words: /\\bcat\\b/ matches \"cat\" but not \"cats\" or \"category\".\n- Use inline flags for portability: (?i) for case insensitive, (?m) for multiline", + "examples": [ + "\\\\b(cancel|stop|wait)\\\\b - Matches whole words", + "^yes$ - Matches exactly yes (full string match)", + "(?i)hello - Case insensitive match" + ] }, - "customVocabularyConfig": { - "description": "Custom vocabulary configuration", + "target": { + "description": "This is the target for messages to check against.\nIf not specified, the condition will run on the last message (position: -1).\nIf role is not specified, it will look at the last message regardless of role.\n@default { position: -1 }", "allOf": [ { - "$ref": "#/components/schemas/GladiaCustomVocabularyConfigDTO" + "$ref": "#/components/schemas/MessageTarget" } ] + }, + "negate": { + "type": "boolean", + "description": "This is the flag that when true, the condition matches if the pattern does NOT match.\nUseful for ensuring certain words/phrases are absent.\n\n@default false", + "example": "true - Reject if user hasn\"t said goodbye: { regex: \"\\\\b(bye|goodbye)\\\\b\", negate: true }" } }, "required": [ - "provider" + "type", + "regex" ] }, - "FallbackSpeechmaticsTranscriber": { + "LiquidCondition": { "type": "object", "properties": { - "provider": { - "type": "string", - "description": "This is the transcription provider that will be used.", - "enum": [ - "speechmatics" - ] - }, - "model": { + "type": { "type": "string", - "description": "This is the model that will be used for the transcription.", + "description": "This is the type discriminator for liquid condition", + "example": "liquid", "enum": [ - "default" + "liquid" ] }, - "language": { + "liquid": { "type": "string", - "enum": [ - "auto", - "ar", - "ba", - "eu", - "be", - "bn", - "bg", - "yue", - "ca", - "hr", - "cs", - "da", - "nl", - "en", - "eo", - "et", - "fi", - "fr", - "gl", - "de", - "el", - "he", - "hi", - "hu", - "id", - "ia", - "ga", - "it", - "ja", - "ko", - "lv", - "lt", - "ms", - "mt", - "cmn", - "mr", - "mn", - "no", - "fa", - "pl", - "pt", - "ro", - "ru", - "sk", - "sl", - "es", - "sw", - "sv", - "ta", - "th", - "tr", - "uk", - "ur", - "ug", - "vi", - "cy" + "description": "This is the Liquid template that must return exactly \"true\" or \"false\" as a string.\nThe template is evaluated and the entire output must be either \"true\" or \"false\" - nothing else.\n\nAvailable variables:\n- `messages`: Array of recent messages in OpenAI chat completions format (ChatCompletionMessageParam[])\n Each message has properties like: role ('user', 'assistant', 'system'), content (string), etc.\n- `now`: Current timestamp in milliseconds (built-in Liquid variable)\n- Any assistant variable values (e.g., `userName`, `accountStatus`)\n\nUseful Liquid filters for messages:\n- `messages | last: 5` - Get the 5 most recent messages\n- `messages | where: 'role', 'user'` - Filter to only user messages\n- `messages | reverse` - Reverse the order of messages", + "examples": [ + "{% if messages.last.content contains goodbye %}true{% else %}false{% endif %}", + "{% assign userMessages = messages | where: role, user %}{% if userMessages.size > 3 %}true{% else %}false{% endif %}" ] } }, "required": [ - "provider" + "type", + "liquid" ] }, - "FallbackTalkscriberTranscriber": { + "GroupCondition": { "type": "object", "properties": { - "provider": { + "type": { "type": "string", - "description": "This is the transcription provider that will be used.", + "description": "This is the type discriminator for group condition", + "example": "group", "enum": [ - "talkscriber" + "group" ] }, - "model": { + "operator": { "type": "string", - "description": "This is the model that will be used for the transcription.", + "description": "This is the logical operator for combining conditions in this group", + "examples": [ + "AND", + "OR" + ], "enum": [ - "whisper" + "AND", + "OR" ] }, - "language": { - "type": "string", - "description": "This is the language that will be set for the transcription. The list of languages Whisper supports can be found here: https://github.com/openai/whisper/blob/main/whisper/tokenizer.py", - "enum": [ - "en", - "zh", - "de", - "es", - "ru", - "ko", - "fr", - "ja", - "pt", - "tr", - "pl", - "ca", - "nl", - "ar", - "sv", - "it", - "id", - "hi", - "fi", - "vi", - "he", - "uk", - "el", - "ms", - "cs", - "ro", - "da", - "hu", - "ta", - "no", - "th", - "ur", - "hr", - "bg", - "lt", - "la", - "mi", - "ml", - "cy", - "sk", - "te", - "fa", - "lv", - "bn", - "sr", - "az", - "sl", - "kn", - "et", - "mk", - "br", - "eu", - "is", - "hy", - "ne", - "mn", - "bs", - "kk", - "sq", - "sw", - "gl", - "mr", - "pa", - "si", - "km", - "sn", - "yo", - "so", - "af", - "oc", - "ka", - "be", - "tg", - "sd", - "gu", - "am", - "yi", - "lo", - "uz", - "fo", - "ht", - "ps", - "tk", - "nn", - "mt", - "sa", - "lb", - "my", - "bo", - "tl", - "mg", - "as", - "tt", - "haw", - "ln", - "ha", - "ba", - "jw", - "su", - "yue" - ] + "conditions": { + "type": "array", + "description": "This is the list of nested conditions to evaluate.\nSupports recursive nesting of groups for complex logic.", + "examples": [ + "[{ type: \"regex\", regex: \"(?i)stop\", target: { role: \"user\" } }]", + "[{ type: \"group\", operator: \"AND\", conditions: [...] }]" + ], + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/RegexCondition", + "title": "RegexCondition" + }, + { + "$ref": "#/components/schemas/LiquidCondition", + "title": "LiquidCondition" + }, + { + "$ref": "#/components/schemas/GroupCondition", + "title": "GroupCondition", + "description": "This is the GroupCondition object but Swagger does not display nested schemas correctly." + } + ] + } } }, "required": [ - "provider" + "type", + "operator", + "conditions" ] }, - "FallbackGoogleTranscriber": { + "ToolRejectionPlan": { "type": "object", "properties": { - "provider": { + "conditions": { + "type": "array", + "description": "This is the list of conditions that must be evaluated.\n\nUsage:\n- If all conditions match (AND logic), the tool call is rejected.\n- For OR logic at the top level, use a single 'group' condition with operator: 'OR'.\n\n@default [] - Empty array means tool always executes", + "examples": [ + "[{ type: \"regex\", regex: \"(?i)\\\\b(cancel|stop)\\\\b\", target: { role: \"user\" } }]", + "[{ type: \"group\", operator: \"OR\", conditions: [...] }]" + ], + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/RegexCondition", + "title": "RegexCondition" + }, + { + "$ref": "#/components/schemas/LiquidCondition", + "title": "LiquidCondition" + }, + { + "$ref": "#/components/schemas/GroupCondition", + "title": "GroupCondition", + "description": "This is the GroupCondition object but Swagger does not display nested schemas correctly." + } + ] + } + } + } + }, + "CreateDtmfToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "type": { "type": "string", - "description": "This is the transcription provider that will be used.", "enum": [ - "google" + "dtmf" + ], + "description": "The type of tool. \"dtmf\" for DTMF tool." + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } ] + } + }, + "required": [ + "type" + ] + }, + "CreateEndCallToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } }, - "model": { + "type": { "type": "string", - "description": "This is the model that will be used for the transcription.", "enum": [ - "gemini-2.5-pro", - "gemini-2.5-flash", - "gemini-2.5-flash-lite", - "gemini-2.0-flash-thinking-exp", - "gemini-2.0-pro-exp-02-05", - "gemini-2.0-flash", - "gemini-2.0-flash-lite", - "gemini-2.0-flash-exp", - "gemini-2.0-flash-realtime-exp", - "gemini-1.5-flash", - "gemini-1.5-flash-002", - "gemini-1.5-pro", - "gemini-1.5-pro-002", - "gemini-1.0-pro" + "endCall" + ], + "description": "The type of tool. \"endCall\" for End Call tool." + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } ] + } + }, + "required": [ + "type" + ] + }, + "CreateVoicemailToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } }, - "language": { + "type": { "type": "string", - "description": "This is the language that will be set for the transcription.", + "description": "The type of tool. \"voicemail\" for Voicemail tool.", "enum": [ - "Multilingual", - "Arabic", - "Bengali", - "Bulgarian", - "Chinese", - "Croatian", - "Czech", - "Danish", - "Dutch", - "English", - "Estonian", - "Finnish", - "French", - "German", - "Greek", - "Hebrew", - "Hindi", - "Hungarian", - "Indonesian", - "Italian", - "Japanese", - "Korean", - "Latvian", - "Lithuanian", - "Norwegian", - "Polish", - "Portuguese", - "Romanian", - "Russian", - "Serbian", - "Slovak", - "Slovenian", - "Spanish", - "Swahili", - "Swedish", - "Thai", - "Turkish", - "Ukrainian", - "Vietnamese" + "voicemail" + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } ] } }, "required": [ - "provider" + "type" ] }, - "FallbackOpenAITranscriber": { + "JsonSchema": { "type": "object", "properties": { - "provider": { + "type": { "type": "string", - "description": "This is the transcription provider that will be used.", + "description": "This is the type of output you'd like.\n\n`string`, `number`, `integer`, `boolean` are the primitive types and should be obvious.\n\n`array` and `object` are more interesting and quite powerful. They allow you to define nested structures.\n\nFor `array`, you can define the schema of the items in the array using the `items` property.\n\nFor `object`, you can define the properties of the object using the `properties` property.", "enum": [ - "openai" + "string", + "number", + "integer", + "boolean", + "array", + "object" ] }, - "model": { + "items": { + "type": "object", + "description": "This is required if the type is \"array\". This is the schema of the items in the array.\n\nThis is of type JsonSchema. However, Swagger doesn't support circular references." + }, + "properties": { + "type": "object", + "description": "This is required if the type is \"object\". This specifies the properties of the object.\n\nThis is a map of string to JsonSchema. However, Swagger doesn't support circular references." + }, + "description": { "type": "string", - "description": "This is the model that will be used for the transcription.", - "enum": [ - "gpt-4o-transcribe", - "gpt-4o-mini-transcribe" - ] + "description": "This is the description to help the model understand what it needs to output." }, - "language": { + "pattern": { "type": "string", - "description": "This is the language that will be set for the transcription.", + "description": "This is the pattern of the string. This is a regex that will be used to validate the data in question. To use a common format, use the `format` property instead.\n\nOpenAI documentation: https://platform.openai.com/docs/guides/structured-outputs#supported-properties" + }, + "format": { + "type": "string", + "description": "This is the format of the string. To pass a regex, use the `pattern` property instead.\n\nOpenAI documentation: https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat&type-restrictions=string-restrictions", "enum": [ - "af", - "ar", - "hy", - "az", - "be", - "bs", - "bg", - "ca", - "zh", - "hr", - "cs", - "da", - "nl", - "en", - "et", - "fi", - "fr", - "gl", - "de", - "el", - "he", - "hi", - "hu", - "is", - "id", - "it", - "ja", - "kn", - "kk", - "ko", - "lv", - "lt", - "mk", - "ms", - "mr", - "mi", - "ne", - "no", - "fa", - "pl", - "pt", - "ro", - "ru", - "sr", - "sk", - "sl", - "es", - "sw", - "sv", - "tl", - "ta", - "th", - "tr", - "uk", - "ur", - "vi", - "cy" + "date-time", + "time", + "date", + "duration", + "email", + "hostname", + "ipv4", + "ipv6", + "uuid" ] + }, + "required": { + "description": "This is a list of properties that are required.\n\nThis only makes sense if the type is \"object\".", + "type": "array", + "items": { + "type": "string" + } + }, + "enum": { + "description": "This array specifies the allowed values that can be used to restrict the output of the model.", + "type": "array", + "items": { + "type": "string" + } + }, + "title": { + "type": "string", + "description": "This is the title of the schema." } }, "required": [ - "provider", - "model" + "type" ] }, - "LangfuseObservabilityPlan": { + "OpenAIFunctionParameters": { "type": "object", "properties": { - "provider": { + "type": { "type": "string", + "description": "This must be set to 'object'. It instructs the model to return a JSON object containing the function call properties.", "enum": [ - "langfuse" + "object" ] }, - "tags": { - "description": "This is an array of tags to be added to the Langfuse trace. Tags allow you to categorize and filter traces. https://langfuse.com/docs/tracing-features/tags", + "properties": { + "type": "object", + "description": "This provides a description of the properties required by the function.\nJSON Schema can be used to specify expectations for each property.\nRefer to [this doc](https://ajv.js.org/json-schema.html#json-data-type) for a comprehensive guide on JSON Schema.", + "additionalProperties": { + "$ref": "#/components/schemas/JsonSchema" + } + }, + "required": { + "description": "This specifies the properties that are required by the function.", "type": "array", "items": { "type": "string" } + } + }, + "required": [ + "type", + "properties" + ] + }, + "OpenAIFunction": { + "type": "object", + "properties": { + "strict": { + "type": "boolean", + "description": "This is a boolean that controls whether to enable strict schema adherence when generating the function call. If set to true, the model will follow the exact schema defined in the parameters field. Only a subset of JSON Schema is supported when strict is true. Learn more about Structured Outputs in the [OpenAI guide](https://openai.com/index/introducing-structured-outputs-in-the-api/).\n\n@default false", + "default": false }, - "metadata": { - "type": "object", - "description": "This is a JSON object that will be added to the Langfuse trace. Traces can be enriched with metadata to better understand your users, application, and experiments. https://langfuse.com/docs/tracing-features/metadata\nBy default it includes the call metadata, assistant metadata, and assistant overrides." + "name": { + "type": "string", + "description": "This is the the name of the function to be called.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.", + "maxLength": 64, + "pattern": "/^[a-zA-Z0-9_-]{1,64}$/" + }, + "description": { + "type": "string", + "description": "This is the description of what the function does, used by the AI to choose when and how to call the function.", + "maxLength": 1000 + }, + "parameters": { + "description": "These are the parameters the functions accepts, described as a JSON Schema object.\n\nSee the [OpenAI guide](https://platform.openai.com/docs/guides/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format.\n\nOmitting parameters defines a function with an empty parameter list.", + "allOf": [ + { + "$ref": "#/components/schemas/OpenAIFunctionParameters" + } + ] } }, "required": [ - "provider", - "tags" + "name" ] }, - "TextContent": { + "CreateFunctionToolDTO": { "type": "object", "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, "type": { "type": "string", "enum": [ - "text" - ] + "function" + ], + "description": "The type of tool. \"function\" for Function tool." }, - "text": { - "type": "string" + "async": { + "type": "boolean", + "example": false, + "description": "This determines if the tool is async.\n\n If async, the assistant will move forward without waiting for your server to respond. This is useful if you just want to trigger something on your server.\n\n If sync, the assistant will wait for your server to respond. This is useful if want assistant to respond with the result from your server.\n\n Defaults to synchronous (`false`)." }, - "language": { - "type": "string", - "enum": [ - "aa", - "ab", - "ae", - "af", - "ak", - "am", - "an", - "ar", - "as", - "av", - "ay", - "az", - "ba", - "be", - "bg", - "bh", - "bi", - "bm", - "bn", - "bo", - "br", - "bs", - "ca", - "ce", - "ch", - "co", - "cr", - "cs", - "cu", - "cv", - "cy", - "da", - "de", - "dv", - "dz", - "ee", - "el", - "en", - "eo", - "es", - "et", - "eu", - "fa", - "ff", - "fi", - "fj", - "fo", - "fr", - "fy", - "ga", - "gd", - "gl", - "gn", - "gu", - "gv", - "ha", - "he", - "hi", - "ho", - "hr", - "ht", - "hu", - "hy", - "hz", - "ia", - "id", - "ie", - "ig", - "ii", - "ik", - "io", - "is", - "it", - "iu", - "ja", - "jv", - "ka", - "kg", - "ki", - "kj", - "kk", - "kl", - "km", - "kn", - "ko", - "kr", - "ks", - "ku", - "kv", - "kw", - "ky", - "la", - "lb", - "lg", - "li", - "ln", - "lo", - "lt", - "lu", - "lv", - "mg", - "mh", - "mi", - "mk", - "ml", - "mn", - "mr", - "ms", - "mt", - "my", - "na", - "nb", - "nd", - "ne", - "ng", - "nl", - "nn", - "no", - "nr", - "nv", - "ny", - "oc", - "oj", - "om", - "or", - "os", - "pa", - "pi", - "pl", - "ps", - "pt", - "qu", - "rm", - "rn", - "ro", - "ru", - "rw", - "sa", - "sc", - "sd", - "se", - "sg", - "si", - "sk", - "sl", - "sm", - "sn", - "so", - "sq", - "sr", - "ss", - "st", - "su", - "sv", - "sw", - "ta", - "te", - "tg", - "th", - "ti", - "tk", - "tl", - "tn", - "to", - "tr", - "ts", - "tt", - "tw", - "ty", - "ug", - "uk", - "ur", - "uz", - "ve", - "vi", - "vo", - "wa", - "wo", - "xh", - "yi", - "yue", - "yo", - "za", - "zh", - "zu" + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "allOf": [ + { + "$ref": "#/components/schemas/Server" + } + ] + }, + "function": { + "description": "This is the function definition of the tool.", + "allOf": [ + { + "$ref": "#/components/schemas/OpenAIFunction" + } + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } ] } }, "required": [ - "type", - "text", - "language" + "type" ] }, - "Condition": { + "GhlToolMetadata": { "type": "object", "properties": { - "operator": { - "type": "string", - "description": "This is the operator you want to use to compare the parameter and value.", - "enum": [ - "eq", - "neq", - "gt", - "gte", - "lt", - "lte" - ] - }, - "param": { - "type": "string", - "description": "This is the name of the parameter that you want to check.", - "maxLength": 1000 + "workflowId": { + "type": "string" }, - "value": { - "type": "string", - "description": "This is the value you want to compare against the parameter.", - "maxLength": 1000 + "locationId": { + "type": "string" } - }, - "required": [ - "operator", - "param", - "value" - ] + } }, - "ToolMessageStart": { + "CreateGhlToolDTO": { "type": "object", "properties": { - "contents": { + "messages": { "type": "array", - "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/TextContent", - "title": "Text" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } ] } @@ -10465,130 +8795,90 @@ "type": { "type": "string", "enum": [ - "request-start" + "ghl" ], - "description": "This message is triggered when the tool call starts.\n\nThis message is never triggered for async tools.\n\nIf this message is not provided, one of the default filler messages \"Hold on a sec\", \"One moment\", \"Just a sec\", \"Give me a moment\" or \"This'll just take a sec\" will be used." - }, - "blocking": { - "type": "boolean", - "description": "This is an optional boolean that if true, the tool call will only trigger after the message is spoken. Default is false.\n\n@default false", - "example": false, - "default": false + "description": "The type of tool. \"ghl\" for GHL tool." }, - "content": { - "type": "string", - "description": "This is the content that the assistant says when this message is triggered.", - "maxLength": 1000 + "metadata": { + "$ref": "#/components/schemas/GhlToolMetadata" }, - "conditions": { - "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Condition" - } + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] } }, "required": [ - "type" + "type", + "metadata" ] }, - "ToolMessageComplete": { + "MakeToolMetadata": { "type": "object", "properties": { - "contents": { - "type": "array", - "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TextContent", - "title": "Text" - } - ] - } - }, - "type": { - "type": "string", - "description": "This message is triggered when the tool call is complete.\n\nThis message is triggered immediately without waiting for your server to respond for async tool calls.\n\nIf this message is not provided, the model will be requested to respond.\n\nIf this message is provided, only this message will be spoken and the model will not be requested to come up with a response. It's an exclusive OR.", - "enum": [ - "request-complete" - ] - }, - "role": { - "type": "string", - "description": "This is optional and defaults to \"assistant\".\n\nWhen role=assistant, `content` is said out loud.\n\nWhen role=system, `content` is passed to the model in a system message. Example:\n system: default one\n assistant:\n user:\n assistant:\n user:\n assistant:\n user:\n assistant: tool called\n tool: your server response\n <--- system prompt as hint\n ---> model generates response which is spoken\nThis is useful when you want to provide a hint to the model about what to say next.", - "enum": [ - "assistant", - "system" - ] - }, - "endCallAfterSpokenEnabled": { - "type": "boolean", - "description": "This is an optional boolean that if true, the call will end after the message is spoken. Default is false.\n\nThis is ignored if `role` is set to `system`.\n\n@default false", - "example": false - }, - "content": { - "type": "string", - "description": "This is the content that the assistant says when this message is triggered.", - "maxLength": 1000 + "scenarioId": { + "type": "number" }, - "conditions": { - "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Condition" - } + "triggerHookId": { + "type": "number" } - }, - "required": [ - "type" - ] + } }, - "ToolMessageFailed": { + "CreateMakeToolDTO": { "type": "object", "properties": { - "contents": { + "messages": { "type": "array", - "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/TextContent", - "title": "Text" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } ] } }, "type": { "type": "string", - "description": "This message is triggered when the tool call fails.\n\nThis message is never triggered for async tool calls.\n\nIf this message is not provided, the model will be requested to respond.\n\nIf this message is provided, only this message will be spoken and the model will not be requested to come up with a response. It's an exclusive OR.", "enum": [ - "request-failed" - ] - }, - "endCallAfterSpokenEnabled": { - "type": "boolean", - "description": "This is an optional boolean that if true, the call will end after the message is spoken. Default is false.\n\n@default false", - "example": false + "make" + ], + "description": "The type of tool. \"make\" for Make tool." }, - "content": { - "type": "string", - "description": "This is the content that the assistant says when this message is triggered.", - "maxLength": 1000 + "metadata": { + "$ref": "#/components/schemas/MakeToolMetadata" }, - "conditions": { - "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Condition" - } + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] } }, "required": [ - "type" + "type", + "metadata" ] }, - "ToolMessageDelayed": { + "CustomMessage": { "type": "object", "properties": { "contents": { @@ -10605,204 +8895,173 @@ }, "type": { "type": "string", - "description": "This message is triggered when the tool call is delayed.\n\nThere are the two things that can trigger this message:\n1. The user talks with the assistant while your server is processing the request. Default is \"Sorry, a few more seconds.\"\n2. The server doesn't respond within `timingMilliseconds`.\n\nThis message is never triggered for async tool calls.", + "description": "This is a custom message.", "enum": [ - "request-response-delayed" + "custom-message" ] }, - "timingMilliseconds": { - "type": "number", - "minimum": 100, - "maximum": 120000, - "example": 1000, - "description": "The number of milliseconds to wait for the server response before saying this message." - }, "content": { "type": "string", - "description": "This is the content that the assistant says when this message is triggered.", + "description": "This is the content that the assistant will say when this message is triggered.", "maxLength": 1000 - }, - "conditions": { - "description": "This is an optional array of conditions that the tool call arguments must meet in order for this message to be triggered.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Condition" - } } }, "required": [ "type" ] }, - "MessageTarget": { + "TransferDestinationAssistant": { "type": "object", "properties": { - "role": { + "message": { + "description": "This is spoken to the customer before connecting them to the destination.\n\nUsage:\n- If this is not provided and transfer tool messages is not provided, default is \"Transferring the call now\".\n- If set to \"\", nothing is spoken. This is useful when you want to silently transfer. This is especially useful when transferring between assistants in a squad. In this scenario, you likely also want to set `assistant.firstMessageMode=assistant-speaks-first-with-model-generated-message` for the destination assistant.\n\nThis accepts a string or a ToolMessageStart class. Latter is useful if you want to specify multiple messages for different languages through the `contents` field.", + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/CustomMessage" + } + ] + }, + "type": { "type": "string", - "description": "This is the role of the message to target.\n\nIf not specified, will find the position in the message history ignoring role (effectively `any`).", - "example": "user", "enum": [ - "user", "assistant" ] }, - "position": { - "type": "number", - "description": "This is the position of the message to target.\n- Negative numbers: Count from end (-1 = most recent, -2 = second most recent)\n- 0: First/oldest message in history\n- Positive numbers: Specific position (0-indexed from start)\n\n@default -1 (most recent message)", - "example": -1 - } - } - }, - "RegexCondition": { - "type": "object", - "properties": { - "type": { + "transferMode": { "type": "string", - "description": "This is the type discriminator for regex condition", - "example": "regex", + "description": "This is the mode to use for the transfer. Defaults to `rolling-history`.\n\n- `rolling-history`: This is the default mode. It keeps the entire conversation history and appends the new assistant's system message on transfer.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n system: assistant2 system message\n assistant: assistant2 first message (or model generated if firstMessageMode is set to `assistant-speaks-first-with-model-generated-message`)\n\n- `swap-system-message-in-history`: This replaces the original system message with the new assistant's system message on transfer.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant2 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n assistant: assistant2 first message (or model generated if firstMessageMode is set to `assistant-speaks-first-with-model-generated-message`)\n\n- `delete-history`: This deletes the entire conversation history on transfer.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant2 system message\n assistant: assistant2 first message\n user: Yes, please\n assistant: how can i help?\n user: i need help with my account\n\n- `swap-system-message-in-history-and-remove-transfer-tool-messages`: This replaces the original system message with the new assistant's system message on transfer and removes transfer tool messages from conversation history sent to the LLM.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n transfer-tool\n transfer-tool-result\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant2 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n assistant: assistant2 first message (or model generated if firstMessageMode is set to `assistant-speaks-first-with-model-generated-message`)\n\n@default 'rolling-history'", "enum": [ - "regex" + "rolling-history", + "swap-system-message-in-history", + "swap-system-message-in-history-and-remove-transfer-tool-messages", + "delete-history" ] }, - "regex": { + "assistantName": { "type": "string", - "description": "This is the regular expression pattern to match against message content.\n\nNote:\n- This works by using the RegExp.test method in Node.JS. Eg. /hello/.test(\"hello there\") will return true.\n\nHot tips:\n- In JavaScript, escape \\ when sending the regex pattern. Eg. \"hello\\sthere\" will be sent over the wire as \"hellosthere\". Send \"hello\\\\sthere\" instead.\n- RegExp.test does substring matching, so /cat/.test(\"I love cats\") will return true. To do full string matching, use anchors: /^cat$/ will only match exactly \"cat\".\n- Word boundaries \\b are useful for matching whole words: /\\bcat\\b/ matches \"cat\" but not \"cats\" or \"category\".\n- Use inline flags for portability: (?i) for case insensitive, (?m) for multiline", - "examples": [ - "\\\\b(cancel|stop|wait)\\\\b - Matches whole words", - "^yes$ - Matches exactly yes (full string match)", - "(?i)hello - Case insensitive match" - ] + "description": "This is the assistant to transfer the call to." }, - "target": { - "description": "This is the target for messages to check against.\nIf not specified, the condition will run on the last message (position: -1).\nIf role is not specified, it will look at the last message regardless of role.\n@default { position: -1 }", - "allOf": [ + "description": { + "type": "string", + "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." + } + }, + "required": [ + "type", + "assistantName" + ] + }, + "TransferFallbackPlan": { + "type": "object", + "properties": { + "message": { + "description": "This is the message the assistant will deliver to the customer if the transfer fails.", + "oneOf": [ { - "$ref": "#/components/schemas/MessageTarget" + "type": "string" + }, + { + "$ref": "#/components/schemas/CustomMessage" } ] }, - "negate": { + "endCallEnabled": { "type": "boolean", - "description": "This is the flag that when true, the condition matches if the pattern does NOT match.\nUseful for ensuring certain words/phrases are absent.\n\n@default false", - "example": "true - Reject if user hasn\"t said goodbye: { regex: \"\\\\b(bye|goodbye)\\\\b\", negate: true }" + "description": "This controls what happens after delivering the failure message to the customer.\n- true: End the call after delivering the failure message (default)\n- false: Keep the assistant on the call to continue handling the customer's request\n\n@default true", + "default": true } }, "required": [ - "type", - "regex" + "message" ] }, - "LiquidCondition": { + "TransferAssistantModel": { "type": "object", "properties": { - "type": { + "provider": { "type": "string", - "description": "This is the type discriminator for liquid condition", - "example": "liquid", + "description": "The model provider for the transfer assistant", "enum": [ - "liquid" + "openai", + "anthropic", + "google", + "custom-llm" ] }, - "liquid": { + "model": { "type": "string", - "description": "This is the Liquid template that must return exactly \"true\" or \"false\" as a string.\nThe template is evaluated and the entire output must be either \"true\" or \"false\" - nothing else.\n\nAvailable variables:\n- `messages`: Array of recent messages in OpenAI chat completions format (ChatCompletionMessageParam[])\n Each message has properties like: role ('user', 'assistant', 'system'), content (string), etc.\n- `now`: Current timestamp in milliseconds (built-in Liquid variable)\n- Any assistant variable values (e.g., `userName`, `accountStatus`)\n\nUseful Liquid filters for messages:\n- `messages | last: 5` - Get the 5 most recent messages\n- `messages | where: 'role', 'user'` - Filter to only user messages\n- `messages | reverse` - Reverse the order of messages", - "examples": [ - "{% if messages.last.content contains goodbye %}true{% else %}false{% endif %}", - "{% assign userMessages = messages | where: role, user %}{% if userMessages.size > 3 %}true{% else %}false{% endif %}" - ] + "description": "The model name - must be compatible with the selected provider", + "example": "gpt-4o" + }, + "messages": { + "type": "array", + "description": "These are the messages used to configure the transfer assistant.\n\n@default: ```\n[\n {\n role: 'system',\n content: 'You are a transfer assistant designed to facilitate call transfers. Your core responsibility is to manage the transfer process efficiently.\\n\\n## Core Responsibility\\n- Facilitate the transfer process by using transferSuccessful or transferCancel tools appropriately\\n\\n## When to Respond\\n- Answer questions about the transfer process or provide summaries when specifically asked by the operator\\n- Respond to direct questions about the current transfer situation\\n\\n## What to Avoid\\n- Do not discuss topics unrelated to the transfer\\n- Do not engage in general conversation\\n- Keep all interactions focused on facilitating the transfer\\n\\n## Transfer Tools\\n- Use transferSuccessful when the transfer should proceed\\n- Use transferCancel when the transfer cannot be completed\\n\\nStay focused on your core responsibility of facilitating transfers.'\n }\n]```\n\n**Default Behavior:** If you don't provide any messages or don't include a system message as the first message, the default system message above will be automatically added.\n\n**Override Default:** To replace the default system message, provide your own system message as the first message in the array.\n\n**Add Context:** You can provide additional messages (user, assistant, etc.) to add context while keeping the default system message, or combine them with your custom system message." + }, + "tools": { + "type": "array", + "description": "Tools available to the transfer assistant during warm-transfer-experimental.\n\n**Default Behavior:** The transfer assistant will ALWAYS have both `transferSuccessful` and `transferCancel` tools automatically added, regardless of what you provide here.\n\n**Default Tools:**\n- `transferSuccessful`: \"Call this function to confirm the transfer is successful and connect the customer. Use this when you detect a human has answered and is ready to take the call.\"\n- `transferCancel`: \"Call this function to cancel the transfer when no human answers or transfer should not proceed. Use this when you detect voicemail, busy signal, or no answer.\"\n\n**Customization:** You can override the default tools by providing `transferSuccessful` and/or `transferCancel` tools with custom `function` or `messages` configurations.\n\n**Additional Tools:** You can also provide other tools, but the two transfer tools will always be present and available to the assistant." } }, "required": [ - "type", - "liquid" + "provider", + "model" ] }, - "GroupCondition": { + "TransferAssistant": { "type": "object", "properties": { - "type": { + "name": { "type": "string", - "description": "This is the type discriminator for group condition", - "example": "group", - "enum": [ - "group" + "description": "Optional name for the transfer assistant", + "maxLength": 100, + "default": "transfer-assistant", + "example": "Sales Transfer Assistant" + }, + "model": { + "description": "Model configuration for the transfer assistant", + "allOf": [ + { + "$ref": "#/components/schemas/TransferAssistantModel" + } ] }, - "operator": { + "firstMessage": { "type": "string", - "description": "This is the logical operator for combining conditions in this group", - "examples": [ - "AND", - "OR" - ], - "enum": [ - "AND", - "OR" - ] + "description": "This is the first message that the transfer assistant will say.\nThis can also be a URL to a custom audio file.\n\nIf unspecified, assistant will wait for user to speak and use the model to respond once they speak.", + "example": "Hello! I understand you need to be transferred. Let me connect you." }, - "conditions": { - "type": "array", - "description": "This is the list of nested conditions to evaluate.\nSupports recursive nesting of groups for complex logic.", - "examples": [ - "[{ type: \"regex\", regex: \"(?i)stop\", target: { role: \"user\" } }]", - "[{ type: \"group\", operator: \"AND\", conditions: [...] }]" + "firstMessageMode": { + "type": "string", + "description": "This is the mode for the first message. Default is 'assistant-speaks-first'.\n\nUse:\n- 'assistant-speaks-first' to have the assistant speak first.\n- 'assistant-waits-for-user' to have the assistant wait for the user to speak first.\n- 'assistant-speaks-first-with-model-generated-message' to have the assistant speak first with a message generated by the model based on the conversation state.\n\n@default 'assistant-speaks-first'", + "enum": [ + "assistant-speaks-first", + "assistant-speaks-first-with-model-generated-message", + "assistant-waits-for-user" ], - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/RegexCondition", - "title": "RegexCondition" - }, - { - "$ref": "#/components/schemas/LiquidCondition", - "title": "LiquidCondition" - }, - { - "$ref": "#/components/schemas/GroupCondition", - "title": "GroupCondition", - "description": "This is the GroupCondition object but Swagger does not display nested schemas correctly." - } - ] - } + "example": "assistant-speaks-first" + }, + "maxDurationSeconds": { + "type": "number", + "description": "This is the maximum duration in seconds for the transfer assistant conversation.\nAfter this time, the transfer will be cancelled automatically.\n@default 120", + "minimum": 10, + "maximum": 43200, + "example": 120 + }, + "silenceTimeoutSeconds": { + "type": "number", + "description": "This is the number of seconds of silence to wait before ending the call. Defaults to 30.\n\n@default 30", + "minimum": 10, + "maximum": 3600 } }, "required": [ - "type", - "operator", - "conditions" + "model" ] }, - "ToolRejectionPlan": { - "type": "object", - "properties": { - "conditions": { - "type": "array", - "description": "This is the list of conditions that must be evaluated.\n\nUsage:\n- If all conditions match (AND logic), the tool call is rejected.\n- For OR logic at the top level, use a single 'group' condition with operator: 'OR'.\n\n@default [] - Empty array means tool always executes", - "examples": [ - "[{ type: \"regex\", regex: \"(?i)\\\\b(cancel|stop)\\\\b\", target: { role: \"user\" } }]", - "[{ type: \"group\", operator: \"OR\", conditions: [...] }]" - ], - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/RegexCondition", - "title": "RegexCondition" - }, - { - "$ref": "#/components/schemas/LiquidCondition", - "title": "LiquidCondition" - }, - { - "$ref": "#/components/schemas/GroupCondition", - "title": "GroupCondition", - "description": "This is the GroupCondition object but Swagger does not display nested schemas correctly." - } - ] - } - } - } - }, - "CreateDtmfToolDTO": { + "TransferCancelToolUserEditable": { "type": "object", "properties": { "messages": { @@ -10832,9 +9091,9 @@ "type": { "type": "string", "enum": [ - "dtmf" + "transferCancel" ], - "description": "The type of tool. \"dtmf\" for DTMF tool." + "description": "The type of tool. \"transferCancel\" for Transfer Cancel tool. This tool can only be used during warm-transfer-experimental by the transfer assistant to cancel an ongoing transfer and return the call back to the original assistant when the transfer cannot be completed." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -10849,7 +9108,7 @@ "type" ] }, - "CreateEndCallToolDTO": { + "TransferSuccessfulToolUserEditable": { "type": "object", "properties": { "messages": { @@ -10879,9 +9138,9 @@ "type": { "type": "string", "enum": [ - "endCall" + "transferSuccessful" ], - "description": "The type of tool. \"endCall\" for End Call tool." + "description": "The type of tool. \"transferSuccessful\" for Transfer Successful tool. This tool can only be used during warm-transfer-experimental by the transfer assistant to confirm that the transfer should proceed and finalize the handoff to the destination." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -10896,185 +9155,218 @@ "type" ] }, - "CreateVoicemailToolDTO": { + "SummaryPlan": { "type": "object", "properties": { "messages": { + "description": "These are the messages used to generate the summary.\n\n@default: ```\n[\n {\n \"role\": \"system\",\n \"content\": \"You are an expert note-taker. You will be given a transcript of a call. Summarize the call in 2-3 sentences. DO NOT return anything except the summary.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Here is the transcript:\\n\\n{{transcript}}\\n\\n. Here is the ended reason of the call:\\n\\n{{endedReason}}\\n\\n\"\n }\n]```\n\nYou can customize by providing any messages you want.\n\nHere are the template variables available:\n- {{transcript}}: The transcript of the call from `call.artifact.transcript` \n- {{systemPrompt}}: The system prompt of the call from `assistant.model.messages[type=system].content` \n- {{messages}}: The messages of the call from `assistant.model.messages` \n- {{endedReason}}: The ended reason of the call from `call.endedReason`", "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] + "type": "object" } }, - "type": { - "type": "string", - "description": "The type of tool. \"voicemail\" for Voicemail tool.", - "enum": [ - "voicemail" - ] + "enabled": { + "type": "boolean", + "description": "This determines whether a summary is generated and stored in `call.analysis.summary`. Defaults to true.\n\nUsage:\n- If you want to disable the summary, set this to false.\n\n@default true" }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "timeoutSeconds": { + "type": "number", + "description": "This is how long the request is tried before giving up. When request times out, `call.analysis.summary` will be empty.\n\nUsage:\n- To guarantee the summary is generated, set this value high. Note, this will delay the end of call report in cases where model is slow to respond.\n\n@default 5 seconds", + "minimum": 1, + "maximum": 60 } - }, - "required": [ - "type" - ] + } }, - "JsonSchema": { + "TransferPlan": { "type": "object", "properties": { - "type": { + "mode": { "type": "string", - "description": "This is the type of output you'd like.\n\n`string`, `number`, `integer`, `boolean` are the primitive types and should be obvious.\n\n`array` and `object` are more interesting and quite powerful. They allow you to define nested structures.\n\nFor `array`, you can define the schema of the items in the array using the `items` property.\n\nFor `object`, you can define the properties of the object using the `properties` property.", + "description": "This configures how transfer is executed and the experience of the destination party receiving the call.\n\nUsage:\n- `blind-transfer`: The assistant forwards the call to the destination without any message or summary.\n- `blind-transfer-add-summary-to-sip-header`: The assistant forwards the call to the destination and adds a SIP header X-Transfer-Summary to the call to include the summary.\n- `warm-transfer-say-message`: The assistant dials the destination, delivers the `message` to the destination party, connects the customer, and leaves the call.\n- `warm-transfer-say-summary`: The assistant dials the destination, provides a summary of the call to the destination party, connects the customer, and leaves the call.\n- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message`: The assistant dials the destination, waits for the operator to speak, delivers the `message` to the destination party, and then connects the customer.\n- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary`: The assistant dials the destination, waits for the operator to speak, provides a summary of the call to the destination party, and then connects the customer.\n- `warm-transfer-twiml`: The assistant dials the destination, executes the twiml instructions on the destination call leg, connects the customer, and leaves the call.\n- `warm-transfer-experimental`: The assistant puts the customer on hold, dials the destination, and if the destination answers (and is human), delivers a message or summary before connecting the customer. If the destination is unreachable or not human (e.g., with voicemail detection), the assistant delivers the `fallbackMessage` to the customer and optionally ends the call.\n\n@default 'blind-transfer'", "enum": [ - "string", - "number", - "integer", - "boolean", - "array", - "object" + "blind-transfer", + "blind-transfer-add-summary-to-sip-header", + "warm-transfer-say-message", + "warm-transfer-say-summary", + "warm-transfer-twiml", + "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message", + "warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary", + "warm-transfer-experimental" ] }, - "items": { - "type": "object", - "description": "This is required if the type is \"array\". This is the schema of the items in the array.\n\nThis is of type JsonSchema. However, Swagger doesn't support circular references." + "message": { + "description": "This is the message the assistant will deliver to the destination party before connecting the customer.\n\nUsage:\n- Used only when `mode` is `blind-transfer-add-summary-to-sip-header`, `warm-transfer-say-message`, `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message`, or `warm-transfer-experimental`.", + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/CustomMessage" + } + ] }, - "properties": { + "timeout": { + "type": "number", + "description": "This is the timeout in seconds for the warm-transfer-wait-for-operator-to-speak-first-and-then-say-message/summary\n\n@default 60", + "minimum": 1, + "maximum": 600, + "default": 60 + }, + "sipVerb": { "type": "object", - "description": "This is required if the type is \"object\". This specifies the properties of the object.\n\nThis is a map of string to JsonSchema. However, Swagger doesn't support circular references." + "description": "This specifies the SIP verb to use while transferring the call.\n- 'refer': Uses SIP REFER to transfer the call (default)\n- 'bye': Ends current call with SIP BYE\n- 'dial': Uses SIP DIAL to transfer the call", + "default": "refer", + "enum": [ + "refer", + "bye", + "dial" + ] }, - "description": { + "holdAudioUrl": { "type": "string", - "description": "This is the description to help the model understand what it needs to output." + "description": "This is the URL to an audio file played while the customer is on hold during transfer.\n\nUsage:\n- Used only when `mode` is `warm-transfer-experimental`.\n- Used when transferring calls to play hold audio for the customer.\n- Must be a publicly accessible URL to an audio file.\n- Supported formats: MP3 and WAV.\n- If not provided, the default hold audio will be used." }, - "pattern": { + "transferCompleteAudioUrl": { "type": "string", - "description": "This is the pattern of the string. This is a regex that will be used to validate the data in question. To use a common format, use the `format` property instead.\n\nOpenAI documentation: https://platform.openai.com/docs/guides/structured-outputs#supported-properties" + "description": "This is the URL to an audio file played after the warm transfer message or summary is delivered to the destination party.\nIt can be used to play a custom sound like 'beep' to notify that the transfer is complete.\n\nUsage:\n- Used only when `mode` is `warm-transfer-experimental`.\n- Used when transferring calls to play hold audio for the destination party.\n- Must be a publicly accessible URL to an audio file.\n- Supported formats: MP3 and WAV." }, - "format": { + "twiml": { "type": "string", - "description": "This is the format of the string. To pass a regex, use the `pattern` property instead.\n\nOpenAI documentation: https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat&type-restrictions=string-restrictions", - "enum": [ - "date-time", - "time", - "date", - "duration", - "email", - "hostname", - "ipv4", - "ipv6", - "uuid" - ] + "description": "This is the TwiML instructions to execute on the destination call leg before connecting the customer.\n\nUsage:\n- Used only when `mode` is `warm-transfer-twiml`.\n- Supports only `Play`, `Say`, `Gather`, `Hangup` and `Pause` verbs.\n- Maximum length is 4096 characters.\n\nExample:\n```\nHello, transferring a customer to you.\n\nThey called about billing questions.\n```", + "maxLength": 4096 }, - "required": { - "description": "This is a list of properties that are required.\n\nThis only makes sense if the type is \"object\".", - "type": "array", - "items": { - "type": "string" - } + "summaryPlan": { + "description": "This is the plan for generating a summary of the call to present to the destination party.\n\nUsage:\n- Used only when `mode` is `blind-transfer-add-summary-to-sip-header` or `warm-transfer-say-summary` or `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary` or `warm-transfer-experimental`.", + "allOf": [ + { + "$ref": "#/components/schemas/SummaryPlan" + } + ] }, - "enum": { - "description": "This array specifies the allowed values that can be used to restrict the output of the model.", - "type": "array", - "items": { - "type": "string" - } + "sipHeadersInReferToEnabled": { + "type": "boolean", + "description": "This flag includes the sipHeaders from above in the refer to sip uri as url encoded query params.\n\n@default false" }, - "title": { - "type": "string", - "description": "This is the title of the schema." + "fallbackPlan": { + "description": "This configures the fallback plan when the transfer fails (destination unreachable, busy, or not human).\n\nUsage:\n- Used only when `mode` is `warm-transfer-experimental`.\n- If not provided when using `warm-transfer-experimental`, a default message will be used.", + "allOf": [ + { + "$ref": "#/components/schemas/TransferFallbackPlan" + } + ] } }, "required": [ - "type" + "mode" ] }, - "OpenAIFunctionParameters": { + "TransferDestinationNumber": { "type": "object", "properties": { + "message": { + "description": "This is spoken to the customer before connecting them to the destination.\n\nUsage:\n- If this is not provided and transfer tool messages is not provided, default is \"Transferring the call now\".\n- If set to \"\", nothing is spoken. This is useful when you want to silently transfer. This is especially useful when transferring between assistants in a squad. In this scenario, you likely also want to set `assistant.firstMessageMode=assistant-speaks-first-with-model-generated-message` for the destination assistant.\n\nThis accepts a string or a ToolMessageStart class. Latter is useful if you want to specify multiple messages for different languages through the `contents` field.", + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/CustomMessage" + } + ] + }, "type": { "type": "string", - "description": "This must be set to 'object'. It instructs the model to return a JSON object containing the function call properties.", "enum": [ - "object" + "number" ] }, - "properties": { - "type": "object", - "description": "This provides a description of the properties required by the function.\nJSON Schema can be used to specify expectations for each property.\nRefer to [this doc](https://ajv.js.org/json-schema.html#json-data-type) for a comprehensive guide on JSON Schema.", - "additionalProperties": { - "$ref": "#/components/schemas/JsonSchema" - } + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true }, - "required": { - "description": "This specifies the properties that are required by the function.", - "type": "array", - "items": { - "type": "string" - } + "number": { + "type": "string", + "description": "This is the phone number to transfer the call to.", + "minLength": 3, + "maxLength": 40 + }, + "extension": { + "type": "string", + "description": "This is the extension to dial after transferring the call to the `number`.", + "minLength": 1, + "maxLength": 10 + }, + "callerId": { + "type": "string", + "description": "This is the caller ID to use when transferring the call to the `number`.\n\nUsage:\n- If not provided, the caller ID will be the number the call is coming from. Example, +14151111111 calls in to and the assistant transfers out to +16470000000. +16470000000 will see +14151111111 as the caller.\n- To change this behavior, provide a `callerId`.\n- Set to '{{customer.number}}' to always use the customer's number as the caller ID.\n- Set to '{{phoneNumber.number}}' to always use the phone number of the assistant as the caller ID.\n- Set to any E164 number to always use that number as the caller ID. This needs to be a number that is owned or verified by your Transport provider like Twilio.\n\nFor Twilio, you can read up more here: https://www.twilio.com/docs/voice/twiml/dial#callerid", + "maxLength": 40 + }, + "transferPlan": { + "description": "This configures how transfer is executed and the experience of the destination party receiving the call. Defaults to `blind-transfer`.\n\n@default `transferPlan.mode='blind-transfer'`", + "allOf": [ + { + "$ref": "#/components/schemas/TransferPlan" + } + ] + }, + "description": { + "type": "string", + "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." } }, "required": [ "type", - "properties" + "number" ] }, - "OpenAIFunction": { + "TransferDestinationSip": { "type": "object", "properties": { - "strict": { - "type": "boolean", - "description": "This is a boolean that controls whether to enable strict schema adherence when generating the function call. If set to true, the model will follow the exact schema defined in the parameters field. Only a subset of JSON Schema is supported when strict is true. Learn more about Structured Outputs in the [OpenAI guide](https://openai.com/index/introducing-structured-outputs-in-the-api/).\n\n@default false", - "default": false + "message": { + "description": "This is spoken to the customer before connecting them to the destination.\n\nUsage:\n- If this is not provided and transfer tool messages is not provided, default is \"Transferring the call now\".\n- If set to \"\", nothing is spoken. This is useful when you want to silently transfer. This is especially useful when transferring between assistants in a squad. In this scenario, you likely also want to set `assistant.firstMessageMode=assistant-speaks-first-with-model-generated-message` for the destination assistant.\n\nThis accepts a string or a ToolMessageStart class. Latter is useful if you want to specify multiple messages for different languages through the `contents` field.", + "oneOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/CustomMessage" + } + ] }, - "name": { + "type": { "type": "string", - "description": "This is the the name of the function to be called.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.", - "maxLength": 64, - "pattern": "/^[a-zA-Z0-9_-]{1,64}$/" + "enum": [ + "sip" + ] }, - "description": { + "sipUri": { "type": "string", - "description": "This is the description of what the function does, used by the AI to choose when and how to call the function.", - "maxLength": 1000 + "description": "This is the SIP URI to transfer the call to." }, - "parameters": { - "description": "These are the parameters the functions accepts, described as a JSON Schema object.\n\nSee the [OpenAI guide](https://platform.openai.com/docs/guides/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format.\n\nOmitting parameters defines a function with an empty parameter list.", + "transferPlan": { + "description": "This configures how transfer is executed and the experience of the destination party receiving the call. Defaults to `blind-transfer`.\n\n@default `transferPlan.mode='blind-transfer'`", "allOf": [ { - "$ref": "#/components/schemas/OpenAIFunctionParameters" + "$ref": "#/components/schemas/TransferPlan" } ] + }, + "sipHeaders": { + "type": "object", + "description": "These are custom headers to be added to SIP refer during transfer call." + }, + "description": { + "type": "string", + "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." } }, "required": [ - "name" + "type", + "sipUri" ] }, - "CreateFunctionToolDTO": { + "CreateTransferCallToolDTO": { "type": "object", "properties": { "messages": { @@ -11104,92 +9396,29 @@ "type": { "type": "string", "enum": [ - "function" - ], - "description": "The type of tool. \"function\" for Function tool." - }, - "async": { - "type": "boolean", - "example": false, - "description": "This determines if the tool is async.\n\n If async, the assistant will move forward without waiting for your server to respond. This is useful if you just want to trigger something on your server.\n\n If sync, the assistant will wait for your server to respond. This is useful if want assistant to respond with the result from your server.\n\n Defaults to synchronous (`false`)." - }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - }, - "function": { - "description": "This is the function definition of the tool.", - "allOf": [ - { - "$ref": "#/components/schemas/OpenAIFunction" - } - ] - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } + "transferCall" ] - } - }, - "required": [ - "type" - ] - }, - "GhlToolMetadata": { - "type": "object", - "properties": { - "workflowId": { - "type": "string" }, - "locationId": { - "type": "string" - } - } - }, - "CreateGhlToolDTO": { - "type": "object", - "properties": { - "messages": { + "destinations": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" + "$ref": "#/components/schemas/TransferDestinationAssistant", + "title": "Assistant" }, { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "Number" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "Sip" } ] } }, - "type": { - "type": "string", - "enum": [ - "ghl" - ], - "description": "The type of tool. \"ghl\" for GHL tool." - }, - "metadata": { - "$ref": "#/components/schemas/GhlToolMetadata" - }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -11200,137 +9429,147 @@ } }, "required": [ - "type", - "metadata" + "type" ] }, - "MakeToolMetadata": { + "ContextEngineeringPlanLastNMessages": { "type": "object", "properties": { - "scenarioId": { - "type": "number" + "type": { + "type": "string", + "enum": [ + "lastNMessages" + ] }, - "triggerHookId": { - "type": "number" - } - } + "maxMessages": { + "type": "number", + "description": "This is the maximum number of messages to include in the context engineering plan.", + "minimum": 0 + } + }, + "required": [ + "type", + "maxMessages" + ] }, - "CreateMakeToolDTO": { + "ContextEngineeringPlanNone": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, "type": { "type": "string", "enum": [ - "make" - ], - "description": "The type of tool. \"make\" for Make tool." - }, - "metadata": { - "$ref": "#/components/schemas/MakeToolMetadata" - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } + "none" ] } }, "required": [ - "type", - "metadata" + "type" ] }, - "CustomMessage": { + "ContextEngineeringPlanAll": { "type": "object", "properties": { - "contents": { - "type": "array", - "description": "This is an alternative to the `content` property. It allows to specify variants of the same content, one per language.\n\nUsage:\n- If your assistants are multilingual, you can provide content for each language.\n- If you don't provide content for a language, the first item in the array will be automatically translated to the active language at that moment.\n\nThis will override the `content` property.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TextContent", - "title": "Text" - } - ] - } - }, "type": { "type": "string", - "description": "This is a custom message.", "enum": [ - "custom-message" + "all" ] + } + }, + "required": [ + "type" + ] + }, + "VariableExtractionAlias": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "This is the key of the variable.\n\nThis variable will be accessible during the call as `{{key}}` and stored in `call.artifact.variableValues` after the call.\n\nRules:\n- Must start with a letter (a-z, A-Z).\n- Subsequent characters can be letters, numbers, or underscores.\n- Minimum length of 1 and maximum length of 40.", + "minLength": 1, + "maxLength": 40, + "pattern": "/^[a-zA-Z][a-zA-Z0-9_]*$/" }, - "content": { + "value": { "type": "string", - "description": "This is the content that the assistant will say when this message is triggered.", - "maxLength": 1000 + "description": "This is the value of the variable.\n\nThis can reference existing variables, use filters, and perform transformations.\n\nExamples: \"{{name}}\", \"{{customer.email}}\", \"Hello {{name | upcase}}\"", + "maxLength": 10000 } }, "required": [ - "type" + "key", + "value" ] }, - "TransferDestinationAssistant": { + "VariableExtractionPlan": { "type": "object", "properties": { - "message": { - "description": "This is spoken to the customer before connecting them to the destination.\n\nUsage:\n- If this is not provided and transfer tool messages is not provided, default is \"Transferring the call now\".\n- If set to \"\", nothing is spoken. This is useful when you want to silently transfer. This is especially useful when transferring between assistants in a squad. In this scenario, you likely also want to set `assistant.firstMessageMode=assistant-speaks-first-with-model-generated-message` for the destination assistant.\n\nThis accepts a string or a ToolMessageStart class. Latter is useful if you want to specify multiple messages for different languages through the `contents` field.", - "oneOf": [ - { - "type": "string" - }, + "schema": { + "description": "This is the schema to extract.\n\nExamples:\n1. To extract object properties, you can use the following schema:\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n2. To extract nested properties, you can use the following schema:\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"object\",\n \"properties\": {\n \"first\": {\n \"type\": \"string\"\n },\n \"last\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n3. To extract array items, you can use the following schema:\n```json\n{\n \"type\": \"array\",\n \"title\": \"zipCodes\",\n \"items\": {\n \"type\": \"string\"\n }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4. To extract array of objects, you can use the following schema:\n\n```json\n{\n \"type\": \"array\",\n \"name\": \"people\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n },\n \"zipCodes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.", + "allOf": [ { - "$ref": "#/components/schemas/CustomMessage" + "$ref": "#/components/schemas/JsonSchema" } ] }, + "aliases": { + "description": "These are additional variables to create.\n\nThese will be accessible during the call as `{{key}}` and stored in `call.artifact.variableValues` after the call.\n\nExample:\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{name}}\"\n },\n {\n \"key\": \"fullName\",\n \"value\": \"{{firstName}} {{lastName}}\"\n },\n {\n \"key\": \"greeting\",\n \"value\": \"Hello {{name}}, welcome to {{company}}!\"\n },\n {\n \"key\": \"customerCity\",\n \"value\": \"{{addresses[0].city}}\"\n },\n {\n \"key\": \"something\",\n \"value\": \"{{any liquid}}\"\n }\n ]\n}\n```\n\nThis will create variables `customerName`, `fullName`, `greeting`, `customerCity`, and `something`. To access these variables, you can reference them as `{{customerName}}`, `{{fullName}}`, `{{greeting}}`, `{{customerCity}}`, and `{{something}}`.", + "type": "array", + "items": { + "$ref": "#/components/schemas/VariableExtractionAlias" + } + } + } + }, + "HandoffDestinationAssistant": { + "type": "object", + "properties": { "type": { "type": "string", "enum": [ "assistant" ] }, - "transferMode": { - "type": "string", - "description": "This is the mode to use for the transfer. Defaults to `rolling-history`.\n\n- `rolling-history`: This is the default mode. It keeps the entire conversation history and appends the new assistant's system message on transfer.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n system: assistant2 system message\n assistant: assistant2 first message (or model generated if firstMessageMode is set to `assistant-speaks-first-with-model-generated-message`)\n\n- `swap-system-message-in-history`: This replaces the original system message with the new assistant's system message on transfer.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant2 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n assistant: assistant2 first message (or model generated if firstMessageMode is set to `assistant-speaks-first-with-model-generated-message`)\n\n- `delete-history`: This deletes the entire conversation history on transfer.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant2 system message\n assistant: assistant2 first message\n user: Yes, please\n assistant: how can i help?\n user: i need help with my account\n\n- `swap-system-message-in-history-and-remove-transfer-tool-messages`: This replaces the original system message with the new assistant's system message on transfer and removes transfer tool messages from conversation history sent to the LLM.\n\n Example:\n\n Pre-transfer:\n system: assistant1 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n transfer-tool\n transfer-tool-result\n assistant: (destination.message)\n\n Post-transfer:\n system: assistant2 system message\n assistant: assistant1 first message\n user: hey, good morning\n assistant: how can i help?\n user: i need help with my account\n assistant: (destination.message)\n assistant: assistant2 first message (or model generated if firstMessageMode is set to `assistant-speaks-first-with-model-generated-message`)\n\n@default 'rolling-history'", - "enum": [ - "rolling-history", - "swap-system-message-in-history", - "swap-system-message-in-history-and-remove-transfer-tool-messages", - "delete-history" + "contextEngineeringPlan": { + "description": "This is the plan for manipulating the message context before handing off the call to the next assistant.", + "oneOf": [ + { + "$ref": "#/components/schemas/ContextEngineeringPlanLastNMessages", + "title": "Last N Messages" + }, + { + "$ref": "#/components/schemas/ContextEngineeringPlanNone", + "title": "None" + }, + { + "$ref": "#/components/schemas/ContextEngineeringPlanAll", + "title": "All" + } ] }, "assistantName": { "type": "string", - "description": "This is the assistant to transfer the call to." + "description": "This is the assistant to transfer the call to. You must provide either assistantName or assistantId." + }, + "assistantId": { + "type": "string", + "description": "This is the assistant id to transfer the call to. You must provide either assistantName or assistantId." + }, + "assistant": { + "description": "This is a transient assistant to transfer the call to. You may provide a transient assistant in the response `handoff-destination-request` in a dynamic handoff.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } + ] + }, + "variableExtractionPlan": { + "description": "This is the variable extraction plan for the handoff tool.", + "allOf": [ + { + "$ref": "#/components/schemas/VariableExtractionPlan" + } + ] }, "description": { "type": "string", @@ -11338,118 +9577,178 @@ } }, "required": [ - "type", - "assistantName" + "type" ] }, - "TransferFallbackPlan": { + "HandoffDestinationDynamic": { "type": "object", "properties": { - "message": { - "description": "This is the message the assistant will deliver to the customer if the transfer fails.", - "oneOf": [ - { - "type": "string" - }, + "type": { + "type": "string", + "enum": [ + "dynamic" + ] + }, + "server": { + "description": "This is where Vapi will send the handoff-destination-request webhook in a dynamic handoff.\n\nThe order of precedence is:\n\n1. tool.server.url\n2. assistant.server.url\n3. phoneNumber.server.url\n4. org.server.url", + "allOf": [ { - "$ref": "#/components/schemas/CustomMessage" + "$ref": "#/components/schemas/Server" } ] }, - "endCallEnabled": { - "type": "boolean", - "description": "This controls what happens after delivering the failure message to the customer.\n- true: End the call after delivering the failure message (default)\n- false: Keep the assistant on the call to continue handling the customer's request\n\n@default true", - "default": true + "description": { + "type": "string", + "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." } }, "required": [ - "message" + "type" ] }, - "TransferAssistantModel": { + "CreateHandoffToolDTO": { "type": "object", "properties": { - "provider": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "type": { "type": "string", - "description": "The model provider for the transfer assistant", + "description": "This is the type of the tool.\nWhen you're using handoff tool, we recommend adding this to your system prompt\n---\n# System context\n\nYou are part of a multi-agent system designed to make agent coordination and execution easy. Agents uses two primary abstraction: **Agents** and **Handoffs**. An agent encompasses instructions and tools and can hand off a conversation to another agent when appropriate. Handoffs are achieved by calling a handoff function, generally named `handoff_to_`. Handoffs between agents are handled seamlessly in the background; do not mention or draw attention to these handoffs in your conversation with the user.\n\n# Agent context\n\n{put your agent system prompt here}\n---", "enum": [ - "openai", - "anthropic", - "google", - "custom-llm" + "handoff" ] }, - "model": { - "type": "string", - "description": "The model name - must be compatible with the selected provider", - "example": "gpt-4o" - }, - "messages": { + "destinations": { "type": "array", - "description": "These are the messages used to configure the transfer assistant.\n\n@default: ```\n[\n {\n role: 'system',\n content: 'You are a transfer assistant designed to facilitate call transfers. Your core responsibility is to manage the transfer process efficiently.\\n\\n## Core Responsibility\\n- Facilitate the transfer process by using transferSuccessful or transferCancel tools appropriately\\n\\n## When to Respond\\n- Answer questions about the transfer process or provide summaries when specifically asked by the operator\\n- Respond to direct questions about the current transfer situation\\n\\n## What to Avoid\\n- Do not discuss topics unrelated to the transfer\\n- Do not engage in general conversation\\n- Keep all interactions focused on facilitating the transfer\\n\\n## Transfer Tools\\n- Use transferSuccessful when the transfer should proceed\\n- Use transferCancel when the transfer cannot be completed\\n\\nStay focused on your core responsibility of facilitating transfers.'\n }\n]```\n\n**Default Behavior:** If you don't provide any messages or don't include a system message as the first message, the default system message above will be automatically added.\n\n**Override Default:** To replace the default system message, provide your own system message as the first message in the array.\n\n**Add Context:** You can provide additional messages (user, assistant, etc.) to add context while keeping the default system message, or combine them with your custom system message." + "description": "These are the destinations that the call can be handed off to.\n\nUsage:\n1. Single destination\n\nUse `assistantId` to handoff the call to a saved assistant, or `assistantName` to handoff the call to an assistant in the same squad.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\", // or \"assistantName\": \"Assistant123\"\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2. Multiple destinations\n\n2.1. Multiple Tools, Each With One Destination (OpenAI recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n ],\n },\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2.2. One Tool, Multiple Destinations (Anthropic recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3. Dynamic destination\n\n3.1 To determine the destination dynamically, supply a `dynamic` handoff destination type and a `server` object.\n VAPI will send a handoff-destination-request webhook to the `server.url`.\n The response from the server will be used as the destination (if valid).\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3.2. To pass custom parameters to the server, you can use the `function` object.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n },\n }\n ],\n \"function\": {\n \"name\": \"handoff\",\n \"description\": \"Call this function when the customer is ready to be handed off to the next assistant\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"destination\": {\n \"type\": \"string\",\n \"description\": \"Use dynamic when customer is ready to be handed off to the next assistant\",\n \"enum\": [\"dynamic\"]\n },\n \"customerAreaCode\": {\n \"type\": \"number\",\n \"description\": \"Area code of the customer\"\n },\n \"customerIntent\": {\n \"type\": \"string\",\n \"enum\": [\"new-customer\", \"existing-customer\"],\n \"description\": \"Use new-customer when customer is a new customer, existing-customer when customer is an existing customer\"\n },\n \"customerSentiment\": {\n \"type\": \"string\",\n \"enum\": [\"positive\", \"negative\", \"neutral\"],\n \"description\": \"Use positive when customer is happy, negative when customer is unhappy, neutral when customer is neutral\"\n }\n }\n }\n }\n }\n ]\n}\n```\n\nThe properties `customerAreaCode`, `customerIntent`, and `customerSentiment` will be passed to the server in the webhook request body.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/HandoffDestinationAssistant", + "title": "Assistant" + }, + { + "$ref": "#/components/schemas/HandoffDestinationDynamic", + "title": "Dynamic" + } + ] + } }, - "tools": { - "type": "array", - "description": "Tools available to the transfer assistant during warm-transfer-experimental.\n\n**Default Behavior:** The transfer assistant will ALWAYS have both `transferSuccessful` and `transferCancel` tools automatically added, regardless of what you provide here.\n\n**Default Tools:**\n- `transferSuccessful`: \"Call this function to confirm the transfer is successful and connect the customer. Use this when you detect a human has answered and is ready to take the call.\"\n- `transferCancel`: \"Call this function to cancel the transfer when no human answers or transfer should not proceed. Use this when you detect voicemail, busy signal, or no answer.\"\n\n**Customization:** You can override the default tools by providing `transferSuccessful` and/or `transferCancel` tools with custom `function` or `messages` configurations.\n\n**Additional Tools:** You can also provide other tools, but the two transfer tools will always be present and available to the assistant." + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] } }, "required": [ - "provider", - "model" + "type" ] }, - "TransferAssistant": { + "CreateCustomKnowledgeBaseDTO": { "type": "object", "properties": { - "name": { + "provider": { "type": "string", - "description": "Optional name for the transfer assistant", - "maxLength": 100, - "default": "transfer-assistant", - "example": "Sales Transfer Assistant" + "description": "This knowledge base is bring your own knowledge base implementation.", + "enum": [ + "custom-knowledge-base" + ] }, - "model": { - "description": "Model configuration for the transfer assistant", + "server": { + "description": "This is where the knowledge base request will be sent.\n\nRequest Example:\n\nPOST https://{server.url}\nContent-Type: application/json\n\n{\n \"messsage\": {\n \"type\": \"knowledge-base-request\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Why is ocean blue?\"\n }\n ],\n ...other metadata about the call...\n }\n}\n\nResponse Expected:\n```\n{\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"The ocean is blue because water absorbs everything but blue.\",\n }, // YOU CAN RETURN THE EXACT RESPONSE TO SPEAK\n \"documents\": [\n {\n \"content\": \"The ocean is blue primarily because water absorbs colors in the red part of the light spectrum and scatters the blue light, making it more visible to our eyes.\",\n \"similarity\": 1\n },\n {\n \"content\": \"Blue light is scattered more by the water molecules than other colors, enhancing the blue appearance of the ocean.\",\n \"similarity\": .5\n }\n ] // OR, YOU CAN RETURN AN ARRAY OF DOCUMENTS THAT WILL BE SENT TO THE MODEL\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/TransferAssistantModel" + "$ref": "#/components/schemas/Server" } ] - }, - "firstMessage": { + } + }, + "required": [ + "provider", + "server" + ] + }, + "KnowledgeBase": { + "type": "object", + "properties": { + "name": { "type": "string", - "description": "This is the first message that the transfer assistant will say.\nThis can also be a URL to a custom audio file.\n\nIf unspecified, assistant will wait for user to speak and use the model to respond once they speak.", - "example": "Hello! I understand you need to be transferred. Let me connect you." + "description": "The name of the knowledge base", + "example": "My Knowledge Base" }, - "firstMessageMode": { + "provider": { "type": "string", - "description": "This is the mode for the first message. Default is 'assistant-speaks-first'.\n\nUse:\n- 'assistant-speaks-first' to have the assistant speak first.\n- 'assistant-waits-for-user' to have the assistant wait for the user to speak first.\n- 'assistant-speaks-first-with-model-generated-message' to have the assistant speak first with a message generated by the model based on the conversation state.\n\n@default 'assistant-speaks-first'", + "description": "The provider of the knowledge base", "enum": [ - "assistant-speaks-first", - "assistant-speaks-first-with-model-generated-message", - "assistant-waits-for-user" + "google" ], - "example": "assistant-speaks-first" + "example": "google" }, - "maxDurationSeconds": { - "type": "number", - "description": "This is the maximum duration in seconds for the transfer assistant conversation.\nAfter this time, the transfer will be cancelled automatically.\n@default 120", - "minimum": 10, - "maximum": 43200, - "example": 120 + "model": { + "type": "string", + "description": "The model to use for the knowledge base", + "enum": [ + "gemini-2.5-pro", + "gemini-2.5-flash", + "gemini-2.5-flash-lite", + "gemini-2.0-flash-thinking-exp", + "gemini-2.0-pro-exp-02-05", + "gemini-2.0-flash", + "gemini-2.0-flash-lite", + "gemini-2.0-flash-exp", + "gemini-2.0-flash-realtime-exp", + "gemini-1.5-flash", + "gemini-1.5-flash-002", + "gemini-1.5-pro", + "gemini-1.5-pro-002", + "gemini-1.0-pro" + ] }, - "silenceTimeoutSeconds": { - "type": "number", - "description": "This is the number of seconds of silence to wait before ending the call. Defaults to 30.\n\n@default 30", - "minimum": 10, - "maximum": 3600 + "description": { + "type": "string", + "description": "A description of the knowledge base" + }, + "fileIds": { + "description": "The file IDs associated with this knowledge base", + "type": "array", + "items": { + "type": "string" + } } }, "required": [ - "model" + "name", + "provider", + "description", + "fileIds" ] }, - "TransferCancelToolUserEditable": { + "CreateQueryToolDTO": { "type": "object", "properties": { "messages": { @@ -11479,9 +9778,16 @@ "type": { "type": "string", "enum": [ - "transferCancel" + "query" ], - "description": "The type of tool. \"transferCancel\" for Transfer Cancel tool. This tool can only be used during warm-transfer-experimental by the transfer assistant to cancel an ongoing transfer and return the call back to the original assistant when the transfer cannot be completed." + "description": "The type of tool. \"query\" for Query tool." + }, + "knowledgeBases": { + "description": "The knowledge bases to query", + "type": "array", + "items": { + "$ref": "#/components/schemas/KnowledgeBase" + } }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -11496,7 +9802,7 @@ "type" ] }, - "TransferSuccessfulToolUserEditable": { + "CreateGoogleCalendarCreateEventToolDTO": { "type": "object", "properties": { "messages": { @@ -11526,9 +9832,9 @@ "type": { "type": "string", "enum": [ - "transferSuccessful" + "google.calendar.event.create" ], - "description": "The type of tool. \"transferSuccessful\" for Transfer Successful tool. This tool can only be used during warm-transfer-experimental by the transfer assistant to confirm that the transfer should proceed and finalize the handoff to the destination." + "description": "The type of tool. \"google.calendar.event.create\" for Google Calendar Create Event tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -11543,218 +9849,54 @@ "type" ] }, - "SummaryPlan": { + "CreateGoogleSheetsRowAppendToolDTO": { "type": "object", "properties": { "messages": { - "description": "These are the messages used to generate the summary.\n\n@default: ```\n[\n {\n \"role\": \"system\",\n \"content\": \"You are an expert note-taker. You will be given a transcript of a call. Summarize the call in 2-3 sentences. DO NOT return anything except the summary.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Here is the transcript:\\n\\n{{transcript}}\\n\\n. Here is the ended reason of the call:\\n\\n{{endedReason}}\\n\\n\"\n }\n]```\n\nYou can customize by providing any messages you want.\n\nHere are the template variables available:\n- {{transcript}}: The transcript of the call from `call.artifact.transcript` \n- {{systemPrompt}}: The system prompt of the call from `assistant.model.messages[type=system].content` \n- {{messages}}: The messages of the call from `assistant.model.messages` \n- {{endedReason}}: The ended reason of the call from `call.endedReason`", "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { - "type": "object" + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] } }, - "enabled": { - "type": "boolean", - "description": "This determines whether a summary is generated and stored in `call.analysis.summary`. Defaults to true.\n\nUsage:\n- If you want to disable the summary, set this to false.\n\n@default true" - }, - "timeoutSeconds": { - "type": "number", - "description": "This is how long the request is tried before giving up. When request times out, `call.analysis.summary` will be empty.\n\nUsage:\n- To guarantee the summary is generated, set this value high. Note, this will delay the end of call report in cases where model is slow to respond.\n\n@default 5 seconds", - "minimum": 1, - "maximum": 60 - } - } - }, - "TransferPlan": { - "type": "object", - "properties": { - "mode": { + "type": { "type": "string", - "description": "This configures how transfer is executed and the experience of the destination party receiving the call.\n\nUsage:\n- `blind-transfer`: The assistant forwards the call to the destination without any message or summary.\n- `blind-transfer-add-summary-to-sip-header`: The assistant forwards the call to the destination and adds a SIP header X-Transfer-Summary to the call to include the summary.\n- `warm-transfer-say-message`: The assistant dials the destination, delivers the `message` to the destination party, connects the customer, and leaves the call.\n- `warm-transfer-say-summary`: The assistant dials the destination, provides a summary of the call to the destination party, connects the customer, and leaves the call.\n- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message`: The assistant dials the destination, waits for the operator to speak, delivers the `message` to the destination party, and then connects the customer.\n- `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary`: The assistant dials the destination, waits for the operator to speak, provides a summary of the call to the destination party, and then connects the customer.\n- `warm-transfer-twiml`: The assistant dials the destination, executes the twiml instructions on the destination call leg, connects the customer, and leaves the call.\n- `warm-transfer-experimental`: The assistant puts the customer on hold, dials the destination, and if the destination answers (and is human), delivers a message or summary before connecting the customer. If the destination is unreachable or not human (e.g., with voicemail detection), the assistant delivers the `fallbackMessage` to the customer and optionally ends the call.\n\n@default 'blind-transfer'", - "enum": [ - "blind-transfer", - "blind-transfer-add-summary-to-sip-header", - "warm-transfer-say-message", - "warm-transfer-say-summary", - "warm-transfer-twiml", - "warm-transfer-wait-for-operator-to-speak-first-and-then-say-message", - "warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary", - "warm-transfer-experimental" - ] - }, - "message": { - "description": "This is the message the assistant will deliver to the destination party before connecting the customer.\n\nUsage:\n- Used only when `mode` is `blind-transfer-add-summary-to-sip-header`, `warm-transfer-say-message`, `warm-transfer-wait-for-operator-to-speak-first-and-then-say-message`, or `warm-transfer-experimental`.", - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/CustomMessage" - } - ] - }, - "timeout": { - "type": "number", - "description": "This is the timeout in seconds for the warm-transfer-wait-for-operator-to-speak-first-and-then-say-message/summary\n\n@default 60", - "minimum": 1, - "maximum": 600, - "default": 60 - }, - "sipVerb": { - "type": "object", - "description": "This specifies the SIP verb to use while transferring the call.\n- 'refer': Uses SIP REFER to transfer the call (default)\n- 'bye': Ends current call with SIP BYE\n- 'dial': Uses SIP DIAL to transfer the call", - "default": "refer", "enum": [ - "refer", - "bye", - "dial" - ] - }, - "holdAudioUrl": { - "type": "string", - "description": "This is the URL to an audio file played while the customer is on hold during transfer.\n\nUsage:\n- Used only when `mode` is `warm-transfer-experimental`.\n- Used when transferring calls to play hold audio for the customer.\n- Must be a publicly accessible URL to an audio file.\n- Supported formats: MP3 and WAV.\n- If not provided, the default hold audio will be used." - }, - "transferCompleteAudioUrl": { - "type": "string", - "description": "This is the URL to an audio file played after the warm transfer message or summary is delivered to the destination party.\nIt can be used to play a custom sound like 'beep' to notify that the transfer is complete.\n\nUsage:\n- Used only when `mode` is `warm-transfer-experimental`.\n- Used when transferring calls to play hold audio for the destination party.\n- Must be a publicly accessible URL to an audio file.\n- Supported formats: MP3 and WAV." - }, - "twiml": { - "type": "string", - "description": "This is the TwiML instructions to execute on the destination call leg before connecting the customer.\n\nUsage:\n- Used only when `mode` is `warm-transfer-twiml`.\n- Supports only `Play`, `Say`, `Gather`, `Hangup` and `Pause` verbs.\n- Maximum length is 4096 characters.\n\nExample:\n```\nHello, transferring a customer to you.\n\nThey called about billing questions.\n```", - "maxLength": 4096 - }, - "summaryPlan": { - "description": "This is the plan for generating a summary of the call to present to the destination party.\n\nUsage:\n- Used only when `mode` is `blind-transfer-add-summary-to-sip-header` or `warm-transfer-say-summary` or `warm-transfer-wait-for-operator-to-speak-first-and-then-say-summary` or `warm-transfer-experimental`.", - "allOf": [ - { - "$ref": "#/components/schemas/SummaryPlan" - } - ] - }, - "sipHeadersInReferToEnabled": { - "type": "boolean", - "description": "This flag includes the sipHeaders from above in the refer to sip uri as url encoded query params.\n\n@default false" + "google.sheets.row.append" + ], + "description": "The type of tool. \"google.sheets.row.append\" for Google Sheets Row Append tool." }, - "fallbackPlan": { - "description": "This configures the fallback plan when the transfer fails (destination unreachable, busy, or not human).\n\nUsage:\n- Used only when `mode` is `warm-transfer-experimental`.\n- If not provided when using `warm-transfer-experimental`, a default message will be used.", + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/TransferFallbackPlan" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] } }, "required": [ - "mode" + "type" ] }, - "TransferDestinationNumber": { - "type": "object", - "properties": { - "message": { - "description": "This is spoken to the customer before connecting them to the destination.\n\nUsage:\n- If this is not provided and transfer tool messages is not provided, default is \"Transferring the call now\".\n- If set to \"\", nothing is spoken. This is useful when you want to silently transfer. This is especially useful when transferring between assistants in a squad. In this scenario, you likely also want to set `assistant.firstMessageMode=assistant-speaks-first-with-model-generated-message` for the destination assistant.\n\nThis accepts a string or a ToolMessageStart class. Latter is useful if you want to specify multiple messages for different languages through the `contents` field.", - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/CustomMessage" - } - ] - }, - "type": { - "type": "string", - "enum": [ - "number" - ] - }, - "numberE164CheckEnabled": { - "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true - }, - "number": { - "type": "string", - "description": "This is the phone number to transfer the call to.", - "minLength": 3, - "maxLength": 40 - }, - "extension": { - "type": "string", - "description": "This is the extension to dial after transferring the call to the `number`.", - "minLength": 1, - "maxLength": 10 - }, - "callerId": { - "type": "string", - "description": "This is the caller ID to use when transferring the call to the `number`.\n\nUsage:\n- If not provided, the caller ID will be the number the call is coming from. Example, +14151111111 calls in to and the assistant transfers out to +16470000000. +16470000000 will see +14151111111 as the caller.\n- To change this behavior, provide a `callerId`.\n- Set to '{{customer.number}}' to always use the customer's number as the caller ID.\n- Set to '{{phoneNumber.number}}' to always use the phone number of the assistant as the caller ID.\n- Set to any E164 number to always use that number as the caller ID. This needs to be a number that is owned or verified by your Transport provider like Twilio.\n\nFor Twilio, you can read up more here: https://www.twilio.com/docs/voice/twiml/dial#callerid", - "maxLength": 40 - }, - "transferPlan": { - "description": "This configures how transfer is executed and the experience of the destination party receiving the call. Defaults to `blind-transfer`.\n\n@default `transferPlan.mode='blind-transfer'`", - "allOf": [ - { - "$ref": "#/components/schemas/TransferPlan" - } - ] - }, - "description": { - "type": "string", - "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." - } - }, - "required": [ - "type", - "number" - ] - }, - "TransferDestinationSip": { - "type": "object", - "properties": { - "message": { - "description": "This is spoken to the customer before connecting them to the destination.\n\nUsage:\n- If this is not provided and transfer tool messages is not provided, default is \"Transferring the call now\".\n- If set to \"\", nothing is spoken. This is useful when you want to silently transfer. This is especially useful when transferring between assistants in a squad. In this scenario, you likely also want to set `assistant.firstMessageMode=assistant-speaks-first-with-model-generated-message` for the destination assistant.\n\nThis accepts a string or a ToolMessageStart class. Latter is useful if you want to specify multiple messages for different languages through the `contents` field.", - "oneOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/CustomMessage" - } - ] - }, - "type": { - "type": "string", - "enum": [ - "sip" - ] - }, - "sipUri": { - "type": "string", - "description": "This is the SIP URI to transfer the call to." - }, - "transferPlan": { - "description": "This configures how transfer is executed and the experience of the destination party receiving the call. Defaults to `blind-transfer`.\n\n@default `transferPlan.mode='blind-transfer'`", - "allOf": [ - { - "$ref": "#/components/schemas/TransferPlan" - } - ] - }, - "sipHeaders": { - "type": "object", - "description": "These are custom headers to be added to SIP refer during transfer call." - }, - "description": { - "type": "string", - "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." - } - }, - "required": [ - "type", - "sipUri" - ] - }, - "CreateTransferCallToolDTO": { + "CreateGoogleCalendarCheckAvailabilityToolDTO": { "type": "object", "properties": { "messages": { @@ -11784,28 +9926,9 @@ "type": { "type": "string", "enum": [ - "transferCall" - ] - }, - "destinations": { - "type": "array", - "description": "These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationAssistant", - "title": "Assistant" - }, - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "Number" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "Sip" - } - ] - } + "google.calendar.availability.check" + ], + "description": "The type of tool. \"google.calendar.availability.check\" for Google Calendar Check Availability tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -11820,181 +9943,7 @@ "type" ] }, - "ContextEngineeringPlanLastNMessages": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "lastNMessages" - ] - }, - "maxMessages": { - "type": "number", - "description": "This is the maximum number of messages to include in the context engineering plan.", - "minimum": 0 - } - }, - "required": [ - "type", - "maxMessages" - ] - }, - "ContextEngineeringPlanNone": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "none" - ] - } - }, - "required": [ - "type" - ] - }, - "ContextEngineeringPlanAll": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "all" - ] - } - }, - "required": [ - "type" - ] - }, - "VariableExtractionAlias": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "This is the key of the variable.\n\nThis variable will be accessible during the call as `{{key}}` and stored in `call.artifact.variableValues` after the call.\n\nRules:\n- Must start with a letter (a-z, A-Z).\n- Subsequent characters can be letters, numbers, or underscores.\n- Minimum length of 1 and maximum length of 40.", - "minLength": 1, - "maxLength": 40, - "pattern": "/^[a-zA-Z][a-zA-Z0-9_]*$/" - }, - "value": { - "type": "string", - "description": "This is the value of the variable.\n\nThis can reference existing variables, use filters, and perform transformations.\n\nExamples: \"{{name}}\", \"{{customer.email}}\", \"Hello {{name | upcase}}\"", - "maxLength": 10000 - } - }, - "required": [ - "key", - "value" - ] - }, - "VariableExtractionPlan": { - "type": "object", - "properties": { - "schema": { - "description": "This is the schema to extract.\n\nExamples:\n1. To extract object properties, you can use the following schema:\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n2. To extract nested properties, you can use the following schema:\n```json\n{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"object\",\n \"properties\": {\n \"first\": {\n \"type\": \"string\"\n },\n \"last\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n3. To extract array items, you can use the following schema:\n```json\n{\n \"type\": \"array\",\n \"title\": \"zipCodes\",\n \"items\": {\n \"type\": \"string\"\n }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4. To extract array of objects, you can use the following schema:\n\n```json\n{\n \"type\": \"array\",\n \"name\": \"people\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n },\n \"zipCodes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.", - "allOf": [ - { - "$ref": "#/components/schemas/JsonSchema" - } - ] - }, - "aliases": { - "description": "These are additional variables to create.\n\nThese will be accessible during the call as `{{key}}` and stored in `call.artifact.variableValues` after the call.\n\nExample:\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{name}}\"\n },\n {\n \"key\": \"fullName\",\n \"value\": \"{{firstName}} {{lastName}}\"\n },\n {\n \"key\": \"greeting\",\n \"value\": \"Hello {{name}}, welcome to {{company}}!\"\n },\n {\n \"key\": \"customerCity\",\n \"value\": \"{{addresses[0].city}}\"\n },\n {\n \"key\": \"something\",\n \"value\": \"{{any liquid}}\"\n }\n ]\n}\n```\n\nThis will create variables `customerName`, `fullName`, `greeting`, `customerCity`, and `something`. To access these variables, you can reference them as `{{customerName}}`, `{{fullName}}`, `{{greeting}}`, `{{customerCity}}`, and `{{something}}`.", - "type": "array", - "items": { - "$ref": "#/components/schemas/VariableExtractionAlias" - } - } - } - }, - "HandoffDestinationAssistant": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "assistant" - ] - }, - "contextEngineeringPlan": { - "description": "This is the plan for manipulating the message context before handing off the call to the next assistant.", - "oneOf": [ - { - "$ref": "#/components/schemas/ContextEngineeringPlanLastNMessages", - "title": "Last N Messages" - }, - { - "$ref": "#/components/schemas/ContextEngineeringPlanNone", - "title": "None" - }, - { - "$ref": "#/components/schemas/ContextEngineeringPlanAll", - "title": "All" - } - ] - }, - "assistantName": { - "type": "string", - "description": "This is the assistant to transfer the call to. You must provide either assistantName or assistantId." - }, - "assistantId": { - "type": "string", - "description": "This is the assistant id to transfer the call to. You must provide either assistantName or assistantId." - }, - "assistant": { - "description": "This is a transient assistant to transfer the call to. You may provide a transient assistant in the response `handoff-destination-request` in a dynamic handoff.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "variableExtractionPlan": { - "description": "This is the variable extraction plan for the handoff tool.", - "allOf": [ - { - "$ref": "#/components/schemas/VariableExtractionPlan" - } - ] - }, - "description": { - "type": "string", - "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." - } - }, - "required": [ - "type" - ] - }, - "HandoffDestinationDynamic": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "dynamic" - ] - }, - "server": { - "description": "This is where Vapi will send the handoff-destination-request webhook in a dynamic handoff.\n\nThe order of precedence is:\n\n1. tool.server.url\n2. assistant.server.url\n3. phoneNumber.server.url\n4. org.server.url", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - }, - "description": { - "type": "string", - "description": "This is the description of the destination, used by the AI to choose when and how to transfer the call." - } - }, - "required": [ - "type" - ] - }, - "CreateHandoffToolDTO": { + "CreateSlackSendMessageToolDTO": { "type": "object", "properties": { "messages": { @@ -12023,26 +9972,10 @@ }, "type": { "type": "string", - "description": "This is the type of the tool.\nWhen you're using handoff tool, we recommend adding this to your system prompt\n---\n# System context\n\nYou are part of a multi-agent system designed to make agent coordination and execution easy. Agents uses two primary abstraction: **Agents** and **Handoffs**. An agent encompasses instructions and tools and can hand off a conversation to another agent when appropriate. Handoffs are achieved by calling a handoff function, generally named `handoff_to_`. Handoffs between agents are handled seamlessly in the background; do not mention or draw attention to these handoffs in your conversation with the user.\n\n# Agent context\n\n{put your agent system prompt here}\n---", "enum": [ - "handoff" - ] - }, - "destinations": { - "type": "array", - "description": "These are the destinations that the call can be handed off to.\n\nUsage:\n1. Single destination\n\nUse `assistantId` to handoff the call to a saved assistant, or `assistantName` to handoff the call to an assistant in the same squad.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\", // or \"assistantName\": \"Assistant123\"\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2. Multiple destinations\n\n2.1. Multiple Tools, Each With One Destination (OpenAI recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n ],\n },\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2.2. One Tool, Multiple Destinations (Anthropic recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3. Dynamic destination\n\n3.1 To determine the destination dynamically, supply a `dynamic` handoff destination type and a `server` object.\n VAPI will send a handoff-destination-request webhook to the `server.url`.\n The response from the server will be used as the destination (if valid).\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3.2. To pass custom parameters to the server, you can use the `function` object.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n },\n }\n ],\n \"function\": {\n \"name\": \"handoff\",\n \"description\": \"Call this function when the customer is ready to be handed off to the next assistant\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"destination\": {\n \"type\": \"string\",\n \"description\": \"Use dynamic when customer is ready to be handed off to the next assistant\",\n \"enum\": [\"dynamic\"]\n },\n \"customerAreaCode\": {\n \"type\": \"number\",\n \"description\": \"Area code of the customer\"\n },\n \"customerIntent\": {\n \"type\": \"string\",\n \"enum\": [\"new-customer\", \"existing-customer\"],\n \"description\": \"Use new-customer when customer is a new customer, existing-customer when customer is an existing customer\"\n },\n \"customerSentiment\": {\n \"type\": \"string\",\n \"enum\": [\"positive\", \"negative\", \"neutral\"],\n \"description\": \"Use positive when customer is happy, negative when customer is unhappy, neutral when customer is neutral\"\n }\n }\n }\n }\n }\n ]\n}\n```\n\nThe properties `customerAreaCode`, `customerIntent`, and `customerSentiment` will be passed to the server in the webhook request body.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/HandoffDestinationAssistant", - "title": "Assistant" - }, - { - "$ref": "#/components/schemas/HandoffDestinationDynamic", - "title": "Dynamic" - } - ] - } + "slack.message.send" + ], + "description": "The type of tool. \"slack.message.send\" for Slack Send Message tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -12057,86 +9990,20 @@ "type" ] }, - "CreateCustomKnowledgeBaseDTO": { - "type": "object", - "properties": { - "provider": { - "type": "string", - "description": "This knowledge base is bring your own knowledge base implementation.", - "enum": [ - "custom-knowledge-base" - ] - }, - "server": { - "description": "This is where the knowledge base request will be sent.\n\nRequest Example:\n\nPOST https://{server.url}\nContent-Type: application/json\n\n{\n \"messsage\": {\n \"type\": \"knowledge-base-request\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Why is ocean blue?\"\n }\n ],\n ...other metadata about the call...\n }\n}\n\nResponse Expected:\n```\n{\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"The ocean is blue because water absorbs everything but blue.\",\n }, // YOU CAN RETURN THE EXACT RESPONSE TO SPEAK\n \"documents\": [\n {\n \"content\": \"The ocean is blue primarily because water absorbs colors in the red part of the light spectrum and scatters the blue light, making it more visible to our eyes.\",\n \"similarity\": 1\n },\n {\n \"content\": \"Blue light is scattered more by the water molecules than other colors, enhancing the blue appearance of the ocean.\",\n \"similarity\": .5\n }\n ] // OR, YOU CAN RETURN AN ARRAY OF DOCUMENTS THAT WILL BE SENT TO THE MODEL\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - } - }, - "required": [ - "provider", - "server" - ] - }, - "KnowledgeBase": { + "McpToolMetadata": { "type": "object", "properties": { - "name": { - "type": "string", - "description": "The name of the knowledge base", - "example": "My Knowledge Base" - }, - "provider": { + "protocol": { "type": "string", - "description": "The provider of the knowledge base", "enum": [ - "google" + "sse", + "shttp" ], - "example": "google" - }, - "model": { - "type": "string", - "description": "The model to use for the knowledge base", - "enum": [ - "gemini-2.5-pro", - "gemini-2.5-flash", - "gemini-2.5-flash-lite", - "gemini-2.0-flash-thinking-exp", - "gemini-2.0-pro-exp-02-05", - "gemini-2.0-flash", - "gemini-2.0-flash-lite", - "gemini-2.0-flash-exp", - "gemini-2.0-flash-realtime-exp", - "gemini-1.5-flash", - "gemini-1.5-flash-002", - "gemini-1.5-pro", - "gemini-1.5-pro-002", - "gemini-1.0-pro" - ] - }, - "description": { - "type": "string", - "description": "A description of the knowledge base" - }, - "fileIds": { - "description": "The file IDs associated with this knowledge base", - "type": "array", - "items": { - "type": "string" - } + "description": "This is the protocol used for MCP communication. Defaults to Streamable HTTP." } - }, - "required": [ - "name", - "provider", - "description", - "fileIds" - ] + } }, - "CreateQueryToolDTO": { + "CreateMcpToolDTO": { "type": "object", "properties": { "messages": { @@ -12166,16 +10033,20 @@ "type": { "type": "string", "enum": [ - "query" + "mcp" ], - "description": "The type of tool. \"query\" for Query tool." + "description": "The type of tool. \"mcp\" for MCP tool." }, - "knowledgeBases": { - "description": "The knowledge bases to query", - "type": "array", - "items": { - "$ref": "#/components/schemas/KnowledgeBase" - } + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "allOf": [ + { + "$ref": "#/components/schemas/Server" + } + ] + }, + "metadata": { + "$ref": "#/components/schemas/McpToolMetadata" }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -12190,7 +10061,7 @@ "type" ] }, - "CreateGoogleCalendarCreateEventToolDTO": { + "CreateGoHighLevelCalendarAvailabilityToolDTO": { "type": "object", "properties": { "messages": { @@ -12220,9 +10091,9 @@ "type": { "type": "string", "enum": [ - "google.calendar.event.create" + "gohighlevel.calendar.availability.check" ], - "description": "The type of tool. \"google.calendar.event.create\" for Google Calendar Create Event tool." + "description": "The type of tool. \"gohighlevel.calendar.availability.check\" for GoHighLevel Calendar Availability Check tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -12237,7 +10108,7 @@ "type" ] }, - "CreateGoogleSheetsRowAppendToolDTO": { + "CreateGoHighLevelCalendarEventCreateToolDTO": { "type": "object", "properties": { "messages": { @@ -12267,9 +10138,9 @@ "type": { "type": "string", "enum": [ - "google.sheets.row.append" + "gohighlevel.calendar.event.create" ], - "description": "The type of tool. \"google.sheets.row.append\" for Google Sheets Row Append tool." + "description": "The type of tool. \"gohighlevel.calendar.event.create\" for GoHighLevel Calendar Event Create tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -12284,7 +10155,7 @@ "type" ] }, - "CreateGoogleCalendarCheckAvailabilityToolDTO": { + "CreateGoHighLevelContactCreateToolDTO": { "type": "object", "properties": { "messages": { @@ -12314,9 +10185,9 @@ "type": { "type": "string", "enum": [ - "google.calendar.availability.check" + "gohighlevel.contact.create" ], - "description": "The type of tool. \"google.calendar.availability.check\" for Google Calendar Check Availability tool." + "description": "The type of tool. \"gohighlevel.contact.create\" for GoHighLevel Contact Create tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -12331,7 +10202,7 @@ "type" ] }, - "CreateSlackSendMessageToolDTO": { + "CreateGoHighLevelContactGetToolDTO": { "type": "object", "properties": { "messages": { @@ -12361,9 +10232,9 @@ "type": { "type": "string", "enum": [ - "slack.message.send" + "gohighlevel.contact.get" ], - "description": "The type of tool. \"slack.message.send\" for Slack Send Message tool." + "description": "The type of tool. \"gohighlevel.contact.get\" for GoHighLevel Contact Get tool." }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", @@ -12378,291 +10249,56 @@ "type" ] }, - "McpToolMetadata": { + "OpenAIMessage": { "type": "object", "properties": { - "protocol": { + "content": { + "type": "string", + "nullable": true, + "maxLength": 100000000 + }, + "role": { "type": "string", "enum": [ - "sse", - "shttp" - ], - "description": "This is the protocol used for MCP communication. Defaults to Streamable HTTP." + "assistant", + "function", + "user", + "system", + "tool" + ] } - } + }, + "required": [ + "content", + "role" + ] }, - "CreateMcpToolDTO": { + "AnyscaleModel": { "type": "object", "properties": { "messages": { + "description": "This is the starting state for the conversation.", "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "$ref": "#/components/schemas/OpenAIMessage" + } + }, + "tools": { + "type": "array", + "description": "These are the tools that the assistant can use during the call. To use existing tools, use `toolIds`.\n\nBoth `tools` and `toolIds` can be used together.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" + "$ref": "#/components/schemas/CreateApiRequestToolDTO", + "title": "ApiRequestTool" }, { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" + "$ref": "#/components/schemas/CreateBashToolDTO", + "title": "BashTool" }, { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "mcp" - ], - "description": "The type of tool. \"mcp\" for MCP tool." - }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - }, - "metadata": { - "$ref": "#/components/schemas/McpToolMetadata" - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] - } - }, - "required": [ - "type" - ] - }, - "CreateGoHighLevelCalendarAvailabilityToolDTO": { - "type": "object", - "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "gohighlevel.calendar.availability.check" - ], - "description": "The type of tool. \"gohighlevel.calendar.availability.check\" for GoHighLevel Calendar Availability Check tool." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] - } - }, - "required": [ - "type" - ] - }, - "CreateGoHighLevelCalendarEventCreateToolDTO": { - "type": "object", - "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "gohighlevel.calendar.event.create" - ], - "description": "The type of tool. \"gohighlevel.calendar.event.create\" for GoHighLevel Calendar Event Create tool." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] - } - }, - "required": [ - "type" - ] - }, - "CreateGoHighLevelContactCreateToolDTO": { - "type": "object", - "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "gohighlevel.contact.create" - ], - "description": "The type of tool. \"gohighlevel.contact.create\" for GoHighLevel Contact Create tool." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] - } - }, - "required": [ - "type" - ] - }, - "CreateGoHighLevelContactGetToolDTO": { - "type": "object", - "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "gohighlevel.contact.get" - ], - "description": "The type of tool. \"gohighlevel.contact.get\" for GoHighLevel Contact Get tool." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] - } - }, - "required": [ - "type" - ] - }, - "AnyscaleModel": { - "type": "object", - "properties": { - "messages": { - "description": "This is the starting state for the conversation.", - "type": "array", - "items": { - "$ref": "#/components/schemas/OpenAIMessage" - } - }, - "tools": { - "type": "array", - "description": "These are the tools that the assistant can use during the call. To use existing tools, use `toolIds`.\n\nBoth `tools` and `toolIds` can be used together.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/CreateApiRequestToolDTO", - "title": "ApiRequestTool" - }, - { - "$ref": "#/components/schemas/CreateBashToolDTO", - "title": "BashTool" - }, - { - "$ref": "#/components/schemas/CreateComputerToolDTO", - "title": "ComputerTool" + "$ref": "#/components/schemas/CreateComputerToolDTO", + "title": "ComputerTool" }, { "$ref": "#/components/schemas/CreateDtmfToolDTO", @@ -12751,10 +10387,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "enum": [ @@ -12927,10 +10559,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "The specific Anthropic/Claude model that will be used.", @@ -13102,10 +10730,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "This is the name of the model. Ex. cognitivecomputations/dolphin-mixtral-8x7b", @@ -13261,10 +10885,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "description": "This is the provider that will be used for the model. Any service, including your own server, that is compatible with the OpenAI API can be used.", @@ -13447,10 +11067,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "enum": [ @@ -13602,10 +11218,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "This is the name of the model. Ex. cognitivecomputations/dolphin-mixtral-8x7b", @@ -13830,10 +11442,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "This is the Google model that will be used.", @@ -14009,10 +11617,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "This is the name of the model. Ex. cognitivecomputations/dolphin-mixtral-8x7b", @@ -14180,10 +11784,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "This is the name of the model. Ex. cognitivecomputations/dolphin-mixtral-8x7b", @@ -14338,10 +11938,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "description": "This is the provider that will be used for the model.", @@ -14371,6 +11967,7 @@ "gpt-4o-realtime-preview-2024-10-01", "gpt-4o-realtime-preview-2024-12-17", "gpt-4o-mini-realtime-preview-2024-12-17", + "gpt-realtime-2025-08-28", "gpt-4o-mini-2024-07-18", "gpt-4o-mini", "gpt-4o", @@ -14473,6 +12070,7 @@ "gpt-4o-realtime-preview-2024-10-01", "gpt-4o-realtime-preview-2024-12-17", "gpt-4o-mini-realtime-preview-2024-12-17", + "gpt-realtime-2025-08-28", "gpt-4o-mini-2024-07-18", "gpt-4o-mini", "gpt-4o", @@ -14577,6 +12175,7 @@ "gpt-4o-realtime-preview-2024-10-01", "gpt-4o-realtime-preview-2024-12-17", "gpt-4o-mini-realtime-preview-2024-12-17", + "gpt-realtime-2025-08-28", "gpt-4o-mini-2024-07-18", "gpt-4o-mini", "gpt-4o", @@ -14807,10 +12406,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "enum": [ @@ -14962,10 +12557,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "enum": [ @@ -15117,10 +12708,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "enum": [ @@ -16138,6 +13725,100 @@ } } }, + "TranscriptPlan": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "This determines whether the transcript is stored in `call.artifact.transcript`. Defaults to true.\n\n@default true", + "example": true + }, + "assistantName": { + "type": "string", + "description": "This is the name of the assistant in the transcript. Defaults to 'AI'.\n\nUsage:\n- If you want to change the name of the assistant in the transcript, set this. Example, here is what the transcript would look like with `assistantName` set to 'Buyer':\n```\nUser: Hello, how are you?\nBuyer: I'm fine.\nUser: Do you want to buy a car?\nBuyer: No.\n```\n\n@default 'AI'" + }, + "userName": { + "type": "string", + "description": "This is the name of the user in the transcript. Defaults to 'User'.\n\nUsage:\n- If you want to change the name of the user in the transcript, set this. Example, here is what the transcript would look like with `userName` set to 'Seller':\n```\nSeller: Hello, how are you?\nAI: I'm fine.\nSeller: Do you want to buy a car?\nAI: No.\n```\n\n@default 'User'" + } + } + }, + "ArtifactPlan": { + "type": "object", + "properties": { + "recordingEnabled": { + "type": "boolean", + "description": "This determines whether assistant's calls are recorded. Defaults to true.\n\nUsage:\n- If you don't want to record the calls, set this to false.\n- If you want to record the calls when `assistant.hipaaEnabled` (deprecated) or `assistant.compliancePlan.hipaaEnabled` explicity set this to true and make sure to provide S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nYou can find the recording at `call.artifact.recordingUrl` and `call.artifact.stereoRecordingUrl` after the call is ended.\n\n@default true", + "example": true + }, + "recordingFormat": { + "type": "string", + "description": "This determines the format of the recording. Defaults to `wav;l16`.\n\n@default 'wav;l16'", + "enum": [ + "wav;l16", + "mp3" + ] + }, + "recordingUseCustomStorageEnabled": { + "type": "boolean", + "description": "This determines whether to use custom storage (S3 or GCP) for call recordings when storage credentials are configured.\n\nWhen set to false, recordings will be stored on Vapi's storage instead of your custom storage, even if you have custom storage credentials configured.\n\nUsage:\n- Set to false if you have custom storage configured but want to store recordings on Vapi's storage for this assistant.\n- Set to true (or leave unset) to use your custom storage for recordings when available.\n\n@default true", + "example": true + }, + "videoRecordingEnabled": { + "type": "boolean", + "description": "This determines whether the video is recorded during the call. Defaults to false. Only relevant for `webCall` type.\n\nYou can find the video recording at `call.artifact.videoRecordingUrl` after the call is ended.\n\n@default false", + "example": false + }, + "pcapEnabled": { + "type": "boolean", + "description": "This determines whether the SIP packet capture is enabled. Defaults to true. Only relevant for `phone` type calls where phone number's provider is `vapi` or `byo-phone-number`.\n\nYou can find the packet capture at `call.artifact.pcapUrl` after the call is ended.\n\n@default true", + "example": true + }, + "pcapS3PathPrefix": { + "type": "string", + "description": "This is the path where the SIP packet capture will be uploaded. This is only used if you have provided S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nIf credential.s3PathPrefix or credential.bucketPlan.path is set, this will append to it.\n\nUsage:\n- If you want to upload the packet capture to a specific path, set this to the path. Example: `/my-assistant-captures`.\n- If you want to upload the packet capture to the root of the bucket, set this to `/`.\n\n@default '/'", + "example": "/pcaps" + }, + "pcapUseCustomStorageEnabled": { + "type": "boolean", + "description": "This determines whether to use custom storage (S3 or GCP) for SIP packet captures when storage credentials are configured.\n\nWhen set to false, packet captures will be stored on Vapi's storage instead of your custom storage, even if you have custom storage credentials configured.\n\nUsage:\n- Set to false if you have custom storage configured but want to store packet captures on Vapi's storage for this assistant.\n- Set to true (or leave unset) to use your custom storage for packet captures when available.\n\n@default true", + "example": true + }, + "loggingEnabled": { + "type": "boolean", + "description": "This determines whether the call logs are enabled. Defaults to true.\n\n@default true", + "example": true + }, + "loggingUseCustomStorageEnabled": { + "type": "boolean", + "description": "This determines whether to use custom storage (S3 or GCP) for call logs when storage credentials are configured.\n\nWhen set to false, logs will be stored on Vapi's storage instead of your custom storage, even if you have custom storage credentials configured.\n\nUsage:\n- Set to false if you have custom storage configured but want to store logs on Vapi's storage for this assistant.\n- Set to true (or leave unset) to use your custom storage for logs when available.\n\n@default true", + "example": true + }, + "transcriptPlan": { + "description": "This is the plan for `call.artifact.transcript`. To disable, set `transcriptPlan.enabled` to false.", + "allOf": [ + { + "$ref": "#/components/schemas/TranscriptPlan" + } + ] + }, + "recordingPath": { + "type": "string", + "description": "This is the path where the recording will be uploaded. This is only used if you have provided S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nIf credential.s3PathPrefix or credential.bucketPlan.path is set, this will append to it.\n\nUsage:\n- If you want to upload the recording to a specific path, set this to the path. Example: `/my-assistant-recordings`.\n- If you want to upload the recording to the root of the bucket, set this to `/`.\n\n@default '/'" + }, + "structuredOutputIds": { + "description": "This is an array of structured output IDs to be calculated during the call.\nThe outputs will be extracted and stored in `call.artifact.structuredOutputs` after the call is ended.", + "type": "array", + "items": { + "type": "string" + } + }, + "loggingPath": { + "type": "string", + "description": "This is the path where the call logs will be uploaded. This is only used if you have provided S3 or GCP credentials on the Provider Credentials page in the Dashboard.\n\nIf credential.s3PathPrefix or credential.bucketPlan.path is set, this will append to it.\n\nUsage:\n- If you want to upload the call logs to a specific path, set this to the path. Example: `/my-assistant-logs`.\n- If you want to upload the call logs to the root of the bucket, set this to `/`.\n\n@default '/'" + } + } + }, "RegexOption": { "type": "object", "properties": { @@ -17094,6 +14775,10 @@ "$ref": "#/components/schemas/CreateWebhookCredentialDTO", "title": "WebhookCredential" }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, { "$ref": "#/components/schemas/CreateXAiCredentialDTO", "title": "XAiCredential" @@ -17163,6 +14848,7 @@ "twilio": "#/components/schemas/CreateTwilioCredentialDTO", "vonage": "#/components/schemas/CreateVonageCredentialDTO", "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", "xai": "#/components/schemas/CreateXAiCredentialDTO", "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", "hume": "#/components/schemas/CreateHumeCredentialDTO", @@ -17394,10 +15080,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "provider": { "type": "string", "enum": [ @@ -17561,10 +15243,6 @@ } ] }, - "knowledgeBaseId": { - "type": "string", - "description": "This is the ID of the knowledge base the model will use." - }, "model": { "type": "string", "description": "This is the name of the model. Ex. cognitivecomputations/dolphin-mixtral-8x7b", @@ -19084,7 +16762,9 @@ "fable", "onyx", "nova", - "shimmer" + "shimmer", + "marin", + "cedar" ], "title": "Preset Voice Options" }, @@ -21068,7 +18748,9 @@ "fable", "onyx", "nova", - "shimmer" + "shimmer", + "marin", + "cedar" ], "title": "Preset Voice Options" }, @@ -23363,20 +21045,24 @@ ] }, "authenticationPlan": { - "description": "This is the authentication plan. Supports OAuth2 RFC 6749 and HMAC signing.", + "description": "This is the authentication plan. Supports OAuth2 RFC 6749, HMAC signing, and Bearer authentication.", "oneOf": [ { "$ref": "#/components/schemas/OAuth2AuthenticationPlan" }, { "$ref": "#/components/schemas/HMACAuthenticationPlan" + }, + { + "$ref": "#/components/schemas/BearerAuthenticationPlan" } ], "discriminator": { "propertyName": "type", "mapping": { "oauth2": "#/components/schemas/OAuth2AuthenticationPlan", - "hmac": "#/components/schemas/HMACAuthenticationPlan" + "hmac": "#/components/schemas/HMACAuthenticationPlan", + "bearer": "#/components/schemas/BearerAuthenticationPlan" } } }, @@ -24898,6 +22584,10 @@ "$ref": "#/components/schemas/CreateWebhookCredentialDTO", "title": "WebhookCredential" }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, { "$ref": "#/components/schemas/CreateXAiCredentialDTO", "title": "XAiCredential" @@ -24967,6 +22657,7 @@ "twilio": "#/components/schemas/CreateTwilioCredentialDTO", "vonage": "#/components/schemas/CreateVonageCredentialDTO", "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", "xai": "#/components/schemas/CreateXAiCredentialDTO", "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", "hume": "#/components/schemas/CreateHumeCredentialDTO", @@ -25107,7 +22798,7 @@ } } }, - "AssistantOverrides": { + "Assistant": { "type": "object", "properties": { "transcriber": { @@ -25690,6 +23381,10 @@ "$ref": "#/components/schemas/CreateWebhookCredentialDTO", "title": "WebhookCredential" }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, { "$ref": "#/components/schemas/CreateXAiCredentialDTO", "title": "XAiCredential" @@ -25759,6 +23454,7 @@ "twilio": "#/components/schemas/CreateTwilioCredentialDTO", "vonage": "#/components/schemas/CreateVonageCredentialDTO", "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", "xai": "#/components/schemas/CreateXAiCredentialDTO", "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", "hume": "#/components/schemas/CreateHumeCredentialDTO", @@ -25800,10 +23496,6 @@ ] } }, - "variableValues": { - "type": "object", - "description": "These are values that will be used to replace the template variables in the assistant messages and other text-based fields.\nThis uses LiquidJS syntax. https://liquidjs.com/tutorials/intro-to-liquid.html\n\nSo for example, `{{ name }}` will be replaced with the value of `name` in `variableValues`.\n`{{\"now\" | date: \"%b %d, %Y, %I:%M %p\", \"America/New_York\"}}` will be replaced with the current date and time in New York.\n Some VAPI reserved defaults:\n - *customer* - the customer object" - }, "name": { "type": "string", "description": "This is the name of the assistant.\n\nThis is required when you want to transfer between assistants in a call.", @@ -25900,119 +23592,96 @@ }, "keypadInputPlan": { "$ref": "#/components/schemas/KeypadInputPlan" + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the assistant." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the org that this assistant belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the assistant was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the assistant was last updated." } - } + }, + "required": [ + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "SquadMemberDTO": { + "PaginationMeta": { "type": "object", "properties": { - "assistantDestinations": { - "type": "array", - "description": "These are the other assistants that this assistant can transfer or handoff to.\n\nSupports both:\n- TransferDestinationAssistant: For transfer call tool (legacy)\n- HandoffDestinationAssistant: For handoff tool (recommended)\n\nIf the assistant already has transfer call or handoff tools, these destinations are just appended to existing ones.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationAssistant", - "title": "Transfer Destination" - }, - { - "$ref": "#/components/schemas/HandoffDestinationAssistant", - "title": "Handoff Destination" - } - ] - } + "itemsPerPage": { + "type": "number" }, - "assistantId": { - "type": "string", - "nullable": true, - "description": "This is the assistant that will be used for the call. To use a transient assistant, use `assistant` instead." + "totalItems": { + "type": "number" }, - "assistant": { - "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] + "currentPage": { + "type": "number" }, - "assistantOverrides": { - "description": "This can be used to override the assistant's settings and provide values for it's template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] + "itemsBeyondRetention": { + "type": "boolean" } - } + }, + "required": [ + "itemsPerPage", + "totalItems", + "currentPage" + ] }, - "CreateSquadDTO": { + "AssistantPaginatedResponse": { "type": "object", "properties": { - "name": { - "type": "string", - "description": "This is the name of the squad." - }, - "members": { - "description": "This is the list of assistants that make up the squad.\n\nThe call will start with the first assistant in the list.", + "results": { "type": "array", "items": { - "$ref": "#/components/schemas/SquadMemberDTO" + "$ref": "#/components/schemas/Assistant" } }, - "membersOverrides": { - "description": "This can be used to override all the assistants' settings and provide values for their template variables.\n\nBoth `membersOverrides` and `members[n].assistantOverrides` can be used together. First, `members[n].assistantOverrides` is applied. Then, `membersOverrides` is applied as a global override.", - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" } }, "required": [ - "members" + "results", + "metadata" ] }, - "CreateWorkflowDTO": { + "AssistantVersionPaginatedResponse": { "type": "object", "properties": { - "nodes": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ConversationNode", - "title": "ConversationNode" - }, - { - "$ref": "#/components/schemas/ToolNode", - "title": "ToolNode" - } - ] - } + "results": { + "type": "array" }, - "model": { - "description": "This is the model for the workflow.\n\nThis can be overridden at node level using `nodes[n].model`.", - "oneOf": [ - { - "$ref": "#/components/schemas/WorkflowOpenAIModel", - "title": "WorkflowOpenAIModel" - }, - { - "$ref": "#/components/schemas/WorkflowAnthropicModel", - "title": "WorkflowAnthropicModel" - }, - { - "$ref": "#/components/schemas/WorkflowGoogleModel", - "title": "WorkflowGoogleModel" - }, - { - "$ref": "#/components/schemas/WorkflowCustomModel", - "title": "WorkflowCustomModel" - } - ] + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" }, + "nextPageState": { + "type": "string" + } + }, + "required": [ + "results", + "metadata" + ] + }, + "UpdateAssistantDTO": { + "type": "object", + "properties": { "transcriber": { - "description": "This is the transcriber for the workflow.\n\nThis can be overridden at node level using `nodes[n].transcriber`.", + "description": "These are the options for the assistant's transcriber.", "oneOf": [ { "$ref": "#/components/schemas/AssemblyAITranscriber", @@ -26060,8 +23729,69 @@ } ] }, + "model": { + "description": "These are the options for the assistant's LLM.", + "oneOf": [ + { + "$ref": "#/components/schemas/AnthropicModel", + "title": "Anthropic" + }, + { + "$ref": "#/components/schemas/AnyscaleModel", + "title": "Anyscale" + }, + { + "$ref": "#/components/schemas/CerebrasModel", + "title": "Cerebras" + }, + { + "$ref": "#/components/schemas/CustomLLMModel", + "title": "CustomLLM" + }, + { + "$ref": "#/components/schemas/DeepInfraModel", + "title": "DeepInfra" + }, + { + "$ref": "#/components/schemas/DeepSeekModel", + "title": "DeepSeek" + }, + { + "$ref": "#/components/schemas/GoogleModel", + "title": "Google" + }, + { + "$ref": "#/components/schemas/GroqModel", + "title": "Groq" + }, + { + "$ref": "#/components/schemas/InflectionAIModel", + "title": "InflectionAI" + }, + { + "$ref": "#/components/schemas/OpenAIModel", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/OpenRouterModel", + "title": "OpenRouter" + }, + { + "$ref": "#/components/schemas/PerplexityAIModel", + "title": "PerplexityAI" + }, + { + "$ref": "#/components/schemas/TogetherAIModel", + "title": "Together" + }, + { + "$ref": "#/components/schemas/XaiModel", + "title": "XAI" + } + ] + }, "voice": { - "description": "This is the voice for the workflow.\n\nThis can be overridden at node level using `nodes[n].voice`.", + "description": "These are the options for the assistant's voice.", "oneOf": [ { "$ref": "#/components/schemas/AzureVoice", @@ -26133,20 +23863,181 @@ } ] }, - "observabilityPlan": { - "description": "This is the plan for observability of workflow's calls.\n\nCurrently, only Langfuse is supported.", + "firstMessage": { + "type": "string", + "description": "This is the first message that the assistant will say. This can also be a URL to a containerized audio file (mp3, wav, etc.).\n\nIf unspecified, assistant will wait for user to speak and use the model to respond once they speak.", + "example": "Hello! How can I help you today?" + }, + "firstMessageInterruptionsEnabled": { + "type": "boolean", + "default": false + }, + "firstMessageMode": { + "type": "string", + "description": "This is the mode for the first message. Default is 'assistant-speaks-first'.\n\nUse:\n- 'assistant-speaks-first' to have the assistant speak first.\n- 'assistant-waits-for-user' to have the assistant wait for the user to speak first.\n- 'assistant-speaks-first-with-model-generated-message' to have the assistant speak first with a message generated by the model based on the conversation state. (`assistant.model.messages` at call start, `call.messages` at squad transfer points).\n\n@default 'assistant-speaks-first'", + "enum": [ + "assistant-speaks-first", + "assistant-speaks-first-with-model-generated-message", + "assistant-waits-for-user" + ], + "example": "assistant-speaks-first" + }, + "voicemailDetection": { + "description": "These are the settings to configure or disable voicemail detection. Alternatively, voicemail detection can be configured using the model.tools=[VoicemailTool].\nThis uses Twilio's built-in detection while the VoicemailTool relies on the model to detect if a voicemail was reached.\nYou can use neither of them, one of them, or both of them. By default, Twilio built-in detection is enabled while VoicemailTool is not.", "oneOf": [ { - "$ref": "#/components/schemas/LangfuseObservabilityPlan", - "title": "Langfuse" - } - ], - "allOf": [ + "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", + "title": "Google" + }, { - "$ref": "#/components/schemas/LangfuseObservabilityPlan" + "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", + "title": "Twilio" + }, + { + "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", + "title": "Vapi" } ] }, + "clientMessages": { + "type": "array", + "enum": [ + "conversation-update", + "function-call", + "function-call-result", + "hang", + "language-changed", + "metadata", + "model-output", + "speech-update", + "status-update", + "transcript", + "tool-calls", + "tool-calls-result", + "tool.completed", + "transfer-update", + "user-interrupted", + "voice-input", + "workflow.node.started" + ], + "example": [ + "conversation-update", + "function-call", + "hang", + "model-output", + "speech-update", + "status-update", + "transfer-update", + "transcript", + "tool-calls", + "user-interrupted", + "voice-input", + "workflow.node.started" + ], + "description": "These are the messages that will be sent to your Client SDKs. Default is conversation-update,function-call,hang,model-output,speech-update,status-update,transfer-update,transcript,tool-calls,user-interrupted,voice-input,workflow.node.started. You can check the shape of the messages in ClientMessage schema.", + "items": { + "type": "string", + "enum": [ + "conversation-update", + "function-call", + "function-call-result", + "hang", + "language-changed", + "metadata", + "model-output", + "speech-update", + "status-update", + "transcript", + "tool-calls", + "tool-calls-result", + "tool.completed", + "transfer-update", + "user-interrupted", + "voice-input", + "workflow.node.started" + ] + } + }, + "serverMessages": { + "type": "array", + "enum": [ + "conversation-update", + "end-of-call-report", + "function-call", + "hang", + "language-changed", + "language-change-detected", + "model-output", + "phone-call-control", + "speech-update", + "status-update", + "transcript", + "transcript[transcriptType=\"final\"]", + "tool-calls", + "transfer-destination-request", + "handoff-destination-request", + "transfer-update", + "user-interrupted", + "voice-input", + "chat.created", + "chat.deleted", + "session.created", + "session.updated", + "session.deleted" + ], + "example": [ + "conversation-update", + "end-of-call-report", + "function-call", + "hang", + "speech-update", + "status-update", + "tool-calls", + "transfer-destination-request", + "handoff-destination-request", + "user-interrupted" + ], + "description": "These are the messages that will be sent to your Server URL. Default is conversation-update,end-of-call-report,function-call,hang,speech-update,status-update,tool-calls,transfer-destination-request,handoff-destination-request,user-interrupted. You can check the shape of the messages in ServerMessage schema.", + "items": { + "type": "string", + "enum": [ + "conversation-update", + "end-of-call-report", + "function-call", + "hang", + "language-changed", + "language-change-detected", + "model-output", + "phone-call-control", + "speech-update", + "status-update", + "transcript", + "transcript[transcriptType=\"final\"]", + "tool-calls", + "transfer-destination-request", + "handoff-destination-request", + "transfer-update", + "user-interrupted", + "voice-input", + "chat.created", + "chat.deleted", + "session.created", + "session.updated", + "session.deleted" + ] + } + }, + "maxDurationSeconds": { + "type": "number", + "description": "This is the maximum number of seconds that the call will last. When the call reaches this duration, it will be ended.\n\n@default 600 (10 minutes)", + "minimum": 10, + "maximum": 43200, + "example": 600 + }, "backgroundSound": { "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", "oneOf": [ @@ -26165,33 +24056,40 @@ } ] }, - "hooks": { + "modelOutputInMessagesEnabled": { + "type": "boolean", + "description": "This determines whether the model's output is used in conversation history rather than the transcription of assistant's speech.\n\nDefault `false` while in beta.\n\n@default false", + "example": false + }, + "transportConfigurations": { "type": "array", - "description": "This is a set of actions that will be performed on certain events.", + "description": "These are the configurations to be passed to the transport providers of assistant's calls, like Twilio. You can store multiple configurations for different transport providers. For a call, only the configuration matching the call transport provider is used.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/CallHookCallEnding", - "title": "CallHookCallEnding" - }, - { - "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", - "title": "CallHookAssistantSpeechInterrupted" - }, - { - "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", - "title": "CallHookCustomerSpeechInterrupted" - }, - { - "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", - "title": "CallHookCustomerSpeechTimeout" + "$ref": "#/components/schemas/TransportConfigurationTwilio", + "title": "Twilio" } ] } }, + "observabilityPlan": { + "description": "This is the plan for observability of assistant's calls.\n\nCurrently, only Langfuse is supported.", + "oneOf": [ + { + "$ref": "#/components/schemas/LangfuseObservabilityPlan", + "title": "Langfuse" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/LangfuseObservabilityPlan" + } + ] + }, "credentials": { "type": "array", - "description": "These are dynamic credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", + "description": "These are dynamic credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", "items": { "oneOf": [ { @@ -26362,6 +24260,10 @@ "$ref": "#/components/schemas/CreateWebhookCredentialDTO", "title": "WebhookCredential" }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, { "$ref": "#/components/schemas/CreateXAiCredentialDTO", "title": "XAiCredential" @@ -26431,6 +24333,7 @@ "twilio": "#/components/schemas/CreateTwilioCredentialDTO", "vonage": "#/components/schemas/CreateVonageCredentialDTO", "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", "xai": "#/components/schemas/CreateXAiCredentialDTO", "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", "hume": "#/components/schemas/CreateHumeCredentialDTO", @@ -26448,38 +24351,71 @@ } } }, + "hooks": { + "type": "array", + "description": "This is a set of actions that will be performed on certain events.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/CallHookCallEnding", + "title": "CallHookCallEnding" + }, + { + "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", + "title": "CallHookAssistantSpeechInterrupted" + }, + { + "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", + "title": "CallHookCustomerSpeechInterrupted" + }, + { + "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", + "title": "CallHookCustomerSpeechTimeout" + } + ] + } + }, "name": { "type": "string", - "maxLength": 80 + "description": "This is the name of the assistant.\n\nThis is required when you want to transfer between assistants in a call.", + "maxLength": 40 }, - "edges": { + "voicemailMessage": { + "type": "string", + "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", + "maxLength": 1000 + }, + "endCallMessage": { + "type": "string", + "description": "This is the message that the assistant will say if it ends the call.\n\nIf unspecified, it will hang up without saying anything.", + "maxLength": 1000 + }, + "endCallPhrases": { + "description": "This list contains phrases that, if spoken by the assistant, will trigger the call to be hung up. Case insensitive.", "type": "array", "items": { - "$ref": "#/components/schemas/Edge" + "type": "string", + "maxLength": 140, + "minLength": 2 } }, - "globalPrompt": { - "type": "string", - "maxLength": 5000 + "compliancePlan": { + "$ref": "#/components/schemas/CompliancePlan" }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. tool.server\n2. workflow.server / assistant.server\n3. phoneNumber.server\n4. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "metadata": { + "type": "object", + "description": "This is for metadata you want to store on the assistant." }, - "compliancePlan": { - "description": "This is the compliance plan for the workflow. It allows you to configure HIPAA and other compliance settings.", + "backgroundSpeechDenoisingPlan": { + "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nSmart denoising can be combined with or used independently of Fourier denoising.\n\nOrder of precedence:\n- Smart denoising\n- Fourier denoising", "allOf": [ { - "$ref": "#/components/schemas/CompliancePlan" + "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" } ] }, "analysisPlan": { - "description": "This is the plan for analysis of workflow's calls. Stored in `call.analysis`.", + "description": "This is the plan for analysis of assistant's calls. Stored in `call.analysis`.", "allOf": [ { "$ref": "#/components/schemas/AnalysisPlan" @@ -26487,7 +24423,7 @@ ] }, "artifactPlan": { - "description": "This is the plan for artifacts generated during workflow's calls. Stored in `call.artifact`.", + "description": "This is the plan for artifacts generated during assistant's calls. Stored in `call.artifact`.", "allOf": [ { "$ref": "#/components/schemas/ArtifactPlan" @@ -26495,7 +24431,7 @@ ] }, "startSpeakingPlan": { - "description": "This is the plan for when the workflow nodes should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", + "description": "This is the plan for when the assistant should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", "allOf": [ { "$ref": "#/components/schemas/StartSpeakingPlan" @@ -26503,7 +24439,7 @@ ] }, "stopSpeakingPlan": { - "description": "This is the plan for when workflow nodes should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", + "description": "This is the plan for when assistant should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", "allOf": [ { "$ref": "#/components/schemas/StopSpeakingPlan" @@ -26511,2011 +24447,860 @@ ] }, "monitorPlan": { - "description": "This is the plan for real-time monitoring of the workflow's calls.\n\nUsage:\n- To enable live listening of the workflow's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the workflow's calls, set `monitorPlan.controlEnabled` to `true`.", + "description": "This is the plan for real-time monitoring of the assistant's calls.\n\nUsage:\n- To enable live listening of the assistant's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the assistant's calls, set `monitorPlan.controlEnabled` to `true`.", "allOf": [ { "$ref": "#/components/schemas/MonitorPlan" } ] }, - "backgroundSpeechDenoisingPlan": { - "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nBoth can be used together. Order of precedence:\n- Smart denoising\n- Fourier denoising", - "allOf": [ - { - "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" - } - ] - }, "credentialIds": { - "description": "These are the credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", + "description": "These are the credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", "type": "array", "items": { "type": "string" } }, - "keypadInputPlan": { - "description": "This is the plan for keypad input handling during workflow calls.", + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server.url\n2. phoneNumber.serverUrl\n3. org.serverUrl", "allOf": [ { - "$ref": "#/components/schemas/KeypadInputPlan" + "$ref": "#/components/schemas/Server" } ] - } - }, - "required": [ - "nodes", - "name", - "edges" - ] - }, - "WorkflowOverrides": { - "type": "object", - "properties": { - "variableValues": { - "type": "object", - "description": "These are values that will be used to replace the template variables in the workflow messages and other text-based fields.\nThis uses LiquidJS syntax. https://liquidjs.com/tutorials/intro-to-liquid.html\n\nSo for example, `{{ name }}` will be replaced with the value of `name` in `variableValues`.\n`{{\"now\" | date: \"%b %d, %Y, %I:%M %p\", \"America/New_York\"}}` will be replaced with the current date and time in New York.\n Some VAPI reserved defaults:\n - *customer* - the customer object" + }, + "keypadInputPlan": { + "$ref": "#/components/schemas/KeypadInputPlan" } } }, - "TransferPhoneNumberHookAction": { + "AssistantOverrides": { "type": "object", "properties": { - "type": { - "type": "string", - "description": "This is the type of action - must be \"transfer\"", - "enum": [ - "transfer" + "transcriber": { + "description": "These are the options for the assistant's transcriber.", + "oneOf": [ + { + "$ref": "#/components/schemas/AssemblyAITranscriber", + "title": "AssemblyAITranscriber" + }, + { + "$ref": "#/components/schemas/AzureSpeechTranscriber", + "title": "AzureSpeechTranscriber" + }, + { + "$ref": "#/components/schemas/CustomTranscriber", + "title": "CustomTranscriber" + }, + { + "$ref": "#/components/schemas/DeepgramTranscriber", + "title": "DeepgramTranscriber" + }, + { + "$ref": "#/components/schemas/ElevenLabsTranscriber", + "title": "ElevenLabsTranscriber" + }, + { + "$ref": "#/components/schemas/GladiaTranscriber", + "title": "GladiaTranscriber" + }, + { + "$ref": "#/components/schemas/GoogleTranscriber", + "title": "GoogleTranscriber" + }, + { + "$ref": "#/components/schemas/SpeechmaticsTranscriber", + "title": "SpeechmaticsTranscriber" + }, + { + "$ref": "#/components/schemas/TalkscriberTranscriber", + "title": "TalkscriberTranscriber" + }, + { + "$ref": "#/components/schemas/OpenAITranscriber", + "title": "OpenAITranscriber" + }, + { + "$ref": "#/components/schemas/CartesiaTranscriber", + "title": "CartesiaTranscriber" + } ] }, - "destination": { - "description": "This is the destination details for the transfer - can be a phone number or SIP URI", + "model": { + "description": "These are the options for the assistant's LLM.", "oneOf": [ { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" + "$ref": "#/components/schemas/AnthropicModel", + "title": "Anthropic" }, { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/AnyscaleModel", + "title": "Anyscale" + }, + { + "$ref": "#/components/schemas/CerebrasModel", + "title": "Cerebras" + }, + { + "$ref": "#/components/schemas/CustomLLMModel", + "title": "CustomLLM" + }, + { + "$ref": "#/components/schemas/DeepInfraModel", + "title": "DeepInfra" + }, + { + "$ref": "#/components/schemas/DeepSeekModel", + "title": "DeepSeek" + }, + { + "$ref": "#/components/schemas/GoogleModel", + "title": "Google" + }, + { + "$ref": "#/components/schemas/GroqModel", + "title": "Groq" + }, + { + "$ref": "#/components/schemas/InflectionAIModel", + "title": "InflectionAI" + }, + { + "$ref": "#/components/schemas/OpenAIModel", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/OpenRouterModel", + "title": "OpenRouter" + }, + { + "$ref": "#/components/schemas/PerplexityAIModel", + "title": "PerplexityAI" + }, + { + "$ref": "#/components/schemas/TogetherAIModel", + "title": "Together" + }, + { + "$ref": "#/components/schemas/XaiModel", + "title": "XAI" } ] - } - }, - "required": [ - "type" - ] - }, - "SayPhoneNumberHookAction": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "This is the type of action - must be \"say\"", - "enum": [ - "say" - ] }, - "exact": { - "type": "string", - "description": "This is the message to say", - "maxLength": 4000 - } - }, - "required": [ - "type", - "exact" - ] - }, - "PhoneNumberHookCallRinging": { - "type": "object", - "properties": { - "on": { - "type": "string", - "description": "This is the event to trigger the hook on", - "enum": [ - "call.ringing" - ], - "maxLength": 1000 + "voice": { + "description": "These are the options for the assistant's voice.", + "oneOf": [ + { + "$ref": "#/components/schemas/AzureVoice", + "title": "AzureVoice" + }, + { + "$ref": "#/components/schemas/CartesiaVoice", + "title": "CartesiaVoice" + }, + { + "$ref": "#/components/schemas/CustomVoice", + "title": "CustomVoice" + }, + { + "$ref": "#/components/schemas/DeepgramVoice", + "title": "DeepgramVoice" + }, + { + "$ref": "#/components/schemas/ElevenLabsVoice", + "title": "ElevenLabsVoice" + }, + { + "$ref": "#/components/schemas/HumeVoice", + "title": "HumeVoice" + }, + { + "$ref": "#/components/schemas/LMNTVoice", + "title": "LMNTVoice" + }, + { + "$ref": "#/components/schemas/NeuphonicVoice", + "title": "NeuphonicVoice" + }, + { + "$ref": "#/components/schemas/OpenAIVoice", + "title": "OpenAIVoice" + }, + { + "$ref": "#/components/schemas/PlayHTVoice", + "title": "PlayHTVoice" + }, + { + "$ref": "#/components/schemas/RimeAIVoice", + "title": "RimeAIVoice" + }, + { + "$ref": "#/components/schemas/SmallestAIVoice", + "title": "SmallestAIVoice" + }, + { + "$ref": "#/components/schemas/TavusVoice", + "title": "TavusVoice" + }, + { + "$ref": "#/components/schemas/VapiVoice", + "title": "VapiVoice" + }, + { + "$ref": "#/components/schemas/SesameVoice", + "title": "SesameVoice" + }, + { + "$ref": "#/components/schemas/InworldVoice", + "title": "InworldVoice" + }, + { + "$ref": "#/components/schemas/MinimaxVoice", + "title": "MinimaxVoice" + } + ] }, - "do": { - "type": "array", - "description": "Only the first action will be executed. Additional actions will be ignored.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TransferPhoneNumberHookAction", - "title": "TransferPhoneNumberHookAction" - }, - { - "$ref": "#/components/schemas/SayPhoneNumberHookAction", - "title": "SayPhoneNumberHookAction" - } - ] - } - } - }, - "required": [ - "on", - "do" - ] - }, - "PhoneNumberCallEndingHookFilter": { - "type": "object", - "properties": { - "type": { + "firstMessage": { "type": "string", - "description": "This is the type of filter - currently only \"oneOf\" is supported", - "enum": [ - "oneOf" - ], - "maxLength": 1000 + "description": "This is the first message that the assistant will say. This can also be a URL to a containerized audio file (mp3, wav, etc.).\n\nIf unspecified, assistant will wait for user to speak and use the model to respond once they speak.", + "example": "Hello! How can I help you today?" }, - "key": { - "type": "string", - "description": "This is the key to filter on - only \"call.endedReason\" is allowed for phone number call ending hooks", - "enum": [ - "call.endedReason" - ], - "maxLength": 1000 + "firstMessageInterruptionsEnabled": { + "type": "boolean", + "default": false }, - "oneOf": { - "type": "array", - "description": "This is the array of assistant-request related ended reasons to match against", - "enum": [ - "assistant-request-failed", - "assistant-request-returned-error", - "assistant-request-returned-unspeakable-error", - "assistant-request-returned-invalid-assistant", - "assistant-request-returned-no-assistant", - "assistant-request-returned-forwarding-phone-number" - ], - "items": { - "type": "string", - "enum": [ - "assistant-request-failed", - "assistant-request-returned-error", - "assistant-request-returned-unspeakable-error", - "assistant-request-returned-invalid-assistant", - "assistant-request-returned-no-assistant", - "assistant-request-returned-forwarding-phone-number" - ] - } - } - }, - "required": [ - "type", - "key", - "oneOf" - ] - }, - "PhoneNumberHookCallEnding": { - "type": "object", - "properties": { - "on": { + "firstMessageMode": { "type": "string", - "description": "This is the event to trigger the hook on", + "description": "This is the mode for the first message. Default is 'assistant-speaks-first'.\n\nUse:\n- 'assistant-speaks-first' to have the assistant speak first.\n- 'assistant-waits-for-user' to have the assistant wait for the user to speak first.\n- 'assistant-speaks-first-with-model-generated-message' to have the assistant speak first with a message generated by the model based on the conversation state. (`assistant.model.messages` at call start, `call.messages` at squad transfer points).\n\n@default 'assistant-speaks-first'", "enum": [ - "call.ending" + "assistant-speaks-first", + "assistant-speaks-first-with-model-generated-message", + "assistant-waits-for-user" ], - "maxLength": 1000 - }, - "filters": { - "type": "array", - "description": "Optional filters to decide when to trigger - restricted to assistant-request related ended reasons", - "items": { - "$ref": "#/components/schemas/PhoneNumberCallEndingHookFilter" - } + "example": "assistant-speaks-first" }, - "do": { - "description": "This is the action to perform when the hook triggers", + "voicemailDetection": { + "description": "These are the settings to configure or disable voicemail detection. Alternatively, voicemail detection can be configured using the model.tools=[VoicemailTool].\nThis uses Twilio's built-in detection while the VoicemailTool relies on the model to detect if a voicemail was reached.\nYou can use neither of them, one of them, or both of them. By default, Twilio built-in detection is enabled while VoicemailTool is not.", "oneOf": [ { - "$ref": "#/components/schemas/TransferPhoneNumberHookAction", - "title": "TransferPhoneNumberHookAction" + "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", + "title": "Google" }, { - "$ref": "#/components/schemas/SayPhoneNumberHookAction", - "title": "SayPhoneNumberHookAction" - } - ] - } - }, - "required": [ - "on" - ] - }, - "ImportTwilioPhoneNumberDTO": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ + "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", + "title": "OpenAI" + }, { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" + "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", + "title": "Twilio" }, { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", + "title": "Vapi" } ] }, - "hooks": { + "clientMessages": { "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", + "enum": [ + "conversation-update", + "function-call", + "function-call-result", + "hang", + "language-changed", + "metadata", + "model-output", + "speech-update", + "status-update", + "transcript", + "tool-calls", + "tool-calls-result", + "tool.completed", + "transfer-update", + "user-interrupted", + "voice-input", + "workflow.node.started" + ], + "example": [ + "conversation-update", + "function-call", + "hang", + "model-output", + "speech-update", + "status-update", + "transfer-update", + "transcript", + "tool-calls", + "user-interrupted", + "voice-input", + "workflow.node.started" + ], + "description": "These are the messages that will be sent to your Client SDKs. Default is conversation-update,function-call,hang,model-output,speech-update,status-update,transfer-update,transcript,tool-calls,user-interrupted,voice-input,workflow.node.started. You can check the shape of the messages in ClientMessage schema.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "smsEnabled": { - "type": "boolean", - "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", - "default": true - }, - "twilioPhoneNumber": { - "type": "string", - "description": "These are the digits of the phone number you own on your Twilio.", - "deprecated": true - }, - "twilioAccountSid": { - "type": "string", - "description": "This is your Twilio Account SID that will be used to handle this phone number." - }, - "twilioAuthToken": { - "type": "string", - "description": "This is the Twilio Auth Token that will be used to handle this phone number." - }, - "twilioApiKey": { - "type": "string", - "description": "This is the Twilio API Key that will be used to handle this phone number. If AuthToken is provided, this will be ignored." - }, - "twilioApiSecret": { - "type": "string", - "description": "This is the Twilio API Secret that will be used to handle this phone number. If AuthToken is provided, this will be ignored." - }, - "name": { - "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 - }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "type": "string", + "enum": [ + "conversation-update", + "function-call", + "function-call-result", + "hang", + "language-changed", + "metadata", + "model-output", + "speech-update", + "status-update", + "transcript", + "tool-calls", + "tool-calls-result", + "tool.completed", + "transfer-update", + "user-interrupted", + "voice-input", + "workflow.node.started" + ] + } }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "serverMessages": { + "type": "array", + "enum": [ + "conversation-update", + "end-of-call-report", + "function-call", + "hang", + "language-changed", + "language-change-detected", + "model-output", + "phone-call-control", + "speech-update", + "status-update", + "transcript", + "transcript[transcriptType=\"final\"]", + "tool-calls", + "transfer-destination-request", + "handoff-destination-request", + "transfer-update", + "user-interrupted", + "voice-input", + "chat.created", + "chat.deleted", + "session.created", + "session.updated", + "session.deleted" + ], + "example": [ + "conversation-update", + "end-of-call-report", + "function-call", + "hang", + "speech-update", + "status-update", + "tool-calls", + "transfer-destination-request", + "handoff-destination-request", + "user-interrupted" + ], + "description": "These are the messages that will be sent to your Server URL. Default is conversation-update,end-of-call-report,function-call,hang,speech-update,status-update,tool-calls,transfer-destination-request,handoff-destination-request,user-interrupted. You can check the shape of the messages in ServerMessage schema.", + "items": { + "type": "string", + "enum": [ + "conversation-update", + "end-of-call-report", + "function-call", + "hang", + "language-changed", + "language-change-detected", + "model-output", + "phone-call-control", + "speech-update", + "status-update", + "transcript", + "transcript[transcriptType=\"final\"]", + "tool-calls", + "transfer-destination-request", + "handoff-destination-request", + "transfer-update", + "user-interrupted", + "voice-input", + "chat.created", + "chat.deleted", + "session.created", + "session.updated", + "session.deleted" + ] + } }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "maxDurationSeconds": { + "type": "number", + "description": "This is the maximum number of seconds that the call will last. When the call reaches this duration, it will be ended.\n\n@default 600 (10 minutes)", + "minimum": 10, + "maximum": 43200, + "example": 600 }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ + "backgroundSound": { + "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", + "oneOf": [ { - "$ref": "#/components/schemas/Server" + "type": "enum", + "enum": [ + "off", + "office" + ], + "example": "office" + }, + { + "type": "string", + "format": "uri", + "example": "https://www.soundjay.com/ambient/sounds/people-in-lounge-1.mp3" } ] - } - }, - "required": [ - "twilioPhoneNumber", - "twilioAccountSid" - ] - }, - "CreateCustomerDTO": { - "type": "object", - "properties": { - "numberE164CheckEnabled": { + }, + "modelOutputInMessagesEnabled": { "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true + "description": "This determines whether the model's output is used in conversation history rather than the transcription of assistant's speech.\n\nDefault `false` while in beta.\n\n@default false", + "example": false }, - "extension": { - "type": "string", - "description": "This is the extension that will be dialed after the call is answered.", - "maxLength": 10, - "example": null + "transportConfigurations": { + "type": "array", + "description": "These are the configurations to be passed to the transport providers of assistant's calls, like Twilio. You can store multiple configurations for different transport providers. For a call, only the configuration matching the call transport provider is used.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/TransportConfigurationTwilio", + "title": "Twilio" + } + ] + } }, - "assistantOverrides": { - "description": "These are the overrides for the assistant's settings and template variables specific to this customer.\nThis allows customization of the assistant's behavior for individual customers in batch calls.", + "observabilityPlan": { + "description": "This is the plan for observability of assistant's calls.\n\nCurrently, only Langfuse is supported.", + "oneOf": [ + { + "$ref": "#/components/schemas/LangfuseObservabilityPlan", + "title": "Langfuse" + } + ], "allOf": [ { - "$ref": "#/components/schemas/AssistantOverrides" + "$ref": "#/components/schemas/LangfuseObservabilityPlan" } ] }, - "number": { - "type": "string", - "description": "This is the number of the customer.", - "minLength": 3, - "maxLength": 40 - }, - "sipUri": { - "type": "string", - "description": "This is the SIP URI of the customer." - }, - "name": { - "type": "string", - "description": "This is the name of the customer. This is just for your own reference.\n\nFor SIP inbound calls, this is extracted from the `From` SIP header with format `\"Display Name\" `.", - "maxLength": 40 - }, - "email": { - "type": "string", - "description": "This is the email of the customer.", - "maxLength": 40 - }, - "externalId": { - "type": "string", - "description": "This is the external ID of the customer.", - "maxLength": 40 - } - } - }, - "SchedulePlan": { - "type": "object", - "properties": { - "earliestAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of the earliest time the call can be scheduled." - }, - "latestAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of the latest time the call can be scheduled." - } - }, - "required": [ - "earliestAt" - ] - }, - "Call": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "This is the type of call.", - "enum": [ - "inboundPhoneCall", - "outboundPhoneCall", - "webCall", - "vapi.websocketCall" - ] - }, - "costs": { + "credentials": { "type": "array", - "description": "These are the costs of individual components of the call in USD.", + "description": "These are dynamic credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/TransportCost", - "title": "TransportCost" + "$ref": "#/components/schemas/CreateAnthropicCredentialDTO", + "title": "AnthropicCredential" }, { - "$ref": "#/components/schemas/TranscriberCost", - "title": "TranscriberCost" + "$ref": "#/components/schemas/CreateAnyscaleCredentialDTO", + "title": "AnyscaleCredential" }, { - "$ref": "#/components/schemas/ModelCost", - "title": "ModelCost" + "$ref": "#/components/schemas/CreateAssemblyAICredentialDTO", + "title": "AssemblyAICredential" }, { - "$ref": "#/components/schemas/VoiceCost", - "title": "VoiceCost" + "$ref": "#/components/schemas/CreateAzureCredentialDTO", + "title": "AzureCredential" }, { - "$ref": "#/components/schemas/VapiCost", - "title": "VapiCost" + "$ref": "#/components/schemas/CreateAzureOpenAICredentialDTO", + "title": "AzureOpenAICredential" }, { - "$ref": "#/components/schemas/VoicemailDetectionCost", - "title": "VoicemailDetectionCost" + "$ref": "#/components/schemas/CreateByoSipTrunkCredentialDTO", + "title": "ByoSipTrunkCredential" }, { - "$ref": "#/components/schemas/AnalysisCost", - "title": "AnalysisCost" + "$ref": "#/components/schemas/CreateCartesiaCredentialDTO", + "title": "CartesiaCredential" }, { - "$ref": "#/components/schemas/KnowledgeBaseCost", - "title": "KnowledgeBaseCost" - } - ] - } - }, - "messages": { - "type": "array", - "items": { - "oneOf": [ + "$ref": "#/components/schemas/CreateCerebrasCredentialDTO", + "title": "CerebrasCredential" + }, { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" + "$ref": "#/components/schemas/CreateCloudflareCredentialDTO", + "title": "CloudflareCredential" }, { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" + "$ref": "#/components/schemas/CreateCustomLLMCredentialDTO", + "title": "CustomLLMCredential" }, { - "$ref": "#/components/schemas/BotMessage", - "title": "BotMessage" + "$ref": "#/components/schemas/CreateDeepgramCredentialDTO", + "title": "DeepgramCredential" }, { - "$ref": "#/components/schemas/ToolCallMessage", - "title": "ToolCallMessage" + "$ref": "#/components/schemas/CreateDeepInfraCredentialDTO", + "title": "DeepInfraCredential" }, { - "$ref": "#/components/schemas/ToolCallResultMessage", - "title": "ToolCallResultMessage" + "$ref": "#/components/schemas/CreateDeepSeekCredentialDTO", + "title": "DeepSeekCredential" + }, + { + "$ref": "#/components/schemas/CreateElevenLabsCredentialDTO", + "title": "ElevenLabsCredential" + }, + { + "$ref": "#/components/schemas/CreateGcpCredentialDTO", + "title": "GcpCredential" + }, + { + "$ref": "#/components/schemas/CreateGladiaCredentialDTO", + "title": "GladiaCredential" + }, + { + "$ref": "#/components/schemas/CreateGoHighLevelCredentialDTO", + "title": "GhlCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCredentialDTO", + "title": "GoogleCredential" + }, + { + "$ref": "#/components/schemas/CreateGroqCredentialDTO", + "title": "GroqCredential" + }, + { + "$ref": "#/components/schemas/CreateHumeCredentialDTO", + "title": "HumeCredential" + }, + { + "$ref": "#/components/schemas/CreateInflectionAICredentialDTO", + "title": "InflectionAICredential" + }, + { + "$ref": "#/components/schemas/CreateLangfuseCredentialDTO", + "title": "LangfuseCredential" + }, + { + "$ref": "#/components/schemas/CreateLmntCredentialDTO", + "title": "LmntCredential" + }, + { + "$ref": "#/components/schemas/CreateMakeCredentialDTO", + "title": "MakeCredential" + }, + { + "$ref": "#/components/schemas/CreateMistralCredentialDTO", + "title": "MistralCredential" + }, + { + "$ref": "#/components/schemas/CreateNeuphonicCredentialDTO", + "title": "NeuphonicCredential" + }, + { + "$ref": "#/components/schemas/CreateOpenAICredentialDTO", + "title": "OpenAICredential" + }, + { + "$ref": "#/components/schemas/CreateOpenRouterCredentialDTO", + "title": "OpenRouterCredential" + }, + { + "$ref": "#/components/schemas/CreatePerplexityAICredentialDTO", + "title": "PerplexityAICredential" + }, + { + "$ref": "#/components/schemas/CreatePlayHTCredentialDTO", + "title": "PlayHTCredential" + }, + { + "$ref": "#/components/schemas/CreateRimeAICredentialDTO", + "title": "RimeAICredential" + }, + { + "$ref": "#/components/schemas/CreateRunpodCredentialDTO", + "title": "RunpodCredential" + }, + { + "$ref": "#/components/schemas/CreateS3CredentialDTO", + "title": "S3Credential" + }, + { + "$ref": "#/components/schemas/CreateSmallestAICredentialDTO", + "title": "SmallestAICredential" + }, + { + "$ref": "#/components/schemas/CreateSpeechmaticsCredentialDTO", + "title": "SpeechmaticsCredential" + }, + { + "$ref": "#/components/schemas/CreateSupabaseCredentialDTO", + "title": "SupabaseCredential" + }, + { + "$ref": "#/components/schemas/CreateTavusCredentialDTO", + "title": "TavusCredential" + }, + { + "$ref": "#/components/schemas/CreateTogetherAICredentialDTO", + "title": "TogetherAICredential" + }, + { + "$ref": "#/components/schemas/CreateTrieveCredentialDTO", + "title": "TrieveCredential" + }, + { + "$ref": "#/components/schemas/CreateTwilioCredentialDTO", + "title": "TwilioCredential" + }, + { + "$ref": "#/components/schemas/CreateVonageCredentialDTO", + "title": "VonageCredential" + }, + { + "$ref": "#/components/schemas/CreateWebhookCredentialDTO", + "title": "WebhookCredential" + }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, + { + "$ref": "#/components/schemas/CreateXAiCredentialDTO", + "title": "XAiCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", + "title": "GoogleCalendarOAuth2ClientCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", + "title": "GoogleCalendarOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", + "title": "GoogleSheetsOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", + "title": "SlackOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", + "title": "GoHighLevelMCPCredential" + }, + { + "$ref": "#/components/schemas/CreateInworldCredentialDTO", + "title": "InworldCredential" + } + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "11labs": "#/components/schemas/CreateElevenLabsCredentialDTO", + "anthropic": "#/components/schemas/CreateAnthropicCredentialDTO", + "anyscale": "#/components/schemas/CreateAnyscaleCredentialDTO", + "assembly-ai": "#/components/schemas/CreateAssemblyAICredentialDTO", + "azure-openai": "#/components/schemas/CreateAzureOpenAICredentialDTO", + "azure": "#/components/schemas/CreateAzureCredentialDTO", + "byo-sip-trunk": "#/components/schemas/CreateByoSipTrunkCredentialDTO", + "cartesia": "#/components/schemas/CreateCartesiaCredentialDTO", + "cerebras": "#/components/schemas/CreateCerebrasCredentialDTO", + "cloudflare": "#/components/schemas/CreateCloudflareCredentialDTO", + "custom-llm": "#/components/schemas/CreateCustomLLMCredentialDTO", + "deepgram": "#/components/schemas/CreateDeepgramCredentialDTO", + "deepinfra": "#/components/schemas/CreateDeepInfraCredentialDTO", + "deep-seek": "#/components/schemas/CreateDeepSeekCredentialDTO", + "gcp": "#/components/schemas/CreateGcpCredentialDTO", + "gladia": "#/components/schemas/CreateGladiaCredentialDTO", + "gohighlevel": "#/components/schemas/CreateGoHighLevelCredentialDTO", + "google": "#/components/schemas/CreateGoogleCredentialDTO", + "groq": "#/components/schemas/CreateGroqCredentialDTO", + "inflection-ai": "#/components/schemas/CreateInflectionAICredentialDTO", + "langfuse": "#/components/schemas/CreateLangfuseCredentialDTO", + "lmnt": "#/components/schemas/CreateLmntCredentialDTO", + "make": "#/components/schemas/CreateMakeCredentialDTO", + "openai": "#/components/schemas/CreateOpenAICredentialDTO", + "openrouter": "#/components/schemas/CreateOpenRouterCredentialDTO", + "perplexity-ai": "#/components/schemas/CreatePerplexityAICredentialDTO", + "playht": "#/components/schemas/CreatePlayHTCredentialDTO", + "rime-ai": "#/components/schemas/CreateRimeAICredentialDTO", + "runpod": "#/components/schemas/CreateRunpodCredentialDTO", + "s3": "#/components/schemas/CreateS3CredentialDTO", + "supabase": "#/components/schemas/CreateSupabaseCredentialDTO", + "smallest-ai": "#/components/schemas/CreateSmallestAICredentialDTO", + "tavus": "#/components/schemas/CreateTavusCredentialDTO", + "together-ai": "#/components/schemas/CreateTogetherAICredentialDTO", + "twilio": "#/components/schemas/CreateTwilioCredentialDTO", + "vonage": "#/components/schemas/CreateVonageCredentialDTO", + "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", + "xai": "#/components/schemas/CreateXAiCredentialDTO", + "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", + "hume": "#/components/schemas/CreateHumeCredentialDTO", + "mistral": "#/components/schemas/CreateMistralCredentialDTO", + "speechmatics": "#/components/schemas/CreateSpeechmaticsCredentialDTO", + "trieve": "#/components/schemas/CreateTrieveCredentialDTO", + "google.calendar.oauth2-client": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", + "google.calendar.oauth2-authorization": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", + "google.sheets.oauth2-authorization": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", + "slack.oauth2-authorization": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", + "ghl.oauth2-authorization": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", + "inworld": "#/components/schemas/CreateInworldCredentialDTO", + "minimax": "#/components/schemas/CreateMinimaxCredentialDTO" } - ] - } - }, - "phoneCallProvider": { - "type": "string", - "description": "This is the provider of the call.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "deprecated": true, - "enum": [ - "twilio", - "vonage", - "vapi", - "telnyx" - ] - }, - "phoneCallTransport": { - "type": "string", - "description": "This is the transport of the phone call.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "enum": [ - "sip", - "pstn" - ] - }, - "status": { - "type": "string", - "description": "This is the status of the call.", - "enum": [ - "scheduled", - "queued", - "ringing", - "in-progress", - "forwarding", - "ended" - ] - }, - "endedReason": { - "type": "string", - "description": "This is the explanation for how the call ended.", - "enum": [ - "call-start-error-neither-assistant-nor-server-set", - "assistant-request-failed", - "assistant-request-returned-error", - "assistant-request-returned-unspeakable-error", - "assistant-request-returned-invalid-assistant", - "assistant-request-returned-no-assistant", - "assistant-request-returned-forwarding-phone-number", - "scheduled-call-deleted", - "call.start.error-vapifault-get-org", - "call.start.error-vapifault-get-subscription", - "call.start.error-get-assistant", - "call.start.error-get-phone-number", - "call.start.error-get-customer", - "call.start.error-get-resources-validation", - "call.start.error-vapi-number-international", - "call.start.error-vapi-number-outbound-daily-limit", - "call.start.error-get-transport", - "call.start.error-subscription-wallet-does-not-exist", - "call.start.error-subscription-frozen", - "call.start.error-subscription-insufficient-credits", - "call.start.error-subscription-upgrade-failed", - "call.start.error-subscription-concurrency-limit-reached", - "assistant-not-valid", - "database-error", - "assistant-not-found", - "pipeline-error-openai-voice-failed", - "pipeline-error-cartesia-voice-failed", - "pipeline-error-deepgram-voice-failed", - "pipeline-error-eleven-labs-voice-failed", - "pipeline-error-playht-voice-failed", - "pipeline-error-lmnt-voice-failed", - "pipeline-error-azure-voice-failed", - "pipeline-error-rime-ai-voice-failed", - "pipeline-error-smallest-ai-voice-failed", - "pipeline-error-neuphonic-voice-failed", - "pipeline-error-hume-voice-failed", - "pipeline-error-sesame-voice-failed", - "pipeline-error-inworld-voice-failed", - "pipeline-error-minimax-voice-failed", - "pipeline-error-tavus-video-failed", - "call.in-progress.error-vapifault-openai-voice-failed", - "call.in-progress.error-vapifault-cartesia-voice-failed", - "call.in-progress.error-vapifault-deepgram-voice-failed", - "call.in-progress.error-vapifault-eleven-labs-voice-failed", - "call.in-progress.error-vapifault-playht-voice-failed", - "call.in-progress.error-vapifault-lmnt-voice-failed", - "call.in-progress.error-vapifault-azure-voice-failed", - "call.in-progress.error-vapifault-rime-ai-voice-failed", - "call.in-progress.error-vapifault-smallest-ai-voice-failed", - "call.in-progress.error-vapifault-neuphonic-voice-failed", - "call.in-progress.error-vapifault-hume-voice-failed", - "call.in-progress.error-vapifault-sesame-voice-failed", - "call.in-progress.error-vapifault-inworld-voice-failed", - "call.in-progress.error-vapifault-minimax-voice-failed", - "call.in-progress.error-vapifault-tavus-video-failed", - "pipeline-error-vapi-llm-failed", - "pipeline-error-vapi-400-bad-request-validation-failed", - "pipeline-error-vapi-401-unauthorized", - "pipeline-error-vapi-403-model-access-denied", - "pipeline-error-vapi-429-exceeded-quota", - "pipeline-error-vapi-500-server-error", - "pipeline-error-vapi-503-server-overloaded-error", - "call.in-progress.error-providerfault-vapi-llm-failed", - "call.in-progress.error-vapifault-vapi-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-vapi-401-unauthorized", - "call.in-progress.error-vapifault-vapi-403-model-access-denied", - "call.in-progress.error-vapifault-vapi-429-exceeded-quota", - "call.in-progress.error-providerfault-vapi-500-server-error", - "call.in-progress.error-providerfault-vapi-503-server-overloaded-error", - "pipeline-error-deepgram-transcriber-failed", - "call.in-progress.error-vapifault-deepgram-transcriber-failed", - "pipeline-error-gladia-transcriber-failed", - "call.in-progress.error-vapifault-gladia-transcriber-failed", - "pipeline-error-speechmatics-transcriber-failed", - "call.in-progress.error-vapifault-speechmatics-transcriber-failed", - "pipeline-error-assembly-ai-transcriber-failed", - "pipeline-error-assembly-ai-returning-400-insufficent-funds", - "pipeline-error-assembly-ai-returning-400-paid-only-feature", - "pipeline-error-assembly-ai-returning-401-invalid-credentials", - "pipeline-error-assembly-ai-returning-500-invalid-schema", - "pipeline-error-assembly-ai-returning-500-word-boost-parsing-failed", - "call.in-progress.error-vapifault-assembly-ai-transcriber-failed", - "call.in-progress.error-vapifault-assembly-ai-returning-400-insufficent-funds", - "call.in-progress.error-vapifault-assembly-ai-returning-400-paid-only-feature", - "call.in-progress.error-vapifault-assembly-ai-returning-401-invalid-credentials", - "call.in-progress.error-vapifault-assembly-ai-returning-500-invalid-schema", - "call.in-progress.error-vapifault-assembly-ai-returning-500-word-boost-parsing-failed", - "pipeline-error-talkscriber-transcriber-failed", - "call.in-progress.error-vapifault-talkscriber-transcriber-failed", - "pipeline-error-azure-speech-transcriber-failed", - "call.in-progress.error-vapifault-azure-speech-transcriber-failed", - "call.in-progress.error-pipeline-no-available-llm-model", - "worker-shutdown", - "vonage-disconnected", - "vonage-failed-to-connect-call", - "vonage-completed", - "phone-call-provider-bypass-enabled-but-no-call-received", - "call.in-progress.error-providerfault-transport-never-connected", - "call.in-progress.error-vapifault-worker-not-available", - "call.in-progress.error-vapifault-transport-never-connected", - "call.in-progress.error-vapifault-transport-connected-but-call-not-active", - "call.in-progress.error-vapifault-call-started-but-connection-to-transport-missing", - "call.in-progress.error-vapifault-worker-died", - "call.in-progress.twilio-completed-call", - "call.in-progress.sip-completed-call", - "call.in-progress.error-providerfault-openai-llm-failed", - "call.in-progress.error-providerfault-azure-openai-llm-failed", - "call.in-progress.error-providerfault-groq-llm-failed", - "call.in-progress.error-providerfault-google-llm-failed", - "call.in-progress.error-providerfault-xai-llm-failed", - "call.in-progress.error-providerfault-mistral-llm-failed", - "call.in-progress.error-providerfault-inflection-ai-llm-failed", - "call.in-progress.error-providerfault-cerebras-llm-failed", - "call.in-progress.error-providerfault-deep-seek-llm-failed", - "call.in-progress.error-vapifault-chat-pipeline-failed-to-start", - "pipeline-error-openai-400-bad-request-validation-failed", - "pipeline-error-openai-401-unauthorized", - "pipeline-error-openai-401-incorrect-api-key", - "pipeline-error-openai-401-account-not-in-organization", - "pipeline-error-openai-403-model-access-denied", - "pipeline-error-openai-429-exceeded-quota", - "pipeline-error-openai-429-rate-limit-reached", - "pipeline-error-openai-500-server-error", - "pipeline-error-openai-503-server-overloaded-error", - "pipeline-error-openai-llm-failed", - "call.in-progress.error-vapifault-openai-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-openai-401-unauthorized", - "call.in-progress.error-vapifault-openai-401-incorrect-api-key", - "call.in-progress.error-vapifault-openai-401-account-not-in-organization", - "call.in-progress.error-vapifault-openai-403-model-access-denied", - "call.in-progress.error-vapifault-openai-429-exceeded-quota", - "call.in-progress.error-vapifault-openai-429-rate-limit-reached", - "call.in-progress.error-providerfault-openai-500-server-error", - "call.in-progress.error-providerfault-openai-503-server-overloaded-error", - "pipeline-error-azure-openai-400-bad-request-validation-failed", - "pipeline-error-azure-openai-401-unauthorized", - "pipeline-error-azure-openai-403-model-access-denied", - "pipeline-error-azure-openai-429-exceeded-quota", - "pipeline-error-azure-openai-500-server-error", - "pipeline-error-azure-openai-503-server-overloaded-error", - "pipeline-error-azure-openai-llm-failed", - "call.in-progress.error-vapifault-azure-openai-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-azure-openai-401-unauthorized", - "call.in-progress.error-vapifault-azure-openai-403-model-access-denied", - "call.in-progress.error-vapifault-azure-openai-429-exceeded-quota", - "call.in-progress.error-providerfault-azure-openai-500-server-error", - "call.in-progress.error-providerfault-azure-openai-503-server-overloaded-error", - "pipeline-error-google-400-bad-request-validation-failed", - "pipeline-error-google-401-unauthorized", - "pipeline-error-google-403-model-access-denied", - "pipeline-error-google-429-exceeded-quota", - "pipeline-error-google-500-server-error", - "pipeline-error-google-503-server-overloaded-error", - "pipeline-error-google-llm-failed", - "call.in-progress.error-vapifault-google-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-google-401-unauthorized", - "call.in-progress.error-vapifault-google-403-model-access-denied", - "call.in-progress.error-vapifault-google-429-exceeded-quota", - "call.in-progress.error-providerfault-google-500-server-error", - "call.in-progress.error-providerfault-google-503-server-overloaded-error", - "pipeline-error-xai-400-bad-request-validation-failed", - "pipeline-error-xai-401-unauthorized", - "pipeline-error-xai-403-model-access-denied", - "pipeline-error-xai-429-exceeded-quota", - "pipeline-error-xai-500-server-error", - "pipeline-error-xai-503-server-overloaded-error", - "pipeline-error-xai-llm-failed", - "call.in-progress.error-vapifault-xai-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-xai-401-unauthorized", - "call.in-progress.error-vapifault-xai-403-model-access-denied", - "call.in-progress.error-vapifault-xai-429-exceeded-quota", - "call.in-progress.error-providerfault-xai-500-server-error", - "call.in-progress.error-providerfault-xai-503-server-overloaded-error", - "pipeline-error-mistral-400-bad-request-validation-failed", - "pipeline-error-mistral-401-unauthorized", - "pipeline-error-mistral-403-model-access-denied", - "pipeline-error-mistral-429-exceeded-quota", - "pipeline-error-mistral-500-server-error", - "pipeline-error-mistral-503-server-overloaded-error", - "pipeline-error-mistral-llm-failed", - "call.in-progress.error-vapifault-mistral-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-mistral-401-unauthorized", - "call.in-progress.error-vapifault-mistral-403-model-access-denied", - "call.in-progress.error-vapifault-mistral-429-exceeded-quota", - "call.in-progress.error-providerfault-mistral-500-server-error", - "call.in-progress.error-providerfault-mistral-503-server-overloaded-error", - "pipeline-error-inflection-ai-400-bad-request-validation-failed", - "pipeline-error-inflection-ai-401-unauthorized", - "pipeline-error-inflection-ai-403-model-access-denied", - "pipeline-error-inflection-ai-429-exceeded-quota", - "pipeline-error-inflection-ai-500-server-error", - "pipeline-error-inflection-ai-503-server-overloaded-error", - "pipeline-error-inflection-ai-llm-failed", - "call.in-progress.error-vapifault-inflection-ai-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-inflection-ai-401-unauthorized", - "call.in-progress.error-vapifault-inflection-ai-403-model-access-denied", - "call.in-progress.error-vapifault-inflection-ai-429-exceeded-quota", - "call.in-progress.error-providerfault-inflection-ai-500-server-error", - "call.in-progress.error-providerfault-inflection-ai-503-server-overloaded-error", - "pipeline-error-deep-seek-400-bad-request-validation-failed", - "pipeline-error-deep-seek-401-unauthorized", - "pipeline-error-deep-seek-403-model-access-denied", - "pipeline-error-deep-seek-429-exceeded-quota", - "pipeline-error-deep-seek-500-server-error", - "pipeline-error-deep-seek-503-server-overloaded-error", - "pipeline-error-deep-seek-llm-failed", - "call.in-progress.error-vapifault-deep-seek-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-deep-seek-401-unauthorized", - "call.in-progress.error-vapifault-deep-seek-403-model-access-denied", - "call.in-progress.error-vapifault-deep-seek-429-exceeded-quota", - "call.in-progress.error-providerfault-deep-seek-500-server-error", - "call.in-progress.error-providerfault-deep-seek-503-server-overloaded-error", - "pipeline-error-groq-400-bad-request-validation-failed", - "pipeline-error-groq-401-unauthorized", - "pipeline-error-groq-403-model-access-denied", - "pipeline-error-groq-429-exceeded-quota", - "pipeline-error-groq-500-server-error", - "pipeline-error-groq-503-server-overloaded-error", - "pipeline-error-groq-llm-failed", - "call.in-progress.error-vapifault-groq-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-groq-401-unauthorized", - "call.in-progress.error-vapifault-groq-403-model-access-denied", - "call.in-progress.error-vapifault-groq-429-exceeded-quota", - "call.in-progress.error-providerfault-groq-500-server-error", - "call.in-progress.error-providerfault-groq-503-server-overloaded-error", - "pipeline-error-cerebras-400-bad-request-validation-failed", - "pipeline-error-cerebras-401-unauthorized", - "pipeline-error-cerebras-403-model-access-denied", - "pipeline-error-cerebras-429-exceeded-quota", - "pipeline-error-cerebras-500-server-error", - "pipeline-error-cerebras-503-server-overloaded-error", - "pipeline-error-cerebras-llm-failed", - "call.in-progress.error-vapifault-cerebras-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-cerebras-401-unauthorized", - "call.in-progress.error-vapifault-cerebras-403-model-access-denied", - "call.in-progress.error-vapifault-cerebras-429-exceeded-quota", - "call.in-progress.error-providerfault-cerebras-500-server-error", - "call.in-progress.error-providerfault-cerebras-503-server-overloaded-error", - "pipeline-error-anthropic-400-bad-request-validation-failed", - "pipeline-error-anthropic-401-unauthorized", - "pipeline-error-anthropic-403-model-access-denied", - "pipeline-error-anthropic-429-exceeded-quota", - "pipeline-error-anthropic-500-server-error", - "pipeline-error-anthropic-503-server-overloaded-error", - "pipeline-error-anthropic-llm-failed", - "call.in-progress.error-providerfault-anthropic-llm-failed", - "call.in-progress.error-vapifault-anthropic-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-anthropic-401-unauthorized", - "call.in-progress.error-vapifault-anthropic-403-model-access-denied", - "call.in-progress.error-vapifault-anthropic-429-exceeded-quota", - "call.in-progress.error-providerfault-anthropic-500-server-error", - "call.in-progress.error-providerfault-anthropic-503-server-overloaded-error", - "pipeline-error-anthropic-bedrock-400-bad-request-validation-failed", - "pipeline-error-anthropic-bedrock-401-unauthorized", - "pipeline-error-anthropic-bedrock-403-model-access-denied", - "pipeline-error-anthropic-bedrock-429-exceeded-quota", - "pipeline-error-anthropic-bedrock-500-server-error", - "pipeline-error-anthropic-bedrock-503-server-overloaded-error", - "pipeline-error-anthropic-bedrock-llm-failed", - "call.in-progress.error-providerfault-anthropic-bedrock-llm-failed", - "call.in-progress.error-vapifault-anthropic-bedrock-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-anthropic-bedrock-401-unauthorized", - "call.in-progress.error-vapifault-anthropic-bedrock-403-model-access-denied", - "call.in-progress.error-vapifault-anthropic-bedrock-429-exceeded-quota", - "call.in-progress.error-providerfault-anthropic-bedrock-500-server-error", - "call.in-progress.error-providerfault-anthropic-bedrock-503-server-overloaded-error", - "pipeline-error-anthropic-vertex-400-bad-request-validation-failed", - "pipeline-error-anthropic-vertex-401-unauthorized", - "pipeline-error-anthropic-vertex-403-model-access-denied", - "pipeline-error-anthropic-vertex-429-exceeded-quota", - "pipeline-error-anthropic-vertex-500-server-error", - "pipeline-error-anthropic-vertex-503-server-overloaded-error", - "pipeline-error-anthropic-vertex-llm-failed", - "call.in-progress.error-providerfault-anthropic-vertex-llm-failed", - "call.in-progress.error-vapifault-anthropic-vertex-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-anthropic-vertex-401-unauthorized", - "call.in-progress.error-vapifault-anthropic-vertex-403-model-access-denied", - "call.in-progress.error-vapifault-anthropic-vertex-429-exceeded-quota", - "call.in-progress.error-providerfault-anthropic-vertex-500-server-error", - "call.in-progress.error-providerfault-anthropic-vertex-503-server-overloaded-error", - "pipeline-error-together-ai-400-bad-request-validation-failed", - "pipeline-error-together-ai-401-unauthorized", - "pipeline-error-together-ai-403-model-access-denied", - "pipeline-error-together-ai-429-exceeded-quota", - "pipeline-error-together-ai-500-server-error", - "pipeline-error-together-ai-503-server-overloaded-error", - "pipeline-error-together-ai-llm-failed", - "call.in-progress.error-providerfault-together-ai-llm-failed", - "call.in-progress.error-vapifault-together-ai-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-together-ai-401-unauthorized", - "call.in-progress.error-vapifault-together-ai-403-model-access-denied", - "call.in-progress.error-vapifault-together-ai-429-exceeded-quota", - "call.in-progress.error-providerfault-together-ai-500-server-error", - "call.in-progress.error-providerfault-together-ai-503-server-overloaded-error", - "pipeline-error-anyscale-400-bad-request-validation-failed", - "pipeline-error-anyscale-401-unauthorized", - "pipeline-error-anyscale-403-model-access-denied", - "pipeline-error-anyscale-429-exceeded-quota", - "pipeline-error-anyscale-500-server-error", - "pipeline-error-anyscale-503-server-overloaded-error", - "pipeline-error-anyscale-llm-failed", - "call.in-progress.error-providerfault-anyscale-llm-failed", - "call.in-progress.error-vapifault-anyscale-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-anyscale-401-unauthorized", - "call.in-progress.error-vapifault-anyscale-403-model-access-denied", - "call.in-progress.error-vapifault-anyscale-429-exceeded-quota", - "call.in-progress.error-providerfault-anyscale-500-server-error", - "call.in-progress.error-providerfault-anyscale-503-server-overloaded-error", - "pipeline-error-openrouter-400-bad-request-validation-failed", - "pipeline-error-openrouter-401-unauthorized", - "pipeline-error-openrouter-403-model-access-denied", - "pipeline-error-openrouter-429-exceeded-quota", - "pipeline-error-openrouter-500-server-error", - "pipeline-error-openrouter-503-server-overloaded-error", - "pipeline-error-openrouter-llm-failed", - "call.in-progress.error-providerfault-openrouter-llm-failed", - "call.in-progress.error-vapifault-openrouter-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-openrouter-401-unauthorized", - "call.in-progress.error-vapifault-openrouter-403-model-access-denied", - "call.in-progress.error-vapifault-openrouter-429-exceeded-quota", - "call.in-progress.error-providerfault-openrouter-500-server-error", - "call.in-progress.error-providerfault-openrouter-503-server-overloaded-error", - "pipeline-error-perplexity-ai-400-bad-request-validation-failed", - "pipeline-error-perplexity-ai-401-unauthorized", - "pipeline-error-perplexity-ai-403-model-access-denied", - "pipeline-error-perplexity-ai-429-exceeded-quota", - "pipeline-error-perplexity-ai-500-server-error", - "pipeline-error-perplexity-ai-503-server-overloaded-error", - "pipeline-error-perplexity-ai-llm-failed", - "call.in-progress.error-providerfault-perplexity-ai-llm-failed", - "call.in-progress.error-vapifault-perplexity-ai-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-perplexity-ai-401-unauthorized", - "call.in-progress.error-vapifault-perplexity-ai-403-model-access-denied", - "call.in-progress.error-vapifault-perplexity-ai-429-exceeded-quota", - "call.in-progress.error-providerfault-perplexity-ai-500-server-error", - "call.in-progress.error-providerfault-perplexity-ai-503-server-overloaded-error", - "pipeline-error-deepinfra-400-bad-request-validation-failed", - "pipeline-error-deepinfra-401-unauthorized", - "pipeline-error-deepinfra-403-model-access-denied", - "pipeline-error-deepinfra-429-exceeded-quota", - "pipeline-error-deepinfra-500-server-error", - "pipeline-error-deepinfra-503-server-overloaded-error", - "pipeline-error-deepinfra-llm-failed", - "call.in-progress.error-providerfault-deepinfra-llm-failed", - "call.in-progress.error-vapifault-deepinfra-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-deepinfra-401-unauthorized", - "call.in-progress.error-vapifault-deepinfra-403-model-access-denied", - "call.in-progress.error-vapifault-deepinfra-429-exceeded-quota", - "call.in-progress.error-providerfault-deepinfra-500-server-error", - "call.in-progress.error-providerfault-deepinfra-503-server-overloaded-error", - "pipeline-error-runpod-400-bad-request-validation-failed", - "pipeline-error-runpod-401-unauthorized", - "pipeline-error-runpod-403-model-access-denied", - "pipeline-error-runpod-429-exceeded-quota", - "pipeline-error-runpod-500-server-error", - "pipeline-error-runpod-503-server-overloaded-error", - "pipeline-error-runpod-llm-failed", - "call.in-progress.error-providerfault-runpod-llm-failed", - "call.in-progress.error-vapifault-runpod-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-runpod-401-unauthorized", - "call.in-progress.error-vapifault-runpod-403-model-access-denied", - "call.in-progress.error-vapifault-runpod-429-exceeded-quota", - "call.in-progress.error-providerfault-runpod-500-server-error", - "call.in-progress.error-providerfault-runpod-503-server-overloaded-error", - "pipeline-error-custom-llm-400-bad-request-validation-failed", - "pipeline-error-custom-llm-401-unauthorized", - "pipeline-error-custom-llm-403-model-access-denied", - "pipeline-error-custom-llm-429-exceeded-quota", - "pipeline-error-custom-llm-500-server-error", - "pipeline-error-custom-llm-503-server-overloaded-error", - "pipeline-error-custom-llm-llm-failed", - "call.in-progress.error-providerfault-custom-llm-llm-failed", - "call.in-progress.error-vapifault-custom-llm-400-bad-request-validation-failed", - "call.in-progress.error-vapifault-custom-llm-401-unauthorized", - "call.in-progress.error-vapifault-custom-llm-403-model-access-denied", - "call.in-progress.error-vapifault-custom-llm-429-exceeded-quota", - "call.in-progress.error-providerfault-custom-llm-500-server-error", - "call.in-progress.error-providerfault-custom-llm-503-server-overloaded-error", - "pipeline-error-custom-voice-failed", - "pipeline-error-cartesia-socket-hang-up", - "pipeline-error-cartesia-requested-payment", - "pipeline-error-cartesia-500-server-error", - "pipeline-error-cartesia-502-server-error", - "pipeline-error-cartesia-503-server-error", - "pipeline-error-cartesia-522-server-error", - "call.in-progress.error-vapifault-cartesia-socket-hang-up", - "call.in-progress.error-vapifault-cartesia-requested-payment", - "call.in-progress.error-providerfault-cartesia-500-server-error", - "call.in-progress.error-providerfault-cartesia-503-server-error", - "call.in-progress.error-providerfault-cartesia-522-server-error", - "pipeline-error-eleven-labs-voice-not-found", - "pipeline-error-eleven-labs-quota-exceeded", - "pipeline-error-eleven-labs-unauthorized-access", - "pipeline-error-eleven-labs-unauthorized-to-access-model", - "pipeline-error-eleven-labs-professional-voices-only-for-creator-plus", - "pipeline-error-eleven-labs-blocked-free-plan-and-requested-upgrade", - "pipeline-error-eleven-labs-blocked-concurrent-requests-and-requested-upgrade", - "pipeline-error-eleven-labs-blocked-using-instant-voice-clone-and-requested-upgrade", - "pipeline-error-eleven-labs-system-busy-and-requested-upgrade", - "pipeline-error-eleven-labs-voice-not-fine-tuned", - "pipeline-error-eleven-labs-invalid-api-key", - "pipeline-error-eleven-labs-invalid-voice-samples", - "pipeline-error-eleven-labs-voice-disabled-by-owner", - "pipeline-error-eleven-labs-vapi-voice-disabled-by-owner", - "pipeline-error-eleven-labs-blocked-account-in-probation", - "pipeline-error-eleven-labs-blocked-content-against-their-policy", - "pipeline-error-eleven-labs-missing-samples-for-voice-clone", - "pipeline-error-eleven-labs-voice-not-fine-tuned-and-cannot-be-used", - "pipeline-error-eleven-labs-voice-not-allowed-for-free-users", - "pipeline-error-eleven-labs-max-character-limit-exceeded", - "pipeline-error-eleven-labs-blocked-voice-potentially-against-terms-of-service-and-awaiting-verification", - "pipeline-error-eleven-labs-500-server-error", - "pipeline-error-eleven-labs-503-server-error", - "call.in-progress.error-vapifault-eleven-labs-voice-not-found", - "call.in-progress.error-vapifault-eleven-labs-quota-exceeded", - "call.in-progress.error-vapifault-eleven-labs-unauthorized-access", - "call.in-progress.error-vapifault-eleven-labs-unauthorized-to-access-model", - "call.in-progress.error-vapifault-eleven-labs-professional-voices-only-for-creator-plus", - "call.in-progress.error-vapifault-eleven-labs-blocked-free-plan-and-requested-upgrade", - "call.in-progress.error-vapifault-eleven-labs-blocked-concurrent-requests-and-requested-upgrade", - "call.in-progress.error-vapifault-eleven-labs-blocked-using-instant-voice-clone-and-requested-upgrade", - "call.in-progress.error-vapifault-eleven-labs-system-busy-and-requested-upgrade", - "call.in-progress.error-vapifault-eleven-labs-voice-not-fine-tuned", - "call.in-progress.error-vapifault-eleven-labs-invalid-api-key", - "call.in-progress.error-vapifault-eleven-labs-invalid-voice-samples", - "call.in-progress.error-vapifault-eleven-labs-voice-disabled-by-owner", - "call.in-progress.error-vapifault-eleven-labs-blocked-account-in-probation", - "call.in-progress.error-vapifault-eleven-labs-blocked-content-against-their-policy", - "call.in-progress.error-vapifault-eleven-labs-missing-samples-for-voice-clone", - "call.in-progress.error-vapifault-eleven-labs-voice-not-fine-tuned-and-cannot-be-used", - "call.in-progress.error-vapifault-eleven-labs-voice-not-allowed-for-free-users", - "call.in-progress.error-vapifault-eleven-labs-max-character-limit-exceeded", - "call.in-progress.error-vapifault-eleven-labs-blocked-voice-potentially-against-terms-of-service-and-awaiting-verification", - "call.in-progress.error-providerfault-eleven-labs-500-server-error", - "call.in-progress.error-providerfault-eleven-labs-503-server-error", - "pipeline-error-playht-request-timed-out", - "pipeline-error-playht-invalid-voice", - "pipeline-error-playht-unexpected-error", - "pipeline-error-playht-out-of-credits", - "pipeline-error-playht-invalid-emotion", - "pipeline-error-playht-voice-must-be-a-valid-voice-manifest-uri", - "pipeline-error-playht-401-unauthorized", - "pipeline-error-playht-403-forbidden-out-of-characters", - "pipeline-error-playht-403-forbidden-api-access-not-available", - "pipeline-error-playht-429-exceeded-quota", - "pipeline-error-playht-502-gateway-error", - "pipeline-error-playht-504-gateway-error", - "call.in-progress.error-vapifault-playht-request-timed-out", - "call.in-progress.error-vapifault-playht-invalid-voice", - "call.in-progress.error-vapifault-playht-unexpected-error", - "call.in-progress.error-vapifault-playht-out-of-credits", - "call.in-progress.error-vapifault-playht-invalid-emotion", - "call.in-progress.error-vapifault-playht-voice-must-be-a-valid-voice-manifest-uri", - "call.in-progress.error-vapifault-playht-401-unauthorized", - "call.in-progress.error-vapifault-playht-403-forbidden-out-of-characters", - "call.in-progress.error-vapifault-playht-403-forbidden-api-access-not-available", - "call.in-progress.error-vapifault-playht-429-exceeded-quota", - "call.in-progress.error-providerfault-playht-502-gateway-error", - "call.in-progress.error-providerfault-playht-504-gateway-error", - "pipeline-error-custom-transcriber-failed", - "call.in-progress.error-vapifault-custom-transcriber-failed", - "pipeline-error-eleven-labs-transcriber-failed", - "call.in-progress.error-vapifault-eleven-labs-transcriber-failed", - "pipeline-error-deepgram-returning-400-no-such-model-language-tier-combination", - "pipeline-error-deepgram-returning-401-invalid-credentials", - "pipeline-error-deepgram-returning-403-model-access-denied", - "pipeline-error-deepgram-returning-404-not-found", - "pipeline-error-deepgram-returning-500-invalid-json", - "pipeline-error-deepgram-returning-502-network-error", - "pipeline-error-deepgram-returning-502-bad-gateway-ehostunreach", - "pipeline-error-deepgram-returning-econnreset", - "call.in-progress.error-vapifault-deepgram-returning-400-no-such-model-language-tier-combination", - "call.in-progress.error-vapifault-deepgram-returning-401-invalid-credentials", - "call.in-progress.error-vapifault-deepgram-returning-404-not-found", - "call.in-progress.error-vapifault-deepgram-returning-403-model-access-denied", - "call.in-progress.error-providerfault-deepgram-returning-500-invalid-json", - "call.in-progress.error-providerfault-deepgram-returning-502-network-error", - "call.in-progress.error-providerfault-deepgram-returning-502-bad-gateway-ehostunreach", - "pipeline-error-google-transcriber-failed", - "call.in-progress.error-vapifault-google-transcriber-failed", - "pipeline-error-openai-transcriber-failed", - "call.in-progress.error-vapifault-openai-transcriber-failed", - "call.in-progress.error-warm-transfer-max-duration", - "call.in-progress.error-warm-transfer-assistant-cancelled", - "call.in-progress.error-warm-transfer-silence-timeout", - "call.in-progress.error-warm-transfer-microphone-timeout", - "call.in-progress.error-warm-transfer-hang-timeout", - "call.in-progress.error-warm-transfer-idle-timeout", - "assistant-ended-call", - "assistant-said-end-call-phrase", - "assistant-ended-call-with-hangup-task", - "assistant-ended-call-after-message-spoken", - "assistant-forwarded-call", - "assistant-join-timed-out", - "call.in-progress.error-assistant-did-not-receive-customer-audio", - "call.in-progress.error-transfer-failed", - "customer-busy", - "customer-ended-call", - "customer-ended-call-after-warm-transfer-attempt", - "customer-did-not-answer", - "customer-did-not-give-microphone-permission", - "exceeded-max-duration", - "manually-canceled", - "phone-call-provider-closed-websocket", - "call.forwarding.operator-busy", - "silence-timed-out", - "call.in-progress.error-sip-inbound-call-failed-to-connect", - "call.in-progress.error-providerfault-outbound-sip-403-forbidden", - "call.in-progress.error-providerfault-outbound-sip-407-proxy-authentication-required", - "call.in-progress.error-providerfault-outbound-sip-503-service-unavailable", - "call.in-progress.error-providerfault-outbound-sip-480-temporarily-unavailable", - "call.in-progress.error-sip-outbound-call-failed-to-connect", - "call.ringing.hook-executed-say", - "call.ringing.hook-executed-transfer", - "call.ending.hook-executed-say", - "call.ending.hook-executed-transfer", - "call.ringing.sip-inbound-caller-hungup-before-call-connect", - "call.ringing.error-sip-inbound-call-failed-to-connect", - "twilio-failed-to-connect-call", - "twilio-reported-customer-misdialed", - "vonage-rejected", - "voicemail" - ] - }, - "destination": { - "description": "This is the destination where the call ended up being transferred to. If the call was not transferred, this will be empty.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "id": { - "type": "string", - "description": "This is the unique identifier for the call." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the org that this call belongs to." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the call was created." - }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the call was last updated." - }, - "startedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the call was started." - }, - "endedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the call was ended." - }, - "cost": { - "type": "number", - "description": "This is the cost of the call in USD." - }, - "costBreakdown": { - "description": "This is the cost of the call in USD.", - "allOf": [ - { - "$ref": "#/components/schemas/CostBreakdown" - } - ] - }, - "artifactPlan": { - "description": "This is a copy of assistant artifact plan. This isn't actually stored on the call but rather just returned in POST /call/web to enable artifact creation client side.", - "allOf": [ - { - "$ref": "#/components/schemas/ArtifactPlan" - } - ] - }, - "analysis": { - "description": "This is the analysis of the call. Configure in `assistant.analysisPlan`.", - "allOf": [ - { - "$ref": "#/components/schemas/Analysis" - } - ] - }, - "monitor": { - "description": "This is to real-time monitor the call. Configure in `assistant.monitorPlan`.", - "allOf": [ - { - "$ref": "#/components/schemas/Monitor" - } - ] - }, - "artifact": { - "description": "These are the artifacts created from the call. Configure in `assistant.artifactPlan`.", - "allOf": [ - { - "$ref": "#/components/schemas/Artifact" - } - ] - }, - "phoneCallProviderId": { - "type": "string", - "description": "The ID of the call as provided by the phone number service. callSid in Twilio. conversationUuid in Vonage. callControlId in Telnyx.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "deprecated": true - }, - "campaignId": { - "type": "string", - "description": "This is the campaign ID that the call belongs to." - }, - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" - }, - "assistant": { - "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "assistantOverrides": { - "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] - }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "squad": { - "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateSquadDTO" - } - ] - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "workflow": { - "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateWorkflowDTO" - } - ] - }, - "workflowOverrides": { - "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/WorkflowOverrides" - } - ] - }, - "phoneNumberId": { - "type": "string", - "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." - }, - "phoneNumber": { - "description": "This is the phone number that will be used for the call. To use an existing number, use `phoneNumberId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "allOf": [ - { - "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" - } - ] - }, - "customerId": { - "type": "string", - "description": "This is the customer that will be called. To call a transient customer , use `customer` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." - }, - "customer": { - "description": "This is the customer that will be called. To call an existing customer, use `customerId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateCustomerDTO" - } - ] - }, - "name": { - "type": "string", - "description": "This is the name of the call. This is just for your own reference.", - "maxLength": 40 - }, - "schedulePlan": { - "description": "This is the schedule plan of the call.", - "allOf": [ - { - "$ref": "#/components/schemas/SchedulePlan" - } - ] - }, - "transport": { - "type": "object", - "description": "This is the transport of the call." - } - }, - "required": [ - "id", - "orgId", - "createdAt", - "updatedAt" - ] - }, - "CallBatchError": { - "type": "object", - "properties": { - "customer": { - "$ref": "#/components/schemas/CreateCustomerDTO" - }, - "error": { - "type": "string" - } - }, - "required": [ - "customer", - "error" - ] - }, - "CallBatchResponse": { - "type": "object", - "properties": { - "results": { - "description": "This is the list of calls that were created.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Call" - } - }, - "errors": { - "description": "This is the list of calls that failed to be created.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CallBatchError" - } - } - }, - "required": [ - "results", - "errors" - ] - }, - "CreateCallDTO": { - "type": "object", - "properties": { - "customers": { - "description": "This is used to issue batch calls to multiple customers.\n\nOnly relevant for `outboundPhoneCall`. To call a single customer, use `customer` instead.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CreateCustomerDTO" - } - }, - "name": { - "type": "string", - "description": "This is the name of the call. This is just for your own reference.", - "maxLength": 40 - }, - "schedulePlan": { - "description": "This is the schedule plan of the call.", - "allOf": [ - { - "$ref": "#/components/schemas/SchedulePlan" - } - ] - }, - "transport": { - "type": "object", - "description": "This is the transport of the call." - }, - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" - }, - "assistant": { - "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "assistantOverrides": { - "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] - }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "squad": { - "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateSquadDTO" - } - ] - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "workflow": { - "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateWorkflowDTO" - } - ] - }, - "workflowOverrides": { - "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/WorkflowOverrides" - } - ] - }, - "phoneNumberId": { - "type": "string", - "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." - }, - "phoneNumber": { - "description": "This is the phone number that will be used for the call. To use an existing number, use `phoneNumberId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "allOf": [ - { - "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" - } - ] - }, - "customerId": { - "type": "string", - "description": "This is the customer that will be called. To call a transient customer , use `customer` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." - }, - "customer": { - "description": "This is the customer that will be called. To call an existing customer, use `customerId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateCustomerDTO" } - ] - } - } - }, - "PaginationMeta": { - "type": "object", - "properties": { - "itemsPerPage": { - "type": "number" - }, - "totalItems": { - "type": "number" - }, - "currentPage": { - "type": "number" - }, - "itemsBeyondRetention": { - "type": "boolean" - } - }, - "required": [ - "itemsPerPage", - "totalItems", - "currentPage" - ] - }, - "CallPaginatedResponse": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Call" } }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" - } - }, - "required": [ - "results", - "metadata" - ] - }, - "CreateOutboundCallDTO": { - "type": "object", - "properties": { - "customers": { - "description": "This is used to issue batch calls to multiple customers.\n\nOnly relevant for `outboundPhoneCall`. To call a single customer, use `customer` instead.", + "hooks": { "type": "array", + "description": "This is a set of actions that will be performed on certain events.", "items": { - "$ref": "#/components/schemas/CreateCustomerDTO" + "oneOf": [ + { + "$ref": "#/components/schemas/CallHookCallEnding", + "title": "CallHookCallEnding" + }, + { + "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", + "title": "CallHookAssistantSpeechInterrupted" + }, + { + "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", + "title": "CallHookCustomerSpeechInterrupted" + }, + { + "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", + "title": "CallHookCustomerSpeechTimeout" + } + ] } }, - "name": { - "type": "string", - "description": "This is the name of the call. This is just for your own reference.", - "maxLength": 40 - }, - "schedulePlan": { - "description": "This is the schedule plan of the call.", - "allOf": [ - { - "$ref": "#/components/schemas/SchedulePlan" - } - ] - }, - "transport": { + "variableValues": { "type": "object", - "description": "This is the transport of the call." - }, - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" - }, - "assistant": { - "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "assistantOverrides": { - "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] - }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "squad": { - "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateSquadDTO" - } - ] - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "workflow": { - "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", - "allOf": [ - { - "$ref": "#/components/schemas/CreateWorkflowDTO" - } - ] - }, - "workflowOverrides": { - "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", - "allOf": [ - { - "$ref": "#/components/schemas/WorkflowOverrides" - } - ] + "description": "These are values that will be used to replace the template variables in the assistant messages and other text-based fields.\nThis uses LiquidJS syntax. https://liquidjs.com/tutorials/intro-to-liquid.html\n\nSo for example, `{{ name }}` will be replaced with the value of `name` in `variableValues`.\n`{{\"now\" | date: \"%b %d, %Y, %I:%M %p\", \"America/New_York\"}}` will be replaced with the current date and time in New York.\n Some VAPI reserved defaults:\n - *customer* - the customer object" }, - "phoneNumberId": { + "name": { "type": "string", - "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." + "description": "This is the name of the assistant.\n\nThis is required when you want to transfer between assistants in a call.", + "maxLength": 40 }, - "phoneNumber": { - "description": "This is the phone number that will be used for the call. To use an existing number, use `phoneNumberId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", - "allOf": [ - { - "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" - } - ] + "voicemailMessage": { + "type": "string", + "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", + "maxLength": 1000 }, - "customerId": { + "endCallMessage": { "type": "string", - "description": "This is the customer that will be called. To call a transient customer , use `customer` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." + "description": "This is the message that the assistant will say if it ends the call.\n\nIf unspecified, it will hang up without saying anything.", + "maxLength": 1000 }, - "customer": { - "description": "This is the customer that will be called. To call an existing customer, use `customerId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "endCallPhrases": { + "description": "This list contains phrases that, if spoken by the assistant, will trigger the call to be hung up. Case insensitive.", + "type": "array", + "items": { + "type": "string", + "maxLength": 140, + "minLength": 2 + } + }, + "compliancePlan": { + "$ref": "#/components/schemas/CompliancePlan" + }, + "metadata": { + "type": "object", + "description": "This is for metadata you want to store on the assistant." + }, + "backgroundSpeechDenoisingPlan": { + "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nSmart denoising can be combined with or used independently of Fourier denoising.\n\nOrder of precedence:\n- Smart denoising\n- Fourier denoising", "allOf": [ { - "$ref": "#/components/schemas/CreateCustomerDTO" + "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" } ] - } - } - }, - "CreateWebCallDTO": { - "type": "object", - "properties": { - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" }, - "assistant": { - "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", + "analysisPlan": { + "description": "This is the plan for analysis of assistant's calls. Stored in `call.analysis`.", "allOf": [ { - "$ref": "#/components/schemas/CreateAssistantDTO" + "$ref": "#/components/schemas/AnalysisPlan" } ] }, - "assistantOverrides": { - "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", + "artifactPlan": { + "description": "This is the plan for artifacts generated during assistant's calls. Stored in `call.artifact`.", "allOf": [ { - "$ref": "#/components/schemas/AssistantOverrides" + "$ref": "#/components/schemas/ArtifactPlan" } ] }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "squad": { - "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "startSpeakingPlan": { + "description": "This is the plan for when the assistant should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", "allOf": [ { - "$ref": "#/components/schemas/CreateSquadDTO" + "$ref": "#/components/schemas/StartSpeakingPlan" } ] }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" - }, - "workflow": { - "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "stopSpeakingPlan": { + "description": "This is the plan for when assistant should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", "allOf": [ { - "$ref": "#/components/schemas/CreateWorkflowDTO" + "$ref": "#/components/schemas/StopSpeakingPlan" } ] }, - "workflowOverrides": { - "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", + "monitorPlan": { + "description": "This is the plan for real-time monitoring of the assistant's calls.\n\nUsage:\n- To enable live listening of the assistant's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the assistant's calls, set `monitorPlan.controlEnabled` to `true`.", "allOf": [ { - "$ref": "#/components/schemas/WorkflowOverrides" + "$ref": "#/components/schemas/MonitorPlan" } ] - } - } - }, - "UpdateCallDTO": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the name of the call. This is just for your own reference.", - "maxLength": 40 - } - } - }, - "DeveloperMessage": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "This is the role of the message author", - "default": "developer", - "enum": [ - "developer" - ] - }, - "content": { - "type": "string", - "description": "This is the content of the developer message", - "maxLength": 10000 - }, - "name": { - "type": "string", - "description": "This is an optional name for the participant", - "maxLength": 40 - }, - "metadata": { - "type": "object", - "description": "This is an optional metadata for the message" - } - }, - "required": [ - "role", - "content" - ] - }, - "SystemMessage": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "The role of the system in the conversation." - }, - "message": { - "type": "string", - "description": "The message content from the system." - }, - "time": { - "type": "number", - "description": "The timestamp when the message was sent." - }, - "secondsFromStart": { - "type": "number", - "description": "The number of seconds from the start of the conversation." - } - }, - "required": [ - "role", - "message", - "time", - "secondsFromStart" - ] - }, - "UserMessage": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "The role of the user in the conversation." - }, - "message": { - "type": "string", - "description": "The message content from the user." - }, - "time": { - "type": "number", - "description": "The timestamp when the message was sent." - }, - "endTime": { - "type": "number", - "description": "The timestamp when the message ended." - }, - "secondsFromStart": { - "type": "number", - "description": "The number of seconds from the start of the conversation." - }, - "duration": { - "type": "number", - "description": "The duration of the message in seconds." - }, - "isFiltered": { - "type": "boolean", - "description": "Indicates if the message was filtered for security reasons." }, - "detectedThreats": { - "description": "List of detected security threats if the message was filtered.", + "credentialIds": { + "description": "These are the credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", "type": "array", "items": { "type": "string" } }, - "originalMessage": { - "type": "string", - "description": "The original message before filtering (only included if content was filtered)." - } - }, - "required": [ - "role", - "message", - "time", - "endTime", - "secondsFromStart" - ] - }, - "ToolCallFunction": { - "type": "object", - "properties": { - "arguments": { - "type": "string", - "description": "This is the arguments to call the function with" - }, - "name": { - "type": "string", - "description": "This is the name of the function to call", - "maxLength": 40 - } - }, - "required": [ - "arguments", - "name" - ] - }, - "ToolCall": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "This is the ID of the tool call" - }, - "type": { - "type": "string", - "description": "This is the type of tool" - }, - "function": { - "description": "This is the function that was called", + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server.url\n2. phoneNumber.serverUrl\n3. org.serverUrl", "allOf": [ { - "$ref": "#/components/schemas/ToolCallFunction" + "$ref": "#/components/schemas/Server" } ] - } - }, - "required": [ - "id", - "type", - "function" - ] - }, - "AssistantMessage": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "This is the role of the message author", - "default": "assistant", - "enum": [ - "assistant" - ] - }, - "content": { - "type": "string", - "description": "This is the content of the assistant message", - "maxLength": 10000 - }, - "refusal": { - "type": "string", - "description": "This is the refusal message generated by the model", - "maxLength": 10000 - }, - "tool_calls": { - "description": "This is the tool calls generated by the model", - "type": "array", - "items": { - "$ref": "#/components/schemas/ToolCall" - } - }, - "name": { - "type": "string", - "description": "This is an optional name for the participant", - "maxLength": 40 - }, - "metadata": { - "type": "object", - "description": "This is an optional metadata for the message" - } - }, - "required": [ - "role" - ] - }, - "ToolMessage": { - "type": "object", - "properties": { - "role": { - "type": "string", - "description": "This is the role of the message author", - "default": "tool", - "enum": [ - "tool" - ] - }, - "content": { - "type": "string", - "description": "This is the content of the tool message", - "maxLength": 10000 - }, - "tool_call_id": { - "type": "string", - "description": "This is the ID of the tool call this message is responding to" - }, - "name": { - "type": "string", - "description": "This is an optional name for the participant", - "maxLength": 40 - }, - "metadata": { - "type": "object", - "description": "This is an optional metadata for the message" - } - }, - "required": [ - "role", - "content", - "tool_call_id" - ] - }, - "FunctionCall": { - "type": "object", - "properties": { - "arguments": { - "type": "string", - "description": "This is the arguments to call the function with" }, - "name": { - "type": "string", - "description": "This is the name of the function to call", - "maxLength": 40 + "keypadInputPlan": { + "$ref": "#/components/schemas/KeypadInputPlan" } - }, - "required": [ - "arguments", - "name" - ] + } }, - "Chat": { + "SquadMemberDTO": { "type": "object", "properties": { - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead." - }, - "assistant": { - "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in chat contexts - other assistant properties cannot be overridden.", - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] - }, - "name": { - "type": "string", - "description": "This is the name of the chat. This is just for your own reference.", - "maxLength": 40 - }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." - }, - "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", - "oneOf": [ - { - "type": "string", - "title": "String" - }, - { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - }, - "title": "MessageArray" - } - ], - "examples": [ - "Hello, how can you help me?", - [ - { - "role": "user", - "content": "Hello, how can you help me?" - } - ] - ] - }, - "stream": { - "type": "boolean", - "description": "This is a flag that determines whether the response should be streamed.\nWhen true, the response will be sent as chunks of text.", - "default": false - }, - "previousChatId": { - "type": "string", - "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." - }, - "id": { - "type": "string", - "description": "This is the unique identifier for the chat." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the org that this chat belongs to." - }, - "messages": { - "type": "array", - "description": "This is an array of messages used as context for the chat.\nUsed to provide message history for multi-turn conversations.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - } - }, - "output": { - "type": "array", - "description": "This is the output messages generated by the system in response to the input.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - } - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the chat was created." - }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the chat was last updated." - }, - "costs": { + "assistantDestinations": { "type": "array", - "description": "These are the costs of individual components of the chat in USD.", + "description": "These are the other assistants that this assistant can transfer or handoff to.\n\nSupports both:\n- TransferDestinationAssistant: For transfer call tool (legacy)\n- HandoffDestinationAssistant: For handoff tool (recommended)\n\nIf the assistant already has transfer call or handoff tools, these destinations are just appended to existing ones.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ModelCost", - "title": "ModelCost" + "$ref": "#/components/schemas/TransferDestinationAssistant", + "title": "Transfer Destination" }, { - "$ref": "#/components/schemas/ChatCost", - "title": "ChatCost" + "$ref": "#/components/schemas/HandoffDestinationAssistant", + "title": "Handoff Destination" } ] } }, - "cost": { - "type": "number", - "description": "This is the cost of the chat in USD." - } - }, - "required": [ - "id", - "orgId", - "createdAt", - "updatedAt" - ] - }, - "CreateChatDTO": { - "type": "object", - "properties": { "assistantId": { "type": "string", - "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead." + "nullable": true, + "description": "This is the assistant that will be used for the call. To use a transient assistant, use `assistant` instead." }, "assistant": { - "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead.", + "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.", "allOf": [ { "$ref": "#/components/schemas/CreateAssistantDTO" @@ -28523,1390 +25308,1339 @@ ] }, "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in chat contexts - other assistant properties cannot be overridden.", + "description": "This can be used to override the assistant's settings and provide values for it's template variables.", "allOf": [ { "$ref": "#/components/schemas/AssistantOverrides" } ] - }, + } + } + }, + "CreateSquadDTO": { + "type": "object", + "properties": { "name": { "type": "string", - "description": "This is the name of the chat. This is just for your own reference.", - "maxLength": 40 + "description": "This is the name of the squad." }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." + "members": { + "description": "This is the list of assistants that make up the squad.\n\nThe call will start with the first assistant in the list.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SquadMemberDTO" + } }, - "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.\nThis field is REQUIRED for chat creation.", - "oneOf": [ - { - "type": "string", - "title": "String" - }, + "membersOverrides": { + "description": "This can be used to override all the assistants' settings and provide values for their template variables.\n\nBoth `membersOverrides` and `members[n].assistantOverrides` can be used together. First, `members[n].assistantOverrides` is applied. Then, `membersOverrides` is applied as a global override.", + "allOf": [ { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - }, - "title": "MessageArray" + "$ref": "#/components/schemas/AssistantOverrides" } - ], - "examples": [ - "Hello, how can you help me?", - [ - { - "role": "user", - "content": "Hello, how can you help me?" - } - ] ] - }, - "stream": { - "type": "boolean", - "description": "This is a flag that determines whether the response should be streamed.\nWhen true, the response will be sent as chunks of text.", - "default": false - }, - "previousChatId": { - "type": "string", - "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." } }, "required": [ - "input" + "members" ] }, - "GetChatPaginatedDTO": { + "Squad": { "type": "object", "properties": { - "assistantId": { - "type": "string", - "description": "This is the unique identifier for the assistant that will be used for the chat." - }, - "workflowId": { - "type": "string", - "description": "This is the unique identifier for the workflow that will be used for the chat." - }, - "sessionId": { + "name": { "type": "string", - "description": "This is the unique identifier for the session that will be used for the chat." + "description": "This is the name of the squad." }, - "page": { - "type": "number", - "description": "This is the page number to return. Defaults to 1.", - "minimum": 1 + "members": { + "description": "This is the list of assistants that make up the squad.\n\nThe call will start with the first assistant in the list.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SquadMemberDTO" + } }, - "sortOrder": { - "type": "string", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "enum": [ - "ASC", - "DESC" + "membersOverrides": { + "description": "This can be used to override all the assistants' settings and provide values for their template variables.\n\nBoth `membersOverrides` and `members[n].assistantOverrides` can be used together. First, `members[n].assistantOverrides` is applied. Then, `membersOverrides` is applied as a global override.", + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } ] }, - "limit": { - "type": "number", - "description": "This is the maximum number of items to return. Defaults to 100.", - "minimum": 0, - "maximum": 1000 - }, - "createdAtGt": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is greater than the specified value." - }, - "createdAtLt": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is less than the specified value." - }, - "createdAtGe": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is greater than or equal to the specified value." - }, - "createdAtLe": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is less than or equal to the specified value." - }, - "updatedAtGt": { - "format": "date-time", + "id": { "type": "string", - "description": "This will return items where the updatedAt is greater than the specified value." + "description": "This is the unique identifier for the squad." }, - "updatedAtLt": { - "format": "date-time", + "orgId": { "type": "string", - "description": "This will return items where the updatedAt is less than the specified value." + "description": "This is the unique identifier for the org that this squad belongs to." }, - "updatedAtGe": { + "createdAt": { "format": "date-time", "type": "string", - "description": "This will return items where the updatedAt is greater than or equal to the specified value." + "description": "This is the ISO 8601 date-time string of when the squad was created." }, - "updatedAtLe": { + "updatedAt": { "format": "date-time", "type": "string", - "description": "This will return items where the updatedAt is less than or equal to the specified value." - } - } - }, - "ChatPaginatedResponse": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Chat" - } - }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" + "description": "This is the ISO 8601 date-time string of when the squad was last updated." } }, "required": [ - "results", - "metadata" + "members", + "id", + "orgId", + "createdAt", + "updatedAt" ] }, - "CreateChatStreamResponse": { + "UpdateSquadDTO": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "This is the unique identifier for the streaming response." - }, - "sessionId": { + "name": { "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nHelps track conversation context across multiple messages." + "description": "This is the name of the squad." }, - "path": { - "type": "string", - "description": "This is the path to the content being updated.\nFormat: `chat.output[{contentIndex}].content` where contentIndex identifies the specific content item.", - "example": "chat.output[0].content" + "members": { + "description": "This is the list of assistants that make up the squad.\n\nThe call will start with the first assistant in the list.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SquadMemberDTO" + } }, - "delta": { - "type": "string", - "description": "This is the incremental content chunk being streamed." + "membersOverrides": { + "description": "This can be used to override all the assistants' settings and provide values for their template variables.\n\nBoth `membersOverrides` and `members[n].assistantOverrides` can be used together. First, `members[n].assistantOverrides` is applied. Then, `membersOverrides` is applied as a global override.", + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } + ] } }, "required": [ - "id", - "path", - "delta" + "members" ] }, - "OpenAIResponsesRequest": { + "Workflow": { "type": "object", "properties": { - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead." + "nodes": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ConversationNode", + "title": "ConversationNode" + }, + { + "$ref": "#/components/schemas/ToolNode", + "title": "ToolNode" + } + ] + } }, - "assistant": { - "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead.", - "allOf": [ + "model": { + "description": "This is the model for the workflow.\n\nThis can be overridden at node level using `nodes[n].model`.", + "oneOf": [ { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in chat contexts - other assistant properties cannot be overridden.", - "allOf": [ + "$ref": "#/components/schemas/WorkflowOpenAIModel", + "title": "WorkflowOpenAIModel" + }, { - "$ref": "#/components/schemas/AssistantOverrides" + "$ref": "#/components/schemas/WorkflowAnthropicModel", + "title": "WorkflowAnthropicModel" + }, + { + "$ref": "#/components/schemas/WorkflowGoogleModel", + "title": "WorkflowGoogleModel" + }, + { + "$ref": "#/components/schemas/WorkflowCustomModel", + "title": "WorkflowCustomModel" } ] }, - "name": { - "type": "string", - "description": "This is the name of the chat. This is just for your own reference.", - "maxLength": 40 - }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." - }, - "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.\nThis field is REQUIRED for chat creation.", + "transcriber": { + "description": "This is the transcriber for the workflow.\n\nThis can be overridden at node level using `nodes[n].transcriber`.", "oneOf": [ { - "type": "string", - "title": "String" + "$ref": "#/components/schemas/AssemblyAITranscriber", + "title": "AssemblyAITranscriber" }, { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - }, - "title": "MessageArray" - } - ], - "examples": [ - "Hello, how can you help me?", - [ - { - "role": "user", - "content": "Hello, how can you help me?" - } - ] - ] - }, - "stream": { - "type": "boolean", - "description": "Whether to stream the response or not.", - "default": true - }, - "previousChatId": { - "type": "string", - "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." - } - }, - "required": [ - "input" - ] - }, - "ChatAssistantOverrides": { - "type": "object", - "properties": { - "variableValues": { - "type": "object", - "description": "Variable values for template substitution", - "example": { - "name": "John", - "company": "ACME Corp" - } - } - } - }, - "CreateWebCustomerDTO": { - "type": "object", - "properties": { - "numberE164CheckEnabled": { - "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true - }, - "extension": { - "type": "string", - "description": "This is the extension that will be dialed after the call is answered.", - "maxLength": 10, - "example": null - }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", - "allOf": [ + "$ref": "#/components/schemas/AzureSpeechTranscriber", + "title": "AzureSpeechTranscriber" + }, { - "$ref": "#/components/schemas/ChatAssistantOverrides" + "$ref": "#/components/schemas/CustomTranscriber", + "title": "CustomTranscriber" + }, + { + "$ref": "#/components/schemas/DeepgramTranscriber", + "title": "DeepgramTranscriber" + }, + { + "$ref": "#/components/schemas/ElevenLabsTranscriber", + "title": "ElevenLabsTranscriber" + }, + { + "$ref": "#/components/schemas/GladiaTranscriber", + "title": "GladiaTranscriber" + }, + { + "$ref": "#/components/schemas/GoogleTranscriber", + "title": "GoogleTranscriber" + }, + { + "$ref": "#/components/schemas/SpeechmaticsTranscriber", + "title": "SpeechmaticsTranscriber" + }, + { + "$ref": "#/components/schemas/TalkscriberTranscriber", + "title": "TalkscriberTranscriber" + }, + { + "$ref": "#/components/schemas/OpenAITranscriber", + "title": "OpenAITranscriber" + }, + { + "$ref": "#/components/schemas/CartesiaTranscriber", + "title": "CartesiaTranscriber" } ] }, - "number": { - "type": "string", - "description": "This is the number of the customer.", - "minLength": 3, - "maxLength": 40 - }, - "sipUri": { - "type": "string", - "description": "This is the SIP URI of the customer." - }, - "name": { - "type": "string", - "description": "This is the name of the customer. This is just for your own reference.\n\nFor SIP inbound calls, this is extracted from the `From` SIP header with format `\"Display Name\" `.", - "maxLength": 40 - }, - "email": { - "type": "string", - "description": "This is the email of the customer.", - "maxLength": 40 - }, - "externalId": { - "type": "string", - "description": "This is the external ID of the customer.", - "maxLength": 40 - } - } - }, - "CreateWebChatDTO": { - "type": "object", - "properties": { - "assistantId": { - "type": "string", - "description": "The assistant ID to use for this chat" - }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nIf provided, the conversation will continue from the previous state.\nIf not provided or expired, a new session will be created." - }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", - "allOf": [ + "voice": { + "description": "This is the voice for the workflow.\n\nThis can be overridden at node level using `nodes[n].voice`.", + "oneOf": [ + { + "$ref": "#/components/schemas/AzureVoice", + "title": "AzureVoice" + }, + { + "$ref": "#/components/schemas/CartesiaVoice", + "title": "CartesiaVoice" + }, + { + "$ref": "#/components/schemas/CustomVoice", + "title": "CustomVoice" + }, + { + "$ref": "#/components/schemas/DeepgramVoice", + "title": "DeepgramVoice" + }, + { + "$ref": "#/components/schemas/ElevenLabsVoice", + "title": "ElevenLabsVoice" + }, + { + "$ref": "#/components/schemas/HumeVoice", + "title": "HumeVoice" + }, + { + "$ref": "#/components/schemas/LMNTVoice", + "title": "LMNTVoice" + }, + { + "$ref": "#/components/schemas/NeuphonicVoice", + "title": "NeuphonicVoice" + }, + { + "$ref": "#/components/schemas/OpenAIVoice", + "title": "OpenAIVoice" + }, + { + "$ref": "#/components/schemas/PlayHTVoice", + "title": "PlayHTVoice" + }, + { + "$ref": "#/components/schemas/RimeAIVoice", + "title": "RimeAIVoice" + }, { - "$ref": "#/components/schemas/ChatAssistantOverrides" + "$ref": "#/components/schemas/SmallestAIVoice", + "title": "SmallestAIVoice" + }, + { + "$ref": "#/components/schemas/TavusVoice", + "title": "TavusVoice" + }, + { + "$ref": "#/components/schemas/VapiVoice", + "title": "VapiVoice" + }, + { + "$ref": "#/components/schemas/SesameVoice", + "title": "SesameVoice" + }, + { + "$ref": "#/components/schemas/InworldVoice", + "title": "InworldVoice" + }, + { + "$ref": "#/components/schemas/MinimaxVoice", + "title": "MinimaxVoice" } ] }, - "customer": { - "description": "This is the customer information for the chat.\nUsed to automatically manage sessions for repeat customers.", + "observabilityPlan": { + "description": "This is the plan for observability of workflow's calls.\n\nCurrently, only Langfuse is supported.", + "oneOf": [ + { + "$ref": "#/components/schemas/LangfuseObservabilityPlan", + "title": "Langfuse" + } + ], "allOf": [ { - "$ref": "#/components/schemas/CreateWebCustomerDTO" + "$ref": "#/components/schemas/LangfuseObservabilityPlan" } ] }, - "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", + "backgroundSound": { + "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", "oneOf": [ { - "type": "string", - "title": "String" + "type": "enum", + "enum": [ + "off", + "office" + ], + "example": "office" }, { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - }, - "title": "MessageArray" + "type": "string", + "format": "uri", + "example": "https://www.soundjay.com/ambient/sounds/people-in-lounge-1.mp3" } - ], - "examples": [ - "Hello, how can you help me?", - [ - { - "role": "user", - "content": "Hello, how can you help me?" - } - ] ] }, - "stream": { - "type": "boolean", - "description": "This is a flag that determines whether the response should be streamed.\nWhen true, the response will be sent as chunks of text.", - "default": false - } - }, - "required": [ - "assistantId", - "input" - ] - }, - "WebChat": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "This is the unique identifier for the chat." - }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session for the chat. Send it in the next chat request to continue the conversation." - }, - "output": { + "hooks": { "type": "array", - "description": "This is the output messages generated by the system in response to the input.", + "description": "This is a set of actions that will be performed on certain events.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" + "$ref": "#/components/schemas/CallHookCallEnding", + "title": "CallHookCallEnding" }, { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" + "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", + "title": "CallHookAssistantSpeechInterrupted" }, { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" + "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", + "title": "CallHookCustomerSpeechInterrupted" }, { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" + "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", + "title": "CallHookCustomerSpeechTimeout" } ] } - } - }, - "required": [ - "id", - "output" - ] - }, - "OpenAIWebChatRequest": { - "type": "object", - "properties": { - "assistantId": { - "type": "string", - "description": "The assistant ID to use for this chat" - }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nIf provided, the conversation will continue from the previous state.\nIf not provided or expired, a new session will be created." - }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", - "allOf": [ - { - "$ref": "#/components/schemas/ChatAssistantOverrides" - } - ] - }, - "customer": { - "description": "This is the customer information for the chat.\nUsed to automatically manage sessions for repeat customers.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateWebCustomerDTO" - } - ] }, - "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", - "oneOf": [ - { - "type": "string", - "title": "String" - }, - { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] + "credentials": { + "type": "array", + "description": "These are dynamic credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/CreateAnthropicCredentialDTO", + "title": "AnthropicCredential" }, - "title": "MessageArray" - } - ], - "examples": [ - "Hello, how can you help me?", - [ { - "role": "user", - "content": "Hello, how can you help me?" + "$ref": "#/components/schemas/CreateAnyscaleCredentialDTO", + "title": "AnyscaleCredential" + }, + { + "$ref": "#/components/schemas/CreateAssemblyAICredentialDTO", + "title": "AssemblyAICredential" + }, + { + "$ref": "#/components/schemas/CreateAzureCredentialDTO", + "title": "AzureCredential" + }, + { + "$ref": "#/components/schemas/CreateAzureOpenAICredentialDTO", + "title": "AzureOpenAICredential" + }, + { + "$ref": "#/components/schemas/CreateByoSipTrunkCredentialDTO", + "title": "ByoSipTrunkCredential" + }, + { + "$ref": "#/components/schemas/CreateCartesiaCredentialDTO", + "title": "CartesiaCredential" + }, + { + "$ref": "#/components/schemas/CreateCerebrasCredentialDTO", + "title": "CerebrasCredential" + }, + { + "$ref": "#/components/schemas/CreateCloudflareCredentialDTO", + "title": "CloudflareCredential" + }, + { + "$ref": "#/components/schemas/CreateCustomLLMCredentialDTO", + "title": "CustomLLMCredential" + }, + { + "$ref": "#/components/schemas/CreateDeepgramCredentialDTO", + "title": "DeepgramCredential" + }, + { + "$ref": "#/components/schemas/CreateDeepInfraCredentialDTO", + "title": "DeepInfraCredential" + }, + { + "$ref": "#/components/schemas/CreateDeepSeekCredentialDTO", + "title": "DeepSeekCredential" + }, + { + "$ref": "#/components/schemas/CreateElevenLabsCredentialDTO", + "title": "ElevenLabsCredential" + }, + { + "$ref": "#/components/schemas/CreateGcpCredentialDTO", + "title": "GcpCredential" + }, + { + "$ref": "#/components/schemas/CreateGladiaCredentialDTO", + "title": "GladiaCredential" + }, + { + "$ref": "#/components/schemas/CreateGoHighLevelCredentialDTO", + "title": "GhlCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCredentialDTO", + "title": "GoogleCredential" + }, + { + "$ref": "#/components/schemas/CreateGroqCredentialDTO", + "title": "GroqCredential" + }, + { + "$ref": "#/components/schemas/CreateHumeCredentialDTO", + "title": "HumeCredential" + }, + { + "$ref": "#/components/schemas/CreateInflectionAICredentialDTO", + "title": "InflectionAICredential" + }, + { + "$ref": "#/components/schemas/CreateLangfuseCredentialDTO", + "title": "LangfuseCredential" + }, + { + "$ref": "#/components/schemas/CreateLmntCredentialDTO", + "title": "LmntCredential" + }, + { + "$ref": "#/components/schemas/CreateMakeCredentialDTO", + "title": "MakeCredential" + }, + { + "$ref": "#/components/schemas/CreateMistralCredentialDTO", + "title": "MistralCredential" + }, + { + "$ref": "#/components/schemas/CreateNeuphonicCredentialDTO", + "title": "NeuphonicCredential" + }, + { + "$ref": "#/components/schemas/CreateOpenAICredentialDTO", + "title": "OpenAICredential" + }, + { + "$ref": "#/components/schemas/CreateOpenRouterCredentialDTO", + "title": "OpenRouterCredential" + }, + { + "$ref": "#/components/schemas/CreatePerplexityAICredentialDTO", + "title": "PerplexityAICredential" + }, + { + "$ref": "#/components/schemas/CreatePlayHTCredentialDTO", + "title": "PlayHTCredential" + }, + { + "$ref": "#/components/schemas/CreateRimeAICredentialDTO", + "title": "RimeAICredential" + }, + { + "$ref": "#/components/schemas/CreateRunpodCredentialDTO", + "title": "RunpodCredential" + }, + { + "$ref": "#/components/schemas/CreateS3CredentialDTO", + "title": "S3Credential" + }, + { + "$ref": "#/components/schemas/CreateSmallestAICredentialDTO", + "title": "SmallestAICredential" + }, + { + "$ref": "#/components/schemas/CreateSpeechmaticsCredentialDTO", + "title": "SpeechmaticsCredential" + }, + { + "$ref": "#/components/schemas/CreateSupabaseCredentialDTO", + "title": "SupabaseCredential" + }, + { + "$ref": "#/components/schemas/CreateTavusCredentialDTO", + "title": "TavusCredential" + }, + { + "$ref": "#/components/schemas/CreateTogetherAICredentialDTO", + "title": "TogetherAICredential" + }, + { + "$ref": "#/components/schemas/CreateTrieveCredentialDTO", + "title": "TrieveCredential" + }, + { + "$ref": "#/components/schemas/CreateTwilioCredentialDTO", + "title": "TwilioCredential" + }, + { + "$ref": "#/components/schemas/CreateVonageCredentialDTO", + "title": "VonageCredential" + }, + { + "$ref": "#/components/schemas/CreateWebhookCredentialDTO", + "title": "WebhookCredential" + }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, + { + "$ref": "#/components/schemas/CreateXAiCredentialDTO", + "title": "XAiCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", + "title": "GoogleCalendarOAuth2ClientCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", + "title": "GoogleCalendarOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", + "title": "GoogleSheetsOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", + "title": "SlackOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", + "title": "GoHighLevelMCPCredential" + }, + { + "$ref": "#/components/schemas/CreateInworldCredentialDTO", + "title": "InworldCredential" } - ] - ] - }, - "stream": { - "type": "boolean", - "description": "Whether to stream the response or not.", - "default": true - } - }, - "required": [ - "assistantId", - "input" - ] - }, - "ResponseOutputText": { - "type": "object", - "properties": { - "annotations": { - "default": [], - "description": "Annotations in the text output", - "type": "array", - "items": { - "type": "object" - } - }, - "text": { - "type": "string", - "description": "The text output from the model" - }, - "type": { - "type": "string", - "default": "output_text", - "description": "The type of the output text", - "enum": [ - "output_text" - ] - } - }, - "required": [ - "annotations", - "text", - "type" - ] - }, - "ResponseOutputMessage": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The unique ID of the output message" - }, - "content": { - "description": "Content of the output message", - "type": "array", - "items": { - "$ref": "#/components/schemas/ResponseOutputText" + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "11labs": "#/components/schemas/CreateElevenLabsCredentialDTO", + "anthropic": "#/components/schemas/CreateAnthropicCredentialDTO", + "anyscale": "#/components/schemas/CreateAnyscaleCredentialDTO", + "assembly-ai": "#/components/schemas/CreateAssemblyAICredentialDTO", + "azure-openai": "#/components/schemas/CreateAzureOpenAICredentialDTO", + "azure": "#/components/schemas/CreateAzureCredentialDTO", + "byo-sip-trunk": "#/components/schemas/CreateByoSipTrunkCredentialDTO", + "cartesia": "#/components/schemas/CreateCartesiaCredentialDTO", + "cerebras": "#/components/schemas/CreateCerebrasCredentialDTO", + "cloudflare": "#/components/schemas/CreateCloudflareCredentialDTO", + "custom-llm": "#/components/schemas/CreateCustomLLMCredentialDTO", + "deepgram": "#/components/schemas/CreateDeepgramCredentialDTO", + "deepinfra": "#/components/schemas/CreateDeepInfraCredentialDTO", + "deep-seek": "#/components/schemas/CreateDeepSeekCredentialDTO", + "gcp": "#/components/schemas/CreateGcpCredentialDTO", + "gladia": "#/components/schemas/CreateGladiaCredentialDTO", + "gohighlevel": "#/components/schemas/CreateGoHighLevelCredentialDTO", + "google": "#/components/schemas/CreateGoogleCredentialDTO", + "groq": "#/components/schemas/CreateGroqCredentialDTO", + "inflection-ai": "#/components/schemas/CreateInflectionAICredentialDTO", + "langfuse": "#/components/schemas/CreateLangfuseCredentialDTO", + "lmnt": "#/components/schemas/CreateLmntCredentialDTO", + "make": "#/components/schemas/CreateMakeCredentialDTO", + "openai": "#/components/schemas/CreateOpenAICredentialDTO", + "openrouter": "#/components/schemas/CreateOpenRouterCredentialDTO", + "perplexity-ai": "#/components/schemas/CreatePerplexityAICredentialDTO", + "playht": "#/components/schemas/CreatePlayHTCredentialDTO", + "rime-ai": "#/components/schemas/CreateRimeAICredentialDTO", + "runpod": "#/components/schemas/CreateRunpodCredentialDTO", + "s3": "#/components/schemas/CreateS3CredentialDTO", + "supabase": "#/components/schemas/CreateSupabaseCredentialDTO", + "smallest-ai": "#/components/schemas/CreateSmallestAICredentialDTO", + "tavus": "#/components/schemas/CreateTavusCredentialDTO", + "together-ai": "#/components/schemas/CreateTogetherAICredentialDTO", + "twilio": "#/components/schemas/CreateTwilioCredentialDTO", + "vonage": "#/components/schemas/CreateVonageCredentialDTO", + "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", + "xai": "#/components/schemas/CreateXAiCredentialDTO", + "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", + "hume": "#/components/schemas/CreateHumeCredentialDTO", + "mistral": "#/components/schemas/CreateMistralCredentialDTO", + "speechmatics": "#/components/schemas/CreateSpeechmaticsCredentialDTO", + "trieve": "#/components/schemas/CreateTrieveCredentialDTO", + "google.calendar.oauth2-client": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", + "google.calendar.oauth2-authorization": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", + "google.sheets.oauth2-authorization": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", + "slack.oauth2-authorization": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", + "ghl.oauth2-authorization": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", + "inworld": "#/components/schemas/CreateInworldCredentialDTO", + "minimax": "#/components/schemas/CreateMinimaxCredentialDTO" + } + } } }, - "role": { - "type": "string", - "default": "assistant", - "description": "The role of the output message", - "enum": [ - "assistant" - ] - }, - "status": { - "type": "string", - "description": "The status of the message", - "enum": [ - "in_progress", - "completed", - "incomplete" - ] - }, - "type": { - "type": "string", - "default": "message", - "description": "The type of the output message", - "enum": [ - "message" - ] - } - }, - "required": [ - "id", - "content", - "role", - "status", - "type" - ] - }, - "ResponseObject": { - "type": "object", - "properties": { "id": { - "type": "string", - "description": "Unique identifier for this Response" + "type": "string" }, - "object": { - "type": "string", - "default": "response", - "description": "The object type", - "enum": [ - "response" - ] + "orgId": { + "type": "string" }, - "created_at": { - "type": "number", - "description": "Unix timestamp (in seconds) of when this Response was created" + "createdAt": { + "format": "date-time", + "type": "string" }, - "status": { - "type": "string", - "description": "Status of the response", - "enum": [ - "completed", - "failed", - "in_progress", - "incomplete" - ] + "updatedAt": { + "format": "date-time", + "type": "string" }, - "error": { + "name": { "type": "string", - "nullable": true, - "default": null, - "description": "Error message if the response failed" + "maxLength": 80 }, - "output": { - "description": "Output messages from the model", + "edges": { "type": "array", "items": { - "$ref": "#/components/schemas/ResponseOutputMessage" + "$ref": "#/components/schemas/Edge" } - } - }, - "required": [ - "id", - "object", - "created_at", - "status", - "output" - ] - }, - "ResponseTextDeltaEvent": { - "type": "object", - "properties": { - "content_index": { - "type": "number", - "description": "Index of the content part" - }, - "delta": { - "type": "string", - "description": "Text delta being added" }, - "item_id": { + "globalPrompt": { "type": "string", - "description": "ID of the output item" - }, - "output_index": { - "type": "number", - "description": "Index of the output item" + "maxLength": 5000 }, - "type": { - "type": "string", - "default": "response.output_text.delta", - "description": "Event type", - "enum": [ - "response.output_text.delta" + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. tool.server\n2. workflow.server / assistant.server\n3. phoneNumber.server\n4. org.server", + "allOf": [ + { + "$ref": "#/components/schemas/Server" + } ] - } - }, - "required": [ - "content_index", - "delta", - "item_id", - "output_index", - "type" - ] - }, - "ResponseTextDoneEvent": { - "type": "object", - "properties": { - "content_index": { - "type": "number", - "description": "Index of the content part" - }, - "item_id": { - "type": "string", - "description": "ID of the output item" - }, - "output_index": { - "type": "number", - "description": "Index of the output item" - }, - "text": { - "type": "string", - "description": "Complete text content" }, - "type": { - "type": "string", - "default": "response.output_text.done", - "description": "Event type", - "enum": [ - "response.output_text.done" - ] - } - }, - "required": [ - "content_index", - "item_id", - "output_index", - "text", - "type" - ] - }, - "ResponseCompletedEvent": { - "type": "object", - "properties": { - "response": { - "description": "The completed response", + "compliancePlan": { + "description": "This is the compliance plan for the workflow. It allows you to configure HIPAA and other compliance settings.", "allOf": [ { - "$ref": "#/components/schemas/ResponseObject" + "$ref": "#/components/schemas/CompliancePlan" } ] }, - "type": { - "type": "string", - "default": "response.completed", - "description": "Event type", - "enum": [ - "response.completed" - ] - } - }, - "required": [ - "response", - "type" - ] - }, - "ResponseErrorEvent": { - "type": "object", - "properties": { - "type": { - "type": "string", - "default": "error", - "description": "Event type", - "enum": [ - "error" + "analysisPlan": { + "description": "This is the plan for analysis of workflow's calls. Stored in `call.analysis`.", + "allOf": [ + { + "$ref": "#/components/schemas/AnalysisPlan" + } ] }, - "code": { - "type": "string", - "description": "Error code", - "example": "ERR_SOMETHING" - }, - "message": { - "type": "string", - "description": "Error message", - "example": "Something went wrong" - }, - "param": { - "type": "string", - "nullable": true, - "description": "Parameter that caused the error" - }, - "sequence_number": { - "type": "number", - "description": "Sequence number of the event", - "example": 1 - } - }, - "required": [ - "type", - "code", - "message", - "sequence_number" - ] - }, - "CreateCampaignDTO": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the name of the campaign. This is just for your own reference.", - "example": "Q2 Sales Campaign" - }, - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." - }, - "phoneNumberId": { - "type": "string", - "description": "This is the phone number ID that will be used for the campaign calls." - }, - "schedulePlan": { - "description": "This is the schedule plan for the campaign.", + "artifactPlan": { + "description": "This is the plan for artifacts generated during workflow's calls. Stored in `call.artifact`.", "allOf": [ { - "$ref": "#/components/schemas/SchedulePlan" + "$ref": "#/components/schemas/ArtifactPlan" } ] }, - "customers": { - "description": "These are the customers that will be called in the campaign.", - "type": "array", - "items": { - "$ref": "#/components/schemas/CreateCustomerDTO" - } - } - }, - "required": [ - "name", - "phoneNumberId", - "customers" - ] - }, - "Campaign": { - "type": "object", - "properties": { - "status": { - "type": "string", - "description": "This is the status of the campaign.", - "enum": [ - "scheduled", - "in-progress", - "ended" + "startSpeakingPlan": { + "description": "This is the plan for when the workflow nodes should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", + "allOf": [ + { + "$ref": "#/components/schemas/StartSpeakingPlan" + } ] }, - "endedReason": { - "type": "string", - "description": "This is the explanation for how the campaign ended.", - "enum": [ - "campaign.scheduled.ended-by-user", - "campaign.in-progress.ended-by-user", - "campaign.ended.success" + "stopSpeakingPlan": { + "description": "This is the plan for when workflow nodes should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", + "allOf": [ + { + "$ref": "#/components/schemas/StopSpeakingPlan" + } ] }, - "name": { - "type": "string", - "description": "This is the name of the campaign. This is just for your own reference.", - "example": "Q2 Sales Campaign" - }, - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." - }, - "phoneNumberId": { - "type": "string", - "description": "This is the phone number ID that will be used for the campaign calls." + "monitorPlan": { + "description": "This is the plan for real-time monitoring of the workflow's calls.\n\nUsage:\n- To enable live listening of the workflow's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the workflow's calls, set `monitorPlan.controlEnabled` to `true`.", + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPlan" + } + ] }, - "schedulePlan": { - "description": "This is the schedule plan for the campaign.", + "backgroundSpeechDenoisingPlan": { + "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nBoth can be used together. Order of precedence:\n- Smart denoising\n- Fourier denoising", "allOf": [ { - "$ref": "#/components/schemas/SchedulePlan" + "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" } ] }, - "customers": { - "description": "These are the customers that will be called in the campaign.", + "credentialIds": { + "description": "These are the credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", "type": "array", "items": { - "$ref": "#/components/schemas/CreateCustomerDTO" + "type": "string" } }, - "id": { - "type": "string", - "description": "This is the unique identifier for the campaign." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the org that this campaign belongs to." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the campaign was created." - }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the campaign was last updated." - }, - "calls": { - "type": "object", - "description": "This is a map of call IDs to campaign call details." - }, - "callsCounterScheduled": { - "type": "number", - "description": "This is the number of calls that have been scheduled." - }, - "callsCounterQueued": { - "type": "number", - "description": "This is the number of calls that have been queued." - }, - "callsCounterInProgress": { - "type": "number", - "description": "This is the number of calls that have been in progress." - }, - "callsCounterEndedVoicemail": { - "type": "number", - "description": "This is the number of calls whose ended reason is 'voicemail'." - }, - "callsCounterEnded": { - "type": "number", - "description": "This is the number of calls that have ended." + "keypadInputPlan": { + "description": "This is the plan for keypad input handling during workflow calls.", + "allOf": [ + { + "$ref": "#/components/schemas/KeypadInputPlan" + } + ] } }, "required": [ - "status", - "name", - "phoneNumberId", - "customers", + "nodes", "id", "orgId", "createdAt", "updatedAt", - "calls", - "callsCounterScheduled", - "callsCounterQueued", - "callsCounterInProgress", - "callsCounterEndedVoicemail", - "callsCounterEnded" + "name", + "edges" ] }, - "CampaignPaginatedResponse": { + "CreateWorkflowDTO": { "type": "object", "properties": { - "results": { + "nodes": { "type": "array", "items": { - "$ref": "#/components/schemas/Campaign" + "oneOf": [ + { + "$ref": "#/components/schemas/ConversationNode", + "title": "ConversationNode" + }, + { + "$ref": "#/components/schemas/ToolNode", + "title": "ToolNode" + } + ] } }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" - } - }, - "required": [ - "results", - "metadata" - ] - }, - "UpdateCampaignDTO": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the name of the campaign. This is just for your own reference." - }, - "assistantId": { - "type": "string", - "description": "This is the assistant ID that will be used for the campaign calls.\nCan only be updated if campaign is not in progress or has ended." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow ID that will be used for the campaign calls.\nCan only be updated if campaign is not in progress or has ended." + "model": { + "description": "This is the model for the workflow.\n\nThis can be overridden at node level using `nodes[n].model`.", + "oneOf": [ + { + "$ref": "#/components/schemas/WorkflowOpenAIModel", + "title": "WorkflowOpenAIModel" + }, + { + "$ref": "#/components/schemas/WorkflowAnthropicModel", + "title": "WorkflowAnthropicModel" + }, + { + "$ref": "#/components/schemas/WorkflowGoogleModel", + "title": "WorkflowGoogleModel" + }, + { + "$ref": "#/components/schemas/WorkflowCustomModel", + "title": "WorkflowCustomModel" + } + ] }, - "phoneNumberId": { - "type": "string", - "description": "This is the phone number ID that will be used for the campaign calls.\nCan only be updated if campaign is not in progress or has ended." + "transcriber": { + "description": "This is the transcriber for the workflow.\n\nThis can be overridden at node level using `nodes[n].transcriber`.", + "oneOf": [ + { + "$ref": "#/components/schemas/AssemblyAITranscriber", + "title": "AssemblyAITranscriber" + }, + { + "$ref": "#/components/schemas/AzureSpeechTranscriber", + "title": "AzureSpeechTranscriber" + }, + { + "$ref": "#/components/schemas/CustomTranscriber", + "title": "CustomTranscriber" + }, + { + "$ref": "#/components/schemas/DeepgramTranscriber", + "title": "DeepgramTranscriber" + }, + { + "$ref": "#/components/schemas/ElevenLabsTranscriber", + "title": "ElevenLabsTranscriber" + }, + { + "$ref": "#/components/schemas/GladiaTranscriber", + "title": "GladiaTranscriber" + }, + { + "$ref": "#/components/schemas/GoogleTranscriber", + "title": "GoogleTranscriber" + }, + { + "$ref": "#/components/schemas/SpeechmaticsTranscriber", + "title": "SpeechmaticsTranscriber" + }, + { + "$ref": "#/components/schemas/TalkscriberTranscriber", + "title": "TalkscriberTranscriber" + }, + { + "$ref": "#/components/schemas/OpenAITranscriber", + "title": "OpenAITranscriber" + }, + { + "$ref": "#/components/schemas/CartesiaTranscriber", + "title": "CartesiaTranscriber" + } + ] }, - "schedulePlan": { - "description": "This is the schedule plan for the campaign.\nCan only be updated if campaign is not in progress or has ended.", - "allOf": [ + "voice": { + "description": "This is the voice for the workflow.\n\nThis can be overridden at node level using `nodes[n].voice`.", + "oneOf": [ { - "$ref": "#/components/schemas/SchedulePlan" + "$ref": "#/components/schemas/AzureVoice", + "title": "AzureVoice" + }, + { + "$ref": "#/components/schemas/CartesiaVoice", + "title": "CartesiaVoice" + }, + { + "$ref": "#/components/schemas/CustomVoice", + "title": "CustomVoice" + }, + { + "$ref": "#/components/schemas/DeepgramVoice", + "title": "DeepgramVoice" + }, + { + "$ref": "#/components/schemas/ElevenLabsVoice", + "title": "ElevenLabsVoice" + }, + { + "$ref": "#/components/schemas/HumeVoice", + "title": "HumeVoice" + }, + { + "$ref": "#/components/schemas/LMNTVoice", + "title": "LMNTVoice" + }, + { + "$ref": "#/components/schemas/NeuphonicVoice", + "title": "NeuphonicVoice" + }, + { + "$ref": "#/components/schemas/OpenAIVoice", + "title": "OpenAIVoice" + }, + { + "$ref": "#/components/schemas/PlayHTVoice", + "title": "PlayHTVoice" + }, + { + "$ref": "#/components/schemas/RimeAIVoice", + "title": "RimeAIVoice" + }, + { + "$ref": "#/components/schemas/SmallestAIVoice", + "title": "SmallestAIVoice" + }, + { + "$ref": "#/components/schemas/TavusVoice", + "title": "TavusVoice" + }, + { + "$ref": "#/components/schemas/VapiVoice", + "title": "VapiVoice" + }, + { + "$ref": "#/components/schemas/SesameVoice", + "title": "SesameVoice" + }, + { + "$ref": "#/components/schemas/InworldVoice", + "title": "InworldVoice" + }, + { + "$ref": "#/components/schemas/MinimaxVoice", + "title": "MinimaxVoice" } ] }, - "status": { - "type": "string", - "description": "This is the status of the campaign.\nCan only be updated to 'ended' if you want to end the campaign.\nWhen set to 'ended', it will delete all scheduled calls. Calls in progress will be allowed to complete.", - "enum": [ - "ended" - ] - } - } - }, - "Session": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "This is the unique identifier for the session." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization that owns this session." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 timestamp indicating when the session was created." - }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 timestamp indicating when the session was last updated." - }, - "name": { - "type": "string", - "description": "This is a user-defined name for the session. Maximum length is 40 characters.", - "maxLength": 40 - }, - "status": { - "type": "string", - "description": "This is the current status of the session. Can be either 'active' or 'completed'.", - "enum": [ - "active", - "completed" + "observabilityPlan": { + "description": "This is the plan for observability of workflow's calls.\n\nCurrently, only Langfuse is supported.", + "oneOf": [ + { + "$ref": "#/components/schemas/LangfuseObservabilityPlan", + "title": "Langfuse" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/LangfuseObservabilityPlan" + } ] }, - "expirationSeconds": { - "type": "number", - "description": "Session expiration time in seconds. Defaults to 24 hours (86400 seconds) if not set.", - "minimum": 60, - "maximum": 2592000, - "example": 86400 - }, - "assistantId": { - "type": "string", - "description": "This is the ID of the assistant associated with this session. Use this when referencing an existing assistant." - }, - "assistant": { - "description": "This is the assistant configuration for this session. Use this when creating a new assistant configuration.\nIf assistantId is provided, this will be ignored.", - "allOf": [ + "backgroundSound": { + "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", + "oneOf": [ { - "$ref": "#/components/schemas/CreateAssistantDTO" + "type": "enum", + "enum": [ + "off", + "office" + ], + "example": "office" + }, + { + "type": "string", + "format": "uri", + "example": "https://www.soundjay.com/ambient/sounds/people-in-lounge-1.mp3" } ] }, - "messages": { + "hooks": { "type": "array", - "description": "This is an array of chat messages in the session.", + "description": "This is a set of actions that will be performed on certain events.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" + "$ref": "#/components/schemas/CallHookCallEnding", + "title": "CallHookCallEnding" }, { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" + "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", + "title": "CallHookAssistantSpeechInterrupted" }, { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" + "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", + "title": "CallHookCustomerSpeechInterrupted" }, { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" + "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", + "title": "CallHookCustomerSpeechTimeout" + } + ] + } + }, + "credentials": { + "type": "array", + "description": "These are dynamic credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/CreateAnthropicCredentialDTO", + "title": "AnthropicCredential" }, { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" + "$ref": "#/components/schemas/CreateAnyscaleCredentialDTO", + "title": "AnyscaleCredential" + }, + { + "$ref": "#/components/schemas/CreateAssemblyAICredentialDTO", + "title": "AssemblyAICredential" + }, + { + "$ref": "#/components/schemas/CreateAzureCredentialDTO", + "title": "AzureCredential" + }, + { + "$ref": "#/components/schemas/CreateAzureOpenAICredentialDTO", + "title": "AzureOpenAICredential" + }, + { + "$ref": "#/components/schemas/CreateByoSipTrunkCredentialDTO", + "title": "ByoSipTrunkCredential" + }, + { + "$ref": "#/components/schemas/CreateCartesiaCredentialDTO", + "title": "CartesiaCredential" + }, + { + "$ref": "#/components/schemas/CreateCerebrasCredentialDTO", + "title": "CerebrasCredential" + }, + { + "$ref": "#/components/schemas/CreateCloudflareCredentialDTO", + "title": "CloudflareCredential" + }, + { + "$ref": "#/components/schemas/CreateCustomLLMCredentialDTO", + "title": "CustomLLMCredential" + }, + { + "$ref": "#/components/schemas/CreateDeepgramCredentialDTO", + "title": "DeepgramCredential" + }, + { + "$ref": "#/components/schemas/CreateDeepInfraCredentialDTO", + "title": "DeepInfraCredential" + }, + { + "$ref": "#/components/schemas/CreateDeepSeekCredentialDTO", + "title": "DeepSeekCredential" + }, + { + "$ref": "#/components/schemas/CreateElevenLabsCredentialDTO", + "title": "ElevenLabsCredential" + }, + { + "$ref": "#/components/schemas/CreateGcpCredentialDTO", + "title": "GcpCredential" + }, + { + "$ref": "#/components/schemas/CreateGladiaCredentialDTO", + "title": "GladiaCredential" + }, + { + "$ref": "#/components/schemas/CreateGoHighLevelCredentialDTO", + "title": "GhlCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCredentialDTO", + "title": "GoogleCredential" + }, + { + "$ref": "#/components/schemas/CreateGroqCredentialDTO", + "title": "GroqCredential" + }, + { + "$ref": "#/components/schemas/CreateHumeCredentialDTO", + "title": "HumeCredential" + }, + { + "$ref": "#/components/schemas/CreateInflectionAICredentialDTO", + "title": "InflectionAICredential" + }, + { + "$ref": "#/components/schemas/CreateLangfuseCredentialDTO", + "title": "LangfuseCredential" + }, + { + "$ref": "#/components/schemas/CreateLmntCredentialDTO", + "title": "LmntCredential" + }, + { + "$ref": "#/components/schemas/CreateMakeCredentialDTO", + "title": "MakeCredential" + }, + { + "$ref": "#/components/schemas/CreateMistralCredentialDTO", + "title": "MistralCredential" + }, + { + "$ref": "#/components/schemas/CreateNeuphonicCredentialDTO", + "title": "NeuphonicCredential" + }, + { + "$ref": "#/components/schemas/CreateOpenAICredentialDTO", + "title": "OpenAICredential" + }, + { + "$ref": "#/components/schemas/CreateOpenRouterCredentialDTO", + "title": "OpenRouterCredential" + }, + { + "$ref": "#/components/schemas/CreatePerplexityAICredentialDTO", + "title": "PerplexityAICredential" + }, + { + "$ref": "#/components/schemas/CreatePlayHTCredentialDTO", + "title": "PlayHTCredential" + }, + { + "$ref": "#/components/schemas/CreateRimeAICredentialDTO", + "title": "RimeAICredential" + }, + { + "$ref": "#/components/schemas/CreateRunpodCredentialDTO", + "title": "RunpodCredential" + }, + { + "$ref": "#/components/schemas/CreateS3CredentialDTO", + "title": "S3Credential" + }, + { + "$ref": "#/components/schemas/CreateSmallestAICredentialDTO", + "title": "SmallestAICredential" + }, + { + "$ref": "#/components/schemas/CreateSpeechmaticsCredentialDTO", + "title": "SpeechmaticsCredential" + }, + { + "$ref": "#/components/schemas/CreateSupabaseCredentialDTO", + "title": "SupabaseCredential" + }, + { + "$ref": "#/components/schemas/CreateTavusCredentialDTO", + "title": "TavusCredential" + }, + { + "$ref": "#/components/schemas/CreateTogetherAICredentialDTO", + "title": "TogetherAICredential" + }, + { + "$ref": "#/components/schemas/CreateTrieveCredentialDTO", + "title": "TrieveCredential" + }, + { + "$ref": "#/components/schemas/CreateTwilioCredentialDTO", + "title": "TwilioCredential" + }, + { + "$ref": "#/components/schemas/CreateVonageCredentialDTO", + "title": "VonageCredential" + }, + { + "$ref": "#/components/schemas/CreateWebhookCredentialDTO", + "title": "WebhookCredential" + }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, + { + "$ref": "#/components/schemas/CreateXAiCredentialDTO", + "title": "XAiCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", + "title": "GoogleCalendarOAuth2ClientCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", + "title": "GoogleCalendarOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", + "title": "GoogleSheetsOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", + "title": "SlackOAuth2AuthorizationCredential" + }, + { + "$ref": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", + "title": "GoHighLevelMCPCredential" + }, + { + "$ref": "#/components/schemas/CreateInworldCredentialDTO", + "title": "InworldCredential" } - ] + ], + "discriminator": { + "propertyName": "provider", + "mapping": { + "11labs": "#/components/schemas/CreateElevenLabsCredentialDTO", + "anthropic": "#/components/schemas/CreateAnthropicCredentialDTO", + "anyscale": "#/components/schemas/CreateAnyscaleCredentialDTO", + "assembly-ai": "#/components/schemas/CreateAssemblyAICredentialDTO", + "azure-openai": "#/components/schemas/CreateAzureOpenAICredentialDTO", + "azure": "#/components/schemas/CreateAzureCredentialDTO", + "byo-sip-trunk": "#/components/schemas/CreateByoSipTrunkCredentialDTO", + "cartesia": "#/components/schemas/CreateCartesiaCredentialDTO", + "cerebras": "#/components/schemas/CreateCerebrasCredentialDTO", + "cloudflare": "#/components/schemas/CreateCloudflareCredentialDTO", + "custom-llm": "#/components/schemas/CreateCustomLLMCredentialDTO", + "deepgram": "#/components/schemas/CreateDeepgramCredentialDTO", + "deepinfra": "#/components/schemas/CreateDeepInfraCredentialDTO", + "deep-seek": "#/components/schemas/CreateDeepSeekCredentialDTO", + "gcp": "#/components/schemas/CreateGcpCredentialDTO", + "gladia": "#/components/schemas/CreateGladiaCredentialDTO", + "gohighlevel": "#/components/schemas/CreateGoHighLevelCredentialDTO", + "google": "#/components/schemas/CreateGoogleCredentialDTO", + "groq": "#/components/schemas/CreateGroqCredentialDTO", + "inflection-ai": "#/components/schemas/CreateInflectionAICredentialDTO", + "langfuse": "#/components/schemas/CreateLangfuseCredentialDTO", + "lmnt": "#/components/schemas/CreateLmntCredentialDTO", + "make": "#/components/schemas/CreateMakeCredentialDTO", + "openai": "#/components/schemas/CreateOpenAICredentialDTO", + "openrouter": "#/components/schemas/CreateOpenRouterCredentialDTO", + "perplexity-ai": "#/components/schemas/CreatePerplexityAICredentialDTO", + "playht": "#/components/schemas/CreatePlayHTCredentialDTO", + "rime-ai": "#/components/schemas/CreateRimeAICredentialDTO", + "runpod": "#/components/schemas/CreateRunpodCredentialDTO", + "s3": "#/components/schemas/CreateS3CredentialDTO", + "supabase": "#/components/schemas/CreateSupabaseCredentialDTO", + "smallest-ai": "#/components/schemas/CreateSmallestAICredentialDTO", + "tavus": "#/components/schemas/CreateTavusCredentialDTO", + "together-ai": "#/components/schemas/CreateTogetherAICredentialDTO", + "twilio": "#/components/schemas/CreateTwilioCredentialDTO", + "vonage": "#/components/schemas/CreateVonageCredentialDTO", + "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", + "xai": "#/components/schemas/CreateXAiCredentialDTO", + "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", + "hume": "#/components/schemas/CreateHumeCredentialDTO", + "mistral": "#/components/schemas/CreateMistralCredentialDTO", + "speechmatics": "#/components/schemas/CreateSpeechmaticsCredentialDTO", + "trieve": "#/components/schemas/CreateTrieveCredentialDTO", + "google.calendar.oauth2-client": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", + "google.calendar.oauth2-authorization": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", + "google.sheets.oauth2-authorization": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", + "slack.oauth2-authorization": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", + "ghl.oauth2-authorization": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", + "inworld": "#/components/schemas/CreateInworldCredentialDTO", + "minimax": "#/components/schemas/CreateMinimaxCredentialDTO" + } + } } }, - "customer": { - "description": "This is the customer information associated with this session.", + "name": { + "type": "string", + "maxLength": 80 + }, + "edges": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Edge" + } + }, + "globalPrompt": { + "type": "string", + "maxLength": 5000 + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. tool.server\n2. workflow.server / assistant.server\n3. phoneNumber.server\n4. org.server", "allOf": [ { - "$ref": "#/components/schemas/CreateCustomerDTO" + "$ref": "#/components/schemas/Server" } ] }, - "phoneNumberId": { - "type": "string", - "description": "This is the ID of the phone number associated with this session." - }, - "phoneNumber": { - "description": "This is the phone number configuration for this session.", + "compliancePlan": { + "description": "This is the compliance plan for the workflow. It allows you to configure HIPAA and other compliance settings.", "allOf": [ { - "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" + "$ref": "#/components/schemas/CompliancePlan" } ] - } - }, - "required": [ - "id", - "orgId", - "createdAt", - "updatedAt" - ] - }, - "CreateSessionDTO": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is a user-defined name for the session. Maximum length is 40 characters.", - "maxLength": 40 }, - "status": { - "type": "string", - "description": "This is the current status of the session. Can be either 'active' or 'completed'.", - "enum": [ - "active", - "completed" + "analysisPlan": { + "description": "This is the plan for analysis of workflow's calls. Stored in `call.analysis`.", + "allOf": [ + { + "$ref": "#/components/schemas/AnalysisPlan" + } ] }, - "expirationSeconds": { - "type": "number", - "description": "Session expiration time in seconds. Defaults to 24 hours (86400 seconds) if not set.", - "minimum": 60, - "maximum": 2592000, - "example": 86400 + "artifactPlan": { + "description": "This is the plan for artifacts generated during workflow's calls. Stored in `call.artifact`.", + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactPlan" + } + ] }, - "assistantId": { - "type": "string", - "description": "This is the ID of the assistant associated with this session. Use this when referencing an existing assistant." + "startSpeakingPlan": { + "description": "This is the plan for when the workflow nodes should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", + "allOf": [ + { + "$ref": "#/components/schemas/StartSpeakingPlan" + } + ] }, - "assistant": { - "description": "This is the assistant configuration for this session. Use this when creating a new assistant configuration.\nIf assistantId is provided, this will be ignored.", + "stopSpeakingPlan": { + "description": "This is the plan for when workflow nodes should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", "allOf": [ { - "$ref": "#/components/schemas/CreateAssistantDTO" + "$ref": "#/components/schemas/StopSpeakingPlan" } ] }, - "messages": { - "type": "array", - "description": "This is an array of chat messages in the session.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - } + "monitorPlan": { + "description": "This is the plan for real-time monitoring of the workflow's calls.\n\nUsage:\n- To enable live listening of the workflow's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the workflow's calls, set `monitorPlan.controlEnabled` to `true`.", + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPlan" + } + ] }, - "customer": { - "description": "This is the customer information associated with this session.", + "backgroundSpeechDenoisingPlan": { + "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nBoth can be used together. Order of precedence:\n- Smart denoising\n- Fourier denoising", "allOf": [ { - "$ref": "#/components/schemas/CreateCustomerDTO" + "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" } ] }, - "phoneNumberId": { - "type": "string", - "description": "This is the ID of the phone number associated with this session." + "credentialIds": { + "description": "These are the credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", + "type": "array", + "items": { + "type": "string" + } }, - "phoneNumber": { - "description": "This is the phone number configuration for this session.", + "keypadInputPlan": { + "description": "This is the plan for keypad input handling during workflow calls.", "allOf": [ { - "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" + "$ref": "#/components/schemas/KeypadInputPlan" } ] } - } + }, + "required": [ + "nodes", + "name", + "edges" + ] }, - "UpdateSessionDTO": { + "UpdateWorkflowDTO": { "type": "object", "properties": { - "name": { - "type": "string", - "description": "This is the new name for the session. Maximum length is 40 characters.", - "maxLength": 40 - }, - "status": { - "type": "string", - "description": "This is the new status for the session.", - "enum": [ - "active", - "completed" - ] - }, - "expirationSeconds": { - "type": "number", - "description": "Session expiration time in seconds. Defaults to 24 hours (86400 seconds) if not set.", - "minimum": 60, - "maximum": 2592000, - "example": 86400 - }, - "messages": { + "nodes": { "type": "array", - "description": "This is the updated array of chat messages.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" + "$ref": "#/components/schemas/ConversationNode", + "title": "ConversationNode" }, { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" + "$ref": "#/components/schemas/ToolNode", + "title": "ToolNode" } ] } - } - } - }, - "GetSessionPaginatedDTO": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the name of the session to filter by." - }, - "assistantId": { - "type": "string", - "description": "This is the ID of the assistant to filter sessions by." }, - "workflowId": { - "type": "string", - "description": "This is the ID of the workflow to filter sessions by." - }, - "page": { - "type": "number", - "description": "This is the page number to return. Defaults to 1.", - "minimum": 1 - }, - "sortOrder": { - "type": "string", - "description": "This is the sort order for pagination. Defaults to 'DESC'.", - "enum": [ - "ASC", - "DESC" + "model": { + "description": "This is the model for the workflow.\n\nThis can be overridden at node level using `nodes[n].model`.", + "oneOf": [ + { + "$ref": "#/components/schemas/WorkflowOpenAIModel", + "title": "WorkflowOpenAIModel" + }, + { + "$ref": "#/components/schemas/WorkflowAnthropicModel", + "title": "WorkflowAnthropicModel" + }, + { + "$ref": "#/components/schemas/WorkflowGoogleModel", + "title": "WorkflowGoogleModel" + }, + { + "$ref": "#/components/schemas/WorkflowCustomModel", + "title": "WorkflowCustomModel" + } ] }, - "limit": { - "type": "number", - "description": "This is the maximum number of items to return. Defaults to 100.", - "minimum": 0, - "maximum": 1000 - }, - "createdAtGt": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is greater than the specified value." - }, - "createdAtLt": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is less than the specified value." - }, - "createdAtGe": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is greater than or equal to the specified value." - }, - "createdAtLe": { - "format": "date-time", - "type": "string", - "description": "This will return items where the createdAt is less than or equal to the specified value." - }, - "updatedAtGt": { - "format": "date-time", - "type": "string", - "description": "This will return items where the updatedAt is greater than the specified value." - }, - "updatedAtLt": { - "format": "date-time", - "type": "string", - "description": "This will return items where the updatedAt is less than the specified value." - }, - "updatedAtGe": { - "format": "date-time", - "type": "string", - "description": "This will return items where the updatedAt is greater than or equal to the specified value." - }, - "updatedAtLe": { - "format": "date-time", - "type": "string", - "description": "This will return items where the updatedAt is less than or equal to the specified value." - } - } - }, - "SessionPaginatedResponse": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Session" - } - }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" - } - }, - "required": [ - "results", - "metadata" - ] - }, - "Assistant": { - "type": "object", - "properties": { "transcriber": { - "description": "These are the options for the assistant's transcriber.", + "description": "This is the transcriber for the workflow.\n\nThis can be overridden at node level using `nodes[n].transcriber`.", "oneOf": [ { "$ref": "#/components/schemas/AssemblyAITranscriber", @@ -29954,69 +26688,8 @@ } ] }, - "model": { - "description": "These are the options for the assistant's LLM.", - "oneOf": [ - { - "$ref": "#/components/schemas/AnthropicModel", - "title": "Anthropic" - }, - { - "$ref": "#/components/schemas/AnyscaleModel", - "title": "Anyscale" - }, - { - "$ref": "#/components/schemas/CerebrasModel", - "title": "Cerebras" - }, - { - "$ref": "#/components/schemas/CustomLLMModel", - "title": "CustomLLM" - }, - { - "$ref": "#/components/schemas/DeepInfraModel", - "title": "DeepInfra" - }, - { - "$ref": "#/components/schemas/DeepSeekModel", - "title": "DeepSeek" - }, - { - "$ref": "#/components/schemas/GoogleModel", - "title": "Google" - }, - { - "$ref": "#/components/schemas/GroqModel", - "title": "Groq" - }, - { - "$ref": "#/components/schemas/InflectionAIModel", - "title": "InflectionAI" - }, - { - "$ref": "#/components/schemas/OpenAIModel", - "title": "OpenAI" - }, - { - "$ref": "#/components/schemas/OpenRouterModel", - "title": "OpenRouter" - }, - { - "$ref": "#/components/schemas/PerplexityAIModel", - "title": "PerplexityAI" - }, - { - "$ref": "#/components/schemas/TogetherAIModel", - "title": "Together" - }, - { - "$ref": "#/components/schemas/XaiModel", - "title": "XAI" - } - ] - }, "voice": { - "description": "These are the options for the assistant's voice.", + "description": "This is the voice for the workflow.\n\nThis can be overridden at node level using `nodes[n].voice`.", "oneOf": [ { "$ref": "#/components/schemas/AzureVoice", @@ -30088,181 +26761,20 @@ } ] }, - "firstMessage": { - "type": "string", - "description": "This is the first message that the assistant will say. This can also be a URL to a containerized audio file (mp3, wav, etc.).\n\nIf unspecified, assistant will wait for user to speak and use the model to respond once they speak.", - "example": "Hello! How can I help you today?" - }, - "firstMessageInterruptionsEnabled": { - "type": "boolean", - "default": false - }, - "firstMessageMode": { - "type": "string", - "description": "This is the mode for the first message. Default is 'assistant-speaks-first'.\n\nUse:\n- 'assistant-speaks-first' to have the assistant speak first.\n- 'assistant-waits-for-user' to have the assistant wait for the user to speak first.\n- 'assistant-speaks-first-with-model-generated-message' to have the assistant speak first with a message generated by the model based on the conversation state. (`assistant.model.messages` at call start, `call.messages` at squad transfer points).\n\n@default 'assistant-speaks-first'", - "enum": [ - "assistant-speaks-first", - "assistant-speaks-first-with-model-generated-message", - "assistant-waits-for-user" - ], - "example": "assistant-speaks-first" - }, - "voicemailDetection": { - "description": "These are the settings to configure or disable voicemail detection. Alternatively, voicemail detection can be configured using the model.tools=[VoicemailTool].\nThis uses Twilio's built-in detection while the VoicemailTool relies on the model to detect if a voicemail was reached.\nYou can use neither of them, one of them, or both of them. By default, Twilio built-in detection is enabled while VoicemailTool is not.", + "observabilityPlan": { + "description": "This is the plan for observability of workflow's calls.\n\nCurrently, only Langfuse is supported.", "oneOf": [ { - "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", - "title": "Google" - }, - { - "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", - "title": "OpenAI" - }, - { - "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", - "title": "Twilio" - }, + "$ref": "#/components/schemas/LangfuseObservabilityPlan", + "title": "Langfuse" + } + ], + "allOf": [ { - "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", - "title": "Vapi" + "$ref": "#/components/schemas/LangfuseObservabilityPlan" } ] }, - "clientMessages": { - "type": "array", - "enum": [ - "conversation-update", - "function-call", - "function-call-result", - "hang", - "language-changed", - "metadata", - "model-output", - "speech-update", - "status-update", - "transcript", - "tool-calls", - "tool-calls-result", - "tool.completed", - "transfer-update", - "user-interrupted", - "voice-input", - "workflow.node.started" - ], - "example": [ - "conversation-update", - "function-call", - "hang", - "model-output", - "speech-update", - "status-update", - "transfer-update", - "transcript", - "tool-calls", - "user-interrupted", - "voice-input", - "workflow.node.started" - ], - "description": "These are the messages that will be sent to your Client SDKs. Default is conversation-update,function-call,hang,model-output,speech-update,status-update,transfer-update,transcript,tool-calls,user-interrupted,voice-input,workflow.node.started. You can check the shape of the messages in ClientMessage schema.", - "items": { - "type": "string", - "enum": [ - "conversation-update", - "function-call", - "function-call-result", - "hang", - "language-changed", - "metadata", - "model-output", - "speech-update", - "status-update", - "transcript", - "tool-calls", - "tool-calls-result", - "tool.completed", - "transfer-update", - "user-interrupted", - "voice-input", - "workflow.node.started" - ] - } - }, - "serverMessages": { - "type": "array", - "enum": [ - "conversation-update", - "end-of-call-report", - "function-call", - "hang", - "language-changed", - "language-change-detected", - "model-output", - "phone-call-control", - "speech-update", - "status-update", - "transcript", - "transcript[transcriptType=\"final\"]", - "tool-calls", - "transfer-destination-request", - "handoff-destination-request", - "transfer-update", - "user-interrupted", - "voice-input", - "chat.created", - "chat.deleted", - "session.created", - "session.updated", - "session.deleted" - ], - "example": [ - "conversation-update", - "end-of-call-report", - "function-call", - "hang", - "speech-update", - "status-update", - "tool-calls", - "transfer-destination-request", - "handoff-destination-request", - "user-interrupted" - ], - "description": "These are the messages that will be sent to your Server URL. Default is conversation-update,end-of-call-report,function-call,hang,speech-update,status-update,tool-calls,transfer-destination-request,handoff-destination-request,user-interrupted. You can check the shape of the messages in ServerMessage schema.", - "items": { - "type": "string", - "enum": [ - "conversation-update", - "end-of-call-report", - "function-call", - "hang", - "language-changed", - "language-change-detected", - "model-output", - "phone-call-control", - "speech-update", - "status-update", - "transcript", - "transcript[transcriptType=\"final\"]", - "tool-calls", - "transfer-destination-request", - "handoff-destination-request", - "transfer-update", - "user-interrupted", - "voice-input", - "chat.created", - "chat.deleted", - "session.created", - "session.updated", - "session.deleted" - ] - } - }, - "maxDurationSeconds": { - "type": "number", - "description": "This is the maximum number of seconds that the call will last. When the call reaches this duration, it will be ended.\n\n@default 600 (10 minutes)", - "minimum": 10, - "maximum": 43200, - "example": 600 - }, "backgroundSound": { "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", "oneOf": [ @@ -30281,40 +26793,33 @@ } ] }, - "modelOutputInMessagesEnabled": { - "type": "boolean", - "description": "This determines whether the model's output is used in conversation history rather than the transcription of assistant's speech.\n\nDefault `false` while in beta.\n\n@default false", - "example": false - }, - "transportConfigurations": { + "hooks": { "type": "array", - "description": "These are the configurations to be passed to the transport providers of assistant's calls, like Twilio. You can store multiple configurations for different transport providers. For a call, only the configuration matching the call transport provider is used.", + "description": "This is a set of actions that will be performed on certain events.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/TransportConfigurationTwilio", - "title": "Twilio" - } - ] - } - }, - "observabilityPlan": { - "description": "This is the plan for observability of assistant's calls.\n\nCurrently, only Langfuse is supported.", - "oneOf": [ - { - "$ref": "#/components/schemas/LangfuseObservabilityPlan", - "title": "Langfuse" - } - ], - "allOf": [ - { - "$ref": "#/components/schemas/LangfuseObservabilityPlan" - } - ] + "$ref": "#/components/schemas/CallHookCallEnding", + "title": "CallHookCallEnding" + }, + { + "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", + "title": "CallHookAssistantSpeechInterrupted" + }, + { + "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", + "title": "CallHookCustomerSpeechInterrupted" + }, + { + "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", + "title": "CallHookCustomerSpeechTimeout" + } + ] + } }, "credentials": { "type": "array", - "description": "These are dynamic credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", + "description": "These are dynamic credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", "items": { "oneOf": [ { @@ -30485,6 +26990,10 @@ "$ref": "#/components/schemas/CreateWebhookCredentialDTO", "title": "WebhookCredential" }, + { + "$ref": "#/components/schemas/CreateCustomCredentialDTO", + "title": "CustomCredential" + }, { "$ref": "#/components/schemas/CreateXAiCredentialDTO", "title": "XAiCredential" @@ -30554,6 +27063,7 @@ "twilio": "#/components/schemas/CreateTwilioCredentialDTO", "vonage": "#/components/schemas/CreateVonageCredentialDTO", "webhook": "#/components/schemas/CreateWebhookCredentialDTO", + "custom-credential": "#/components/schemas/CreateCustomCredentialDTO", "xai": "#/components/schemas/CreateXAiCredentialDTO", "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", "hume": "#/components/schemas/CreateHumeCredentialDTO", @@ -30571,71 +27081,38 @@ } } }, - "hooks": { - "type": "array", - "description": "This is a set of actions that will be performed on certain events.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/CallHookCallEnding", - "title": "CallHookCallEnding" - }, - { - "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", - "title": "CallHookAssistantSpeechInterrupted" - }, - { - "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", - "title": "CallHookCustomerSpeechInterrupted" - }, - { - "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", - "title": "CallHookCustomerSpeechTimeout" - } - ] - } - }, "name": { "type": "string", - "description": "This is the name of the assistant.\n\nThis is required when you want to transfer between assistants in a call.", - "maxLength": 40 - }, - "voicemailMessage": { - "type": "string", - "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", - "maxLength": 1000 - }, - "endCallMessage": { - "type": "string", - "description": "This is the message that the assistant will say if it ends the call.\n\nIf unspecified, it will hang up without saying anything.", - "maxLength": 1000 + "maxLength": 80 }, - "endCallPhrases": { - "description": "This list contains phrases that, if spoken by the assistant, will trigger the call to be hung up. Case insensitive.", + "edges": { "type": "array", "items": { - "type": "string", - "maxLength": 140, - "minLength": 2 + "$ref": "#/components/schemas/Edge" } }, - "compliancePlan": { - "$ref": "#/components/schemas/CompliancePlan" + "globalPrompt": { + "type": "string", + "maxLength": 5000 }, - "metadata": { - "type": "object", - "description": "This is for metadata you want to store on the assistant." + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. tool.server\n2. workflow.server / assistant.server\n3. phoneNumber.server\n4. org.server", + "allOf": [ + { + "$ref": "#/components/schemas/Server" + } + ] }, - "backgroundSpeechDenoisingPlan": { - "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nSmart denoising can be combined with or used independently of Fourier denoising.\n\nOrder of precedence:\n- Smart denoising\n- Fourier denoising", + "compliancePlan": { + "description": "This is the compliance plan for the workflow. It allows you to configure HIPAA and other compliance settings.", "allOf": [ { - "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" + "$ref": "#/components/schemas/CompliancePlan" } ] }, "analysisPlan": { - "description": "This is the plan for analysis of assistant's calls. Stored in `call.analysis`.", + "description": "This is the plan for analysis of workflow's calls. Stored in `call.analysis`.", "allOf": [ { "$ref": "#/components/schemas/AnalysisPlan" @@ -30643,7 +27120,7 @@ ] }, "artifactPlan": { - "description": "This is the plan for artifacts generated during assistant's calls. Stored in `call.artifact`.", + "description": "This is the plan for artifacts generated during workflow's calls. Stored in `call.artifact`.", "allOf": [ { "$ref": "#/components/schemas/ArtifactPlan" @@ -30651,7 +27128,7 @@ ] }, "startSpeakingPlan": { - "description": "This is the plan for when the assistant should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", + "description": "This is the plan for when the workflow nodes should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", "allOf": [ { "$ref": "#/components/schemas/StartSpeakingPlan" @@ -30659,7 +27136,7 @@ ] }, "stopSpeakingPlan": { - "description": "This is the plan for when assistant should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", + "description": "This is the plan for when workflow nodes should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", "allOf": [ { "$ref": "#/components/schemas/StopSpeakingPlan" @@ -30667,4658 +27144,5268 @@ ] }, "monitorPlan": { - "description": "This is the plan for real-time monitoring of the assistant's calls.\n\nUsage:\n- To enable live listening of the assistant's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the assistant's calls, set `monitorPlan.controlEnabled` to `true`.", + "description": "This is the plan for real-time monitoring of the workflow's calls.\n\nUsage:\n- To enable live listening of the workflow's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the workflow's calls, set `monitorPlan.controlEnabled` to `true`.", "allOf": [ { "$ref": "#/components/schemas/MonitorPlan" } ] }, + "backgroundSpeechDenoisingPlan": { + "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nBoth can be used together. Order of precedence:\n- Smart denoising\n- Fourier denoising", + "allOf": [ + { + "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" + } + ] + }, "credentialIds": { - "description": "These are the credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", + "description": "These are the credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", "type": "array", "items": { "type": "string" } }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server.url\n2. phoneNumber.serverUrl\n3. org.serverUrl", + "keypadInputPlan": { + "description": "This is the plan for keypad input handling during workflow calls.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/KeypadInputPlan" } ] + } + } + }, + "AnalysisCostBreakdown": { + "type": "object", + "properties": { + "summary": { + "type": "number", + "description": "This is the cost to summarize the call." }, - "keypadInputPlan": { - "$ref": "#/components/schemas/KeypadInputPlan" + "summaryPromptTokens": { + "type": "number", + "description": "This is the number of prompt tokens used to summarize the call." }, - "id": { + "summaryCompletionTokens": { + "type": "number", + "description": "This is the number of completion tokens used to summarize the call." + }, + "structuredData": { + "type": "number", + "description": "This is the cost to extract structured data from the call." + }, + "structuredDataPromptTokens": { + "type": "number", + "description": "This is the number of prompt tokens used to extract structured data from the call." + }, + "structuredDataCompletionTokens": { + "type": "number", + "description": "This is the number of completion tokens used to extract structured data from the call." + }, + "successEvaluation": { + "type": "number", + "description": "This is the cost to evaluate if the call was successful." + }, + "successEvaluationPromptTokens": { + "type": "number", + "description": "This is the number of prompt tokens used to evaluate if the call was successful." + }, + "successEvaluationCompletionTokens": { + "type": "number", + "description": "This is the number of completion tokens used to evaluate if the call was successful." + }, + "structuredOutput": { + "type": "number", + "description": "This is the cost to evaluate structuredOutputs from the call." + }, + "structuredOutputPromptTokens": { + "type": "number", + "description": "This is the number of prompt tokens used to evaluate structuredOutputs from the call." + }, + "structuredOutputCompletionTokens": { + "type": "number", + "description": "This is the number of completion tokens used to evaluate structuredOutputs from the call." + } + } + }, + "CostBreakdown": { + "type": "object", + "properties": { + "transport": { + "type": "number", + "description": "This is the cost of the transport provider, like Twilio or Vonage." + }, + "stt": { + "type": "number", + "description": "This is the cost of the speech-to-text service." + }, + "llm": { + "type": "number", + "description": "This is the cost of the language model." + }, + "tts": { + "type": "number", + "description": "This is the cost of the text-to-speech service." + }, + "vapi": { + "type": "number", + "description": "This is the cost of Vapi." + }, + "chat": { + "type": "number", + "description": "This is the cost of chat interactions." + }, + "total": { + "type": "number", + "description": "This is the total cost of the call." + }, + "llmPromptTokens": { + "type": "number", + "description": "This is the LLM prompt tokens used for the call." + }, + "llmCompletionTokens": { + "type": "number", + "description": "This is the LLM completion tokens used for the call." + }, + "ttsCharacters": { + "type": "number", + "description": "This is the TTS characters used for the call." + }, + "analysisCostBreakdown": { + "description": "This is the cost of the analysis.", + "allOf": [ + { + "$ref": "#/components/schemas/AnalysisCostBreakdown" + } + ] + } + } + }, + "Analysis": { + "type": "object", + "properties": { + "summary": { "type": "string", - "description": "This is the unique identifier for the assistant." + "description": "This is the summary of the call. Customize by setting `assistant.analysisPlan.summaryPrompt`." }, - "orgId": { + "structuredData": { + "type": "object", + "description": "This is the structured data extracted from the call. Customize by setting `assistant.analysisPlan.structuredDataPrompt` and/or `assistant.analysisPlan.structuredDataSchema`." + }, + "structuredDataMulti": { + "description": "This is the structured data catalog of the call. Customize by setting `assistant.analysisPlan.structuredDataMultiPlan`.", + "type": "array", + "items": { + "type": "object" + } + }, + "successEvaluation": { "type": "string", - "description": "This is the unique identifier for the org that this assistant belongs to." + "description": "This is the evaluation of the call. Customize by setting `assistant.analysisPlan.successEvaluationPrompt` and/or `assistant.analysisPlan.successEvaluationRubric`." + } + } + }, + "Monitor": { + "type": "object", + "properties": { + "listenUrl": { + "type": "string", + "description": "This is the URL where the assistant's calls can be listened to in real-time. To enable, set `assistant.monitorPlan.listenEnabled` to `true`." }, - "createdAt": { - "format": "date-time", + "controlUrl": { + "type": "string", + "description": "This is the URL where the assistant's calls can be controlled in real-time. To enable, set `assistant.monitorPlan.controlEnabled` to `true`." + } + } + }, + "Mono": { + "type": "object", + "properties": { + "combinedUrl": { + "type": "string", + "description": "This is the combined recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`." + }, + "assistantUrl": { + "type": "string", + "description": "This is the mono recording url for the assistant. To enable, set `assistant.artifactPlan.recordingEnabled`." + }, + "customerUrl": { + "type": "string", + "description": "This is the mono recording url for the customer. To enable, set `assistant.artifactPlan.recordingEnabled`." + } + } + }, + "Recording": { + "type": "object", + "properties": { + "stereoUrl": { + "type": "string", + "description": "This is the stereo recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`." + }, + "videoUrl": { + "type": "string", + "description": "This is the video recording url for the call. To enable, set `assistant.artifactPlan.videoRecordingEnabled`." + }, + "videoRecordingStartDelaySeconds": { + "type": "number", + "description": "This is video recording start delay in ms. To enable, set `assistant.artifactPlan.videoRecordingEnabled`. This can be used to align the playback of the recording with artifact.messages timestamps." + }, + "mono": { + "description": "This is the mono recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", + "allOf": [ + { + "$ref": "#/components/schemas/Mono" + } + ] + } + } + }, + "NodeArtifact": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that were spoken during the node.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/BotMessage", + "title": "BotMessage" + }, + { + "$ref": "#/components/schemas/ToolCallMessage", + "title": "ToolCallMessage" + }, + { + "$ref": "#/components/schemas/ToolCallResultMessage", + "title": "ToolCallResultMessage" + } + ] + } + }, + "nodeName": { + "type": "string", + "description": "This is the node name." + }, + "variableValues": { + "type": "object", + "description": "These are the variable values that were extracted from the node." + } + } + }, + "TurnLatency": { + "type": "object", + "properties": { + "modelLatency": { + "type": "number", + "description": "This is the model latency for the first token." + }, + "voiceLatency": { + "type": "number", + "description": "This is the voice latency from the model output." + }, + "transcriberLatency": { + "type": "number", + "description": "This is the transcriber latency from the user speech." + }, + "endpointingLatency": { + "type": "number", + "description": "This is the endpointing latency." + }, + "turnLatency": { + "type": "number", + "description": "This is the latency for the whole turn." + } + } + }, + "PerformanceMetrics": { + "type": "object", + "properties": { + "turnLatencies": { + "description": "These are the individual latencies for each turn.", + "type": "array", + "items": { + "$ref": "#/components/schemas/TurnLatency" + } + }, + "modelLatencyAverage": { + "type": "number", + "description": "This is the average latency for the model to output the first token." + }, + "voiceLatencyAverage": { + "type": "number", + "description": "This is the average latency for the text to speech." + }, + "transcriberLatencyAverage": { + "type": "number", + "description": "This is the average latency for the transcriber." + }, + "endpointingLatencyAverage": { + "type": "number", + "description": "This is the average latency for the endpointing." + }, + "turnLatencyAverage": { + "type": "number", + "description": "This is the average latency for complete turns." + } + } + }, + "Artifact": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that were spoken during the call.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/BotMessage", + "title": "BotMessage" + }, + { + "$ref": "#/components/schemas/ToolCallMessage", + "title": "ToolCallMessage" + }, + { + "$ref": "#/components/schemas/ToolCallResultMessage", + "title": "ToolCallResultMessage" + } + ] + } + }, + "messagesOpenAIFormatted": { + "description": "These are the messages that were spoken during the call, formatted for OpenAI.", + "type": "array", + "items": { + "$ref": "#/components/schemas/OpenAIMessage" + } + }, + "recordingUrl": { + "type": "string", + "description": "This is the recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", + "deprecated": true + }, + "stereoRecordingUrl": { + "type": "string", + "description": "This is the stereo recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", + "deprecated": true + }, + "videoRecordingUrl": { + "type": "string", + "description": "This is video recording url for the call. To enable, set `assistant.artifactPlan.videoRecordingEnabled`.", + "deprecated": true + }, + "videoRecordingStartDelaySeconds": { + "type": "number", + "description": "This is video recording start delay in ms. To enable, set `assistant.artifactPlan.videoRecordingEnabled`. This can be used to align the playback of the recording with artifact.messages timestamps.", + "deprecated": true + }, + "recording": { + "description": "This is the recording url for the call. To enable, set `assistant.artifactPlan.recordingEnabled`.", + "allOf": [ + { + "$ref": "#/components/schemas/Recording" + } + ] + }, + "transcript": { + "type": "string", + "description": "This is the transcript of the call. This is derived from `artifact.messages` but provided for convenience." + }, + "pcapUrl": { + "type": "string", + "description": "This is the packet capture url for the call. This is only available for `phone` type calls where phone number's provider is `vapi` or `byo-phone-number`." + }, + "logUrl": { + "type": "string", + "description": "This is the url for the call logs. This includes all logging output during the call for debugging purposes." + }, + "nodes": { + "description": "This is the history of workflow nodes that were executed during the call.", + "type": "array", + "items": { + "$ref": "#/components/schemas/NodeArtifact" + } + }, + "variableValues": { + "type": "object", + "description": "These are the variable values at the end of the workflow execution." + }, + "performanceMetrics": { + "description": "This is the performance metrics for the call. It contains the turn latency, broken down by component.", + "allOf": [ + { + "$ref": "#/components/schemas/PerformanceMetrics" + } + ] + }, + "structuredOutputs": { + "type": "object", + "description": "These are the structured outputs that will be extracted from the call.\nTo enable, set `assistant.artifactPlan.structuredOutputIds` with the IDs of the structured outputs you want to extract." + } + } + }, + "WorkflowOverrides": { + "type": "object", + "properties": { + "variableValues": { + "type": "object", + "description": "These are values that will be used to replace the template variables in the workflow messages and other text-based fields.\nThis uses LiquidJS syntax. https://liquidjs.com/tutorials/intro-to-liquid.html\n\nSo for example, `{{ name }}` will be replaced with the value of `name` in `variableValues`.\n`{{\"now\" | date: \"%b %d, %Y, %I:%M %p\", \"America/New_York\"}}` will be replaced with the current date and time in New York.\n Some VAPI reserved defaults:\n - *customer* - the customer object" + } + } + }, + "TransferPhoneNumberHookAction": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "This is the type of action - must be \"transfer\"", + "enum": [ + "transfer" + ] + }, + "destination": { + "description": "This is the destination details for the transfer - can be a phone number or SIP URI", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + } + }, + "required": [ + "type" + ] + }, + "SayPhoneNumberHookAction": { + "type": "object", + "properties": { + "type": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the assistant was created." + "description": "This is the type of action - must be \"say\"", + "enum": [ + "say" + ] }, - "updatedAt": { - "format": "date-time", + "exact": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the assistant was last updated." + "description": "This is the message to say", + "maxLength": 4000 } }, "required": [ - "id", - "orgId", - "createdAt", - "updatedAt" + "type", + "exact" ] }, - "AssistantPaginatedResponse": { + "PhoneNumberHookCallRinging": { "type": "object", "properties": { - "results": { + "on": { + "type": "string", + "description": "This is the event to trigger the hook on", + "enum": [ + "call.ringing" + ], + "maxLength": 1000 + }, + "do": { "type": "array", + "description": "Only the first action will be executed. Additional actions will be ignored.", "items": { - "$ref": "#/components/schemas/Assistant" + "oneOf": [ + { + "$ref": "#/components/schemas/TransferPhoneNumberHookAction", + "title": "TransferPhoneNumberHookAction" + }, + { + "$ref": "#/components/schemas/SayPhoneNumberHookAction", + "title": "SayPhoneNumberHookAction" + } + ] } - }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" } }, "required": [ - "results", - "metadata" + "on", + "do" ] }, - "AssistantVersionPaginatedResponse": { + "PhoneNumberCallEndingHookFilter": { "type": "object", "properties": { - "results": { - "type": "array" + "type": { + "type": "string", + "description": "This is the type of filter - currently only \"oneOf\" is supported", + "enum": [ + "oneOf" + ], + "maxLength": 1000 }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" + "key": { + "type": "string", + "description": "This is the key to filter on - only \"call.endedReason\" is allowed for phone number call ending hooks", + "enum": [ + "call.endedReason" + ], + "maxLength": 1000 }, - "nextPageState": { - "type": "string" + "oneOf": { + "type": "array", + "description": "This is the array of assistant-request related ended reasons to match against", + "enum": [ + "assistant-request-failed", + "assistant-request-returned-error", + "assistant-request-returned-unspeakable-error", + "assistant-request-returned-invalid-assistant", + "assistant-request-returned-no-assistant", + "assistant-request-returned-forwarding-phone-number" + ], + "items": { + "type": "string", + "enum": [ + "assistant-request-failed", + "assistant-request-returned-error", + "assistant-request-returned-unspeakable-error", + "assistant-request-returned-invalid-assistant", + "assistant-request-returned-no-assistant", + "assistant-request-returned-forwarding-phone-number" + ] + } } }, "required": [ - "results", - "metadata" + "type", + "key", + "oneOf" ] }, - "UpdateAssistantDTO": { + "PhoneNumberHookCallEnding": { "type": "object", "properties": { - "transcriber": { - "description": "These are the options for the assistant's transcriber.", - "oneOf": [ - { - "$ref": "#/components/schemas/AssemblyAITranscriber", - "title": "AssemblyAITranscriber" - }, - { - "$ref": "#/components/schemas/AzureSpeechTranscriber", - "title": "AzureSpeechTranscriber" - }, - { - "$ref": "#/components/schemas/CustomTranscriber", - "title": "CustomTranscriber" - }, - { - "$ref": "#/components/schemas/DeepgramTranscriber", - "title": "DeepgramTranscriber" - }, - { - "$ref": "#/components/schemas/ElevenLabsTranscriber", - "title": "ElevenLabsTranscriber" - }, - { - "$ref": "#/components/schemas/GladiaTranscriber", - "title": "GladiaTranscriber" - }, - { - "$ref": "#/components/schemas/GoogleTranscriber", - "title": "GoogleTranscriber" - }, - { - "$ref": "#/components/schemas/SpeechmaticsTranscriber", - "title": "SpeechmaticsTranscriber" - }, - { - "$ref": "#/components/schemas/TalkscriberTranscriber", - "title": "TalkscriberTranscriber" - }, - { - "$ref": "#/components/schemas/OpenAITranscriber", - "title": "OpenAITranscriber" - }, - { - "$ref": "#/components/schemas/CartesiaTranscriber", - "title": "CartesiaTranscriber" - } - ] + "on": { + "type": "string", + "description": "This is the event to trigger the hook on", + "enum": [ + "call.ending" + ], + "maxLength": 1000 }, - "model": { - "description": "These are the options for the assistant's LLM.", - "oneOf": [ - { - "$ref": "#/components/schemas/AnthropicModel", - "title": "Anthropic" - }, - { - "$ref": "#/components/schemas/AnyscaleModel", - "title": "Anyscale" - }, - { - "$ref": "#/components/schemas/CerebrasModel", - "title": "Cerebras" - }, - { - "$ref": "#/components/schemas/CustomLLMModel", - "title": "CustomLLM" - }, - { - "$ref": "#/components/schemas/DeepInfraModel", - "title": "DeepInfra" - }, - { - "$ref": "#/components/schemas/DeepSeekModel", - "title": "DeepSeek" - }, - { - "$ref": "#/components/schemas/GoogleModel", - "title": "Google" - }, - { - "$ref": "#/components/schemas/GroqModel", - "title": "Groq" - }, - { - "$ref": "#/components/schemas/InflectionAIModel", - "title": "InflectionAI" - }, - { - "$ref": "#/components/schemas/OpenAIModel", - "title": "OpenAI" - }, - { - "$ref": "#/components/schemas/OpenRouterModel", - "title": "OpenRouter" - }, - { - "$ref": "#/components/schemas/PerplexityAIModel", - "title": "PerplexityAI" - }, - { - "$ref": "#/components/schemas/TogetherAIModel", - "title": "Together" - }, - { - "$ref": "#/components/schemas/XaiModel", - "title": "XAI" - } - ] + "filters": { + "type": "array", + "description": "Optional filters to decide when to trigger - restricted to assistant-request related ended reasons", + "items": { + "$ref": "#/components/schemas/PhoneNumberCallEndingHookFilter" + } }, - "voice": { - "description": "These are the options for the assistant's voice.", + "do": { + "description": "This is the action to perform when the hook triggers", "oneOf": [ { - "$ref": "#/components/schemas/AzureVoice", - "title": "AzureVoice" - }, - { - "$ref": "#/components/schemas/CartesiaVoice", - "title": "CartesiaVoice" - }, - { - "$ref": "#/components/schemas/CustomVoice", - "title": "CustomVoice" - }, - { - "$ref": "#/components/schemas/DeepgramVoice", - "title": "DeepgramVoice" - }, - { - "$ref": "#/components/schemas/ElevenLabsVoice", - "title": "ElevenLabsVoice" - }, - { - "$ref": "#/components/schemas/HumeVoice", - "title": "HumeVoice" - }, - { - "$ref": "#/components/schemas/LMNTVoice", - "title": "LMNTVoice" - }, - { - "$ref": "#/components/schemas/NeuphonicVoice", - "title": "NeuphonicVoice" - }, - { - "$ref": "#/components/schemas/OpenAIVoice", - "title": "OpenAIVoice" - }, - { - "$ref": "#/components/schemas/PlayHTVoice", - "title": "PlayHTVoice" - }, - { - "$ref": "#/components/schemas/RimeAIVoice", - "title": "RimeAIVoice" - }, - { - "$ref": "#/components/schemas/SmallestAIVoice", - "title": "SmallestAIVoice" - }, - { - "$ref": "#/components/schemas/TavusVoice", - "title": "TavusVoice" - }, - { - "$ref": "#/components/schemas/VapiVoice", - "title": "VapiVoice" - }, - { - "$ref": "#/components/schemas/SesameVoice", - "title": "SesameVoice" - }, - { - "$ref": "#/components/schemas/InworldVoice", - "title": "InworldVoice" + "$ref": "#/components/schemas/TransferPhoneNumberHookAction", + "title": "TransferPhoneNumberHookAction" }, { - "$ref": "#/components/schemas/MinimaxVoice", - "title": "MinimaxVoice" + "$ref": "#/components/schemas/SayPhoneNumberHookAction", + "title": "SayPhoneNumberHookAction" } ] - }, - "firstMessage": { - "type": "string", - "description": "This is the first message that the assistant will say. This can also be a URL to a containerized audio file (mp3, wav, etc.).\n\nIf unspecified, assistant will wait for user to speak and use the model to respond once they speak.", - "example": "Hello! How can I help you today?" - }, - "firstMessageInterruptionsEnabled": { - "type": "boolean", - "default": false - }, - "firstMessageMode": { - "type": "string", - "description": "This is the mode for the first message. Default is 'assistant-speaks-first'.\n\nUse:\n- 'assistant-speaks-first' to have the assistant speak first.\n- 'assistant-waits-for-user' to have the assistant wait for the user to speak first.\n- 'assistant-speaks-first-with-model-generated-message' to have the assistant speak first with a message generated by the model based on the conversation state. (`assistant.model.messages` at call start, `call.messages` at squad transfer points).\n\n@default 'assistant-speaks-first'", - "enum": [ - "assistant-speaks-first", - "assistant-speaks-first-with-model-generated-message", - "assistant-waits-for-user" - ], - "example": "assistant-speaks-first" - }, - "voicemailDetection": { - "description": "These are the settings to configure or disable voicemail detection. Alternatively, voicemail detection can be configured using the model.tools=[VoicemailTool].\nThis uses Twilio's built-in detection while the VoicemailTool relies on the model to detect if a voicemail was reached.\nYou can use neither of them, one of them, or both of them. By default, Twilio built-in detection is enabled while VoicemailTool is not.", + } + }, + "required": [ + "on" + ] + }, + "ImportTwilioPhoneNumberDTO": { + "type": "object", + "properties": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", "oneOf": [ { - "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", - "title": "Google" - }, - { - "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", - "title": "OpenAI" - }, - { - "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", - "title": "Twilio" + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" }, { - "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", - "title": "Vapi" + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" } ] }, - "clientMessages": { + "hooks": { "type": "array", - "enum": [ - "conversation-update", - "function-call", - "function-call-result", - "hang", - "language-changed", - "metadata", - "model-output", - "speech-update", - "status-update", - "transcript", - "tool-calls", - "tool-calls-result", - "tool.completed", - "transfer-update", - "user-interrupted", - "voice-input", - "workflow.node.started" - ], - "example": [ - "conversation-update", - "function-call", - "hang", - "model-output", - "speech-update", - "status-update", - "transfer-update", - "transcript", - "tool-calls", - "user-interrupted", - "voice-input", - "workflow.node.started" - ], - "description": "These are the messages that will be sent to your Client SDKs. Default is conversation-update,function-call,hang,model-output,speech-update,status-update,transfer-update,transcript,tool-calls,user-interrupted,voice-input,workflow.node.started. You can check the shape of the messages in ClientMessage schema.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { - "type": "string", - "enum": [ - "conversation-update", - "function-call", - "function-call-result", - "hang", - "language-changed", - "metadata", - "model-output", - "speech-update", - "status-update", - "transcript", - "tool-calls", - "tool-calls-result", - "tool.completed", - "transfer-update", - "user-interrupted", - "voice-input", - "workflow.node.started" + "oneOf": [ + { + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" + }, + { + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" + } ] } }, - "serverMessages": { - "type": "array", - "enum": [ - "conversation-update", - "end-of-call-report", - "function-call", - "hang", - "language-changed", - "language-change-detected", - "model-output", - "phone-call-control", - "speech-update", - "status-update", - "transcript", - "transcript[transcriptType=\"final\"]", - "tool-calls", - "transfer-destination-request", - "handoff-destination-request", - "transfer-update", - "user-interrupted", - "voice-input", - "chat.created", - "chat.deleted", - "session.created", - "session.updated", - "session.deleted" - ], - "example": [ - "conversation-update", - "end-of-call-report", - "function-call", - "hang", - "speech-update", - "status-update", - "tool-calls", - "transfer-destination-request", - "handoff-destination-request", - "user-interrupted" - ], - "description": "These are the messages that will be sent to your Server URL. Default is conversation-update,end-of-call-report,function-call,hang,speech-update,status-update,tool-calls,transfer-destination-request,handoff-destination-request,user-interrupted. You can check the shape of the messages in ServerMessage schema.", - "items": { - "type": "string", - "enum": [ - "conversation-update", - "end-of-call-report", - "function-call", - "hang", - "language-changed", - "language-change-detected", - "model-output", - "phone-call-control", - "speech-update", - "status-update", - "transcript", - "transcript[transcriptType=\"final\"]", - "tool-calls", - "transfer-destination-request", - "handoff-destination-request", - "transfer-update", - "user-interrupted", - "voice-input", - "chat.created", - "chat.deleted", - "session.created", - "session.updated", - "session.deleted" - ] - } + "smsEnabled": { + "type": "boolean", + "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", + "default": true + }, + "twilioPhoneNumber": { + "type": "string", + "description": "These are the digits of the phone number you own on your Twilio.", + "deprecated": true + }, + "twilioAccountSid": { + "type": "string", + "description": "This is your Twilio Account SID that will be used to handle this phone number." + }, + "twilioAuthToken": { + "type": "string", + "description": "This is the Twilio Auth Token that will be used to handle this phone number." }, - "maxDurationSeconds": { - "type": "number", - "description": "This is the maximum number of seconds that the call will last. When the call reaches this duration, it will be ended.\n\n@default 600 (10 minutes)", - "minimum": 10, - "maximum": 43200, - "example": 600 + "twilioApiKey": { + "type": "string", + "description": "This is the Twilio API Key that will be used to handle this phone number. If AuthToken is provided, this will be ignored." }, - "backgroundSound": { - "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", - "oneOf": [ + "twilioApiSecret": { + "type": "string", + "description": "This is the Twilio API Secret that will be used to handle this phone number. If AuthToken is provided, this will be ignored." + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 + }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "allOf": [ { - "type": "enum", - "enum": [ - "off", - "office" - ], - "example": "office" - }, + "$ref": "#/components/schemas/Server" + } + ] + } + }, + "required": [ + "twilioPhoneNumber", + "twilioAccountSid" + ] + }, + "CreateCustomerDTO": { + "type": "object", + "properties": { + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true + }, + "extension": { + "type": "string", + "description": "This is the extension that will be dialed after the call is answered.", + "maxLength": 10, + "example": null + }, + "assistantOverrides": { + "description": "These are the overrides for the assistant's settings and template variables specific to this customer.\nThis allows customization of the assistant's behavior for individual customers in batch calls.", + "allOf": [ { - "type": "string", - "format": "uri", - "example": "https://www.soundjay.com/ambient/sounds/people-in-lounge-1.mp3" + "$ref": "#/components/schemas/AssistantOverrides" } ] }, - "modelOutputInMessagesEnabled": { - "type": "boolean", - "description": "This determines whether the model's output is used in conversation history rather than the transcription of assistant's speech.\n\nDefault `false` while in beta.\n\n@default false", - "example": false + "number": { + "type": "string", + "description": "This is the number of the customer.", + "minLength": 3, + "maxLength": 40 }, - "transportConfigurations": { + "sipUri": { + "type": "string", + "description": "This is the SIP URI of the customer." + }, + "name": { + "type": "string", + "description": "This is the name of the customer. This is just for your own reference.\n\nFor SIP inbound calls, this is extracted from the `From` SIP header with format `\"Display Name\" `.", + "maxLength": 40 + }, + "email": { + "type": "string", + "description": "This is the email of the customer.", + "maxLength": 40 + }, + "externalId": { + "type": "string", + "description": "This is the external ID of the customer.", + "maxLength": 40 + } + } + }, + "SchedulePlan": { + "type": "object", + "properties": { + "earliestAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of the earliest time the call can be scheduled." + }, + "latestAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of the latest time the call can be scheduled." + } + }, + "required": [ + "earliestAt" + ] + }, + "Call": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "This is the type of call.", + "enum": [ + "inboundPhoneCall", + "outboundPhoneCall", + "webCall", + "vapi.websocketCall" + ] + }, + "costs": { "type": "array", - "description": "These are the configurations to be passed to the transport providers of assistant's calls, like Twilio. You can store multiple configurations for different transport providers. For a call, only the configuration matching the call transport provider is used.", + "description": "These are the costs of individual components of the call in USD.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/TransportConfigurationTwilio", - "title": "Twilio" + "$ref": "#/components/schemas/TransportCost", + "title": "TransportCost" + }, + { + "$ref": "#/components/schemas/TranscriberCost", + "title": "TranscriberCost" + }, + { + "$ref": "#/components/schemas/ModelCost", + "title": "ModelCost" + }, + { + "$ref": "#/components/schemas/VoiceCost", + "title": "VoiceCost" + }, + { + "$ref": "#/components/schemas/VapiCost", + "title": "VapiCost" + }, + { + "$ref": "#/components/schemas/VoicemailDetectionCost", + "title": "VoicemailDetectionCost" + }, + { + "$ref": "#/components/schemas/AnalysisCost", + "title": "AnalysisCost" + }, + { + "$ref": "#/components/schemas/KnowledgeBaseCost", + "title": "KnowledgeBaseCost" } ] } }, - "observabilityPlan": { - "description": "This is the plan for observability of assistant's calls.\n\nCurrently, only Langfuse is supported.", - "oneOf": [ - { - "$ref": "#/components/schemas/LangfuseObservabilityPlan", - "title": "Langfuse" - } - ], - "allOf": [ - { - "$ref": "#/components/schemas/LangfuseObservabilityPlan" - } + "messages": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/BotMessage", + "title": "BotMessage" + }, + { + "$ref": "#/components/schemas/ToolCallMessage", + "title": "ToolCallMessage" + }, + { + "$ref": "#/components/schemas/ToolCallResultMessage", + "title": "ToolCallResultMessage" + } + ] + } + }, + "phoneCallProvider": { + "type": "string", + "description": "This is the provider of the call.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "deprecated": true, + "enum": [ + "twilio", + "vonage", + "vapi", + "telnyx" + ] + }, + "phoneCallTransport": { + "type": "string", + "description": "This is the transport of the phone call.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "enum": [ + "sip", + "pstn" + ] + }, + "status": { + "type": "string", + "description": "This is the status of the call.", + "enum": [ + "scheduled", + "queued", + "ringing", + "in-progress", + "forwarding", + "ended" + ] + }, + "endedReason": { + "type": "string", + "description": "This is the explanation for how the call ended.", + "enum": [ + "call-start-error-neither-assistant-nor-server-set", + "assistant-request-failed", + "assistant-request-returned-error", + "assistant-request-returned-unspeakable-error", + "assistant-request-returned-invalid-assistant", + "assistant-request-returned-no-assistant", + "assistant-request-returned-forwarding-phone-number", + "scheduled-call-deleted", + "call.start.error-vapifault-get-org", + "call.start.error-vapifault-get-subscription", + "call.start.error-get-assistant", + "call.start.error-get-phone-number", + "call.start.error-get-customer", + "call.start.error-get-resources-validation", + "call.start.error-vapi-number-international", + "call.start.error-vapi-number-outbound-daily-limit", + "call.start.error-get-transport", + "call.start.error-subscription-wallet-does-not-exist", + "call.start.error-subscription-frozen", + "call.start.error-subscription-insufficient-credits", + "call.start.error-subscription-upgrade-failed", + "call.start.error-subscription-concurrency-limit-reached", + "assistant-not-valid", + "database-error", + "assistant-not-found", + "pipeline-error-openai-voice-failed", + "pipeline-error-cartesia-voice-failed", + "pipeline-error-deepgram-voice-failed", + "pipeline-error-eleven-labs-voice-failed", + "pipeline-error-playht-voice-failed", + "pipeline-error-lmnt-voice-failed", + "pipeline-error-azure-voice-failed", + "pipeline-error-rime-ai-voice-failed", + "pipeline-error-smallest-ai-voice-failed", + "pipeline-error-neuphonic-voice-failed", + "pipeline-error-hume-voice-failed", + "pipeline-error-sesame-voice-failed", + "pipeline-error-inworld-voice-failed", + "pipeline-error-minimax-voice-failed", + "pipeline-error-tavus-video-failed", + "call.in-progress.error-vapifault-openai-voice-failed", + "call.in-progress.error-vapifault-cartesia-voice-failed", + "call.in-progress.error-vapifault-deepgram-voice-failed", + "call.in-progress.error-vapifault-eleven-labs-voice-failed", + "call.in-progress.error-vapifault-playht-voice-failed", + "call.in-progress.error-vapifault-lmnt-voice-failed", + "call.in-progress.error-vapifault-azure-voice-failed", + "call.in-progress.error-vapifault-rime-ai-voice-failed", + "call.in-progress.error-vapifault-smallest-ai-voice-failed", + "call.in-progress.error-vapifault-neuphonic-voice-failed", + "call.in-progress.error-vapifault-hume-voice-failed", + "call.in-progress.error-vapifault-sesame-voice-failed", + "call.in-progress.error-vapifault-inworld-voice-failed", + "call.in-progress.error-vapifault-minimax-voice-failed", + "call.in-progress.error-vapifault-tavus-video-failed", + "pipeline-error-vapi-llm-failed", + "pipeline-error-vapi-400-bad-request-validation-failed", + "pipeline-error-vapi-401-unauthorized", + "pipeline-error-vapi-403-model-access-denied", + "pipeline-error-vapi-429-exceeded-quota", + "pipeline-error-vapi-500-server-error", + "pipeline-error-vapi-503-server-overloaded-error", + "call.in-progress.error-providerfault-vapi-llm-failed", + "call.in-progress.error-vapifault-vapi-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-vapi-401-unauthorized", + "call.in-progress.error-vapifault-vapi-403-model-access-denied", + "call.in-progress.error-vapifault-vapi-429-exceeded-quota", + "call.in-progress.error-providerfault-vapi-500-server-error", + "call.in-progress.error-providerfault-vapi-503-server-overloaded-error", + "pipeline-error-deepgram-transcriber-failed", + "call.in-progress.error-vapifault-deepgram-transcriber-failed", + "pipeline-error-gladia-transcriber-failed", + "call.in-progress.error-vapifault-gladia-transcriber-failed", + "pipeline-error-speechmatics-transcriber-failed", + "call.in-progress.error-vapifault-speechmatics-transcriber-failed", + "pipeline-error-assembly-ai-transcriber-failed", + "pipeline-error-assembly-ai-returning-400-insufficent-funds", + "pipeline-error-assembly-ai-returning-400-paid-only-feature", + "pipeline-error-assembly-ai-returning-401-invalid-credentials", + "pipeline-error-assembly-ai-returning-500-invalid-schema", + "pipeline-error-assembly-ai-returning-500-word-boost-parsing-failed", + "call.in-progress.error-vapifault-assembly-ai-transcriber-failed", + "call.in-progress.error-vapifault-assembly-ai-returning-400-insufficent-funds", + "call.in-progress.error-vapifault-assembly-ai-returning-400-paid-only-feature", + "call.in-progress.error-vapifault-assembly-ai-returning-401-invalid-credentials", + "call.in-progress.error-vapifault-assembly-ai-returning-500-invalid-schema", + "call.in-progress.error-vapifault-assembly-ai-returning-500-word-boost-parsing-failed", + "pipeline-error-talkscriber-transcriber-failed", + "call.in-progress.error-vapifault-talkscriber-transcriber-failed", + "pipeline-error-azure-speech-transcriber-failed", + "call.in-progress.error-vapifault-azure-speech-transcriber-failed", + "call.in-progress.error-pipeline-no-available-llm-model", + "worker-shutdown", + "vonage-disconnected", + "vonage-failed-to-connect-call", + "vonage-completed", + "phone-call-provider-bypass-enabled-but-no-call-received", + "call.in-progress.error-providerfault-transport-never-connected", + "call.in-progress.error-vapifault-worker-not-available", + "call.in-progress.error-vapifault-transport-never-connected", + "call.in-progress.error-vapifault-transport-connected-but-call-not-active", + "call.in-progress.error-vapifault-call-started-but-connection-to-transport-missing", + "call.in-progress.error-vapifault-worker-died", + "call.in-progress.twilio-completed-call", + "call.in-progress.sip-completed-call", + "call.in-progress.error-providerfault-openai-llm-failed", + "call.in-progress.error-providerfault-azure-openai-llm-failed", + "call.in-progress.error-providerfault-groq-llm-failed", + "call.in-progress.error-providerfault-google-llm-failed", + "call.in-progress.error-providerfault-xai-llm-failed", + "call.in-progress.error-providerfault-mistral-llm-failed", + "call.in-progress.error-providerfault-inflection-ai-llm-failed", + "call.in-progress.error-providerfault-cerebras-llm-failed", + "call.in-progress.error-providerfault-deep-seek-llm-failed", + "call.in-progress.error-vapifault-chat-pipeline-failed-to-start", + "pipeline-error-openai-400-bad-request-validation-failed", + "pipeline-error-openai-401-unauthorized", + "pipeline-error-openai-401-incorrect-api-key", + "pipeline-error-openai-401-account-not-in-organization", + "pipeline-error-openai-403-model-access-denied", + "pipeline-error-openai-429-exceeded-quota", + "pipeline-error-openai-429-rate-limit-reached", + "pipeline-error-openai-500-server-error", + "pipeline-error-openai-503-server-overloaded-error", + "pipeline-error-openai-llm-failed", + "call.in-progress.error-vapifault-openai-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-openai-401-unauthorized", + "call.in-progress.error-vapifault-openai-401-incorrect-api-key", + "call.in-progress.error-vapifault-openai-401-account-not-in-organization", + "call.in-progress.error-vapifault-openai-403-model-access-denied", + "call.in-progress.error-vapifault-openai-429-exceeded-quota", + "call.in-progress.error-vapifault-openai-429-rate-limit-reached", + "call.in-progress.error-providerfault-openai-500-server-error", + "call.in-progress.error-providerfault-openai-503-server-overloaded-error", + "pipeline-error-azure-openai-400-bad-request-validation-failed", + "pipeline-error-azure-openai-401-unauthorized", + "pipeline-error-azure-openai-403-model-access-denied", + "pipeline-error-azure-openai-429-exceeded-quota", + "pipeline-error-azure-openai-500-server-error", + "pipeline-error-azure-openai-503-server-overloaded-error", + "pipeline-error-azure-openai-llm-failed", + "call.in-progress.error-vapifault-azure-openai-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-azure-openai-401-unauthorized", + "call.in-progress.error-vapifault-azure-openai-403-model-access-denied", + "call.in-progress.error-vapifault-azure-openai-429-exceeded-quota", + "call.in-progress.error-providerfault-azure-openai-500-server-error", + "call.in-progress.error-providerfault-azure-openai-503-server-overloaded-error", + "pipeline-error-google-400-bad-request-validation-failed", + "pipeline-error-google-401-unauthorized", + "pipeline-error-google-403-model-access-denied", + "pipeline-error-google-429-exceeded-quota", + "pipeline-error-google-500-server-error", + "pipeline-error-google-503-server-overloaded-error", + "pipeline-error-google-llm-failed", + "call.in-progress.error-vapifault-google-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-google-401-unauthorized", + "call.in-progress.error-vapifault-google-403-model-access-denied", + "call.in-progress.error-vapifault-google-429-exceeded-quota", + "call.in-progress.error-providerfault-google-500-server-error", + "call.in-progress.error-providerfault-google-503-server-overloaded-error", + "pipeline-error-xai-400-bad-request-validation-failed", + "pipeline-error-xai-401-unauthorized", + "pipeline-error-xai-403-model-access-denied", + "pipeline-error-xai-429-exceeded-quota", + "pipeline-error-xai-500-server-error", + "pipeline-error-xai-503-server-overloaded-error", + "pipeline-error-xai-llm-failed", + "call.in-progress.error-vapifault-xai-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-xai-401-unauthorized", + "call.in-progress.error-vapifault-xai-403-model-access-denied", + "call.in-progress.error-vapifault-xai-429-exceeded-quota", + "call.in-progress.error-providerfault-xai-500-server-error", + "call.in-progress.error-providerfault-xai-503-server-overloaded-error", + "pipeline-error-mistral-400-bad-request-validation-failed", + "pipeline-error-mistral-401-unauthorized", + "pipeline-error-mistral-403-model-access-denied", + "pipeline-error-mistral-429-exceeded-quota", + "pipeline-error-mistral-500-server-error", + "pipeline-error-mistral-503-server-overloaded-error", + "pipeline-error-mistral-llm-failed", + "call.in-progress.error-vapifault-mistral-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-mistral-401-unauthorized", + "call.in-progress.error-vapifault-mistral-403-model-access-denied", + "call.in-progress.error-vapifault-mistral-429-exceeded-quota", + "call.in-progress.error-providerfault-mistral-500-server-error", + "call.in-progress.error-providerfault-mistral-503-server-overloaded-error", + "pipeline-error-inflection-ai-400-bad-request-validation-failed", + "pipeline-error-inflection-ai-401-unauthorized", + "pipeline-error-inflection-ai-403-model-access-denied", + "pipeline-error-inflection-ai-429-exceeded-quota", + "pipeline-error-inflection-ai-500-server-error", + "pipeline-error-inflection-ai-503-server-overloaded-error", + "pipeline-error-inflection-ai-llm-failed", + "call.in-progress.error-vapifault-inflection-ai-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-inflection-ai-401-unauthorized", + "call.in-progress.error-vapifault-inflection-ai-403-model-access-denied", + "call.in-progress.error-vapifault-inflection-ai-429-exceeded-quota", + "call.in-progress.error-providerfault-inflection-ai-500-server-error", + "call.in-progress.error-providerfault-inflection-ai-503-server-overloaded-error", + "pipeline-error-deep-seek-400-bad-request-validation-failed", + "pipeline-error-deep-seek-401-unauthorized", + "pipeline-error-deep-seek-403-model-access-denied", + "pipeline-error-deep-seek-429-exceeded-quota", + "pipeline-error-deep-seek-500-server-error", + "pipeline-error-deep-seek-503-server-overloaded-error", + "pipeline-error-deep-seek-llm-failed", + "call.in-progress.error-vapifault-deep-seek-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-deep-seek-401-unauthorized", + "call.in-progress.error-vapifault-deep-seek-403-model-access-denied", + "call.in-progress.error-vapifault-deep-seek-429-exceeded-quota", + "call.in-progress.error-providerfault-deep-seek-500-server-error", + "call.in-progress.error-providerfault-deep-seek-503-server-overloaded-error", + "pipeline-error-groq-400-bad-request-validation-failed", + "pipeline-error-groq-401-unauthorized", + "pipeline-error-groq-403-model-access-denied", + "pipeline-error-groq-429-exceeded-quota", + "pipeline-error-groq-500-server-error", + "pipeline-error-groq-503-server-overloaded-error", + "pipeline-error-groq-llm-failed", + "call.in-progress.error-vapifault-groq-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-groq-401-unauthorized", + "call.in-progress.error-vapifault-groq-403-model-access-denied", + "call.in-progress.error-vapifault-groq-429-exceeded-quota", + "call.in-progress.error-providerfault-groq-500-server-error", + "call.in-progress.error-providerfault-groq-503-server-overloaded-error", + "pipeline-error-cerebras-400-bad-request-validation-failed", + "pipeline-error-cerebras-401-unauthorized", + "pipeline-error-cerebras-403-model-access-denied", + "pipeline-error-cerebras-429-exceeded-quota", + "pipeline-error-cerebras-500-server-error", + "pipeline-error-cerebras-503-server-overloaded-error", + "pipeline-error-cerebras-llm-failed", + "call.in-progress.error-vapifault-cerebras-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-cerebras-401-unauthorized", + "call.in-progress.error-vapifault-cerebras-403-model-access-denied", + "call.in-progress.error-vapifault-cerebras-429-exceeded-quota", + "call.in-progress.error-providerfault-cerebras-500-server-error", + "call.in-progress.error-providerfault-cerebras-503-server-overloaded-error", + "pipeline-error-anthropic-400-bad-request-validation-failed", + "pipeline-error-anthropic-401-unauthorized", + "pipeline-error-anthropic-403-model-access-denied", + "pipeline-error-anthropic-429-exceeded-quota", + "pipeline-error-anthropic-500-server-error", + "pipeline-error-anthropic-503-server-overloaded-error", + "pipeline-error-anthropic-llm-failed", + "call.in-progress.error-providerfault-anthropic-llm-failed", + "call.in-progress.error-vapifault-anthropic-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-anthropic-401-unauthorized", + "call.in-progress.error-vapifault-anthropic-403-model-access-denied", + "call.in-progress.error-vapifault-anthropic-429-exceeded-quota", + "call.in-progress.error-providerfault-anthropic-500-server-error", + "call.in-progress.error-providerfault-anthropic-503-server-overloaded-error", + "pipeline-error-anthropic-bedrock-400-bad-request-validation-failed", + "pipeline-error-anthropic-bedrock-401-unauthorized", + "pipeline-error-anthropic-bedrock-403-model-access-denied", + "pipeline-error-anthropic-bedrock-429-exceeded-quota", + "pipeline-error-anthropic-bedrock-500-server-error", + "pipeline-error-anthropic-bedrock-503-server-overloaded-error", + "pipeline-error-anthropic-bedrock-llm-failed", + "call.in-progress.error-providerfault-anthropic-bedrock-llm-failed", + "call.in-progress.error-vapifault-anthropic-bedrock-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-anthropic-bedrock-401-unauthorized", + "call.in-progress.error-vapifault-anthropic-bedrock-403-model-access-denied", + "call.in-progress.error-vapifault-anthropic-bedrock-429-exceeded-quota", + "call.in-progress.error-providerfault-anthropic-bedrock-500-server-error", + "call.in-progress.error-providerfault-anthropic-bedrock-503-server-overloaded-error", + "pipeline-error-anthropic-vertex-400-bad-request-validation-failed", + "pipeline-error-anthropic-vertex-401-unauthorized", + "pipeline-error-anthropic-vertex-403-model-access-denied", + "pipeline-error-anthropic-vertex-429-exceeded-quota", + "pipeline-error-anthropic-vertex-500-server-error", + "pipeline-error-anthropic-vertex-503-server-overloaded-error", + "pipeline-error-anthropic-vertex-llm-failed", + "call.in-progress.error-providerfault-anthropic-vertex-llm-failed", + "call.in-progress.error-vapifault-anthropic-vertex-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-anthropic-vertex-401-unauthorized", + "call.in-progress.error-vapifault-anthropic-vertex-403-model-access-denied", + "call.in-progress.error-vapifault-anthropic-vertex-429-exceeded-quota", + "call.in-progress.error-providerfault-anthropic-vertex-500-server-error", + "call.in-progress.error-providerfault-anthropic-vertex-503-server-overloaded-error", + "pipeline-error-together-ai-400-bad-request-validation-failed", + "pipeline-error-together-ai-401-unauthorized", + "pipeline-error-together-ai-403-model-access-denied", + "pipeline-error-together-ai-429-exceeded-quota", + "pipeline-error-together-ai-500-server-error", + "pipeline-error-together-ai-503-server-overloaded-error", + "pipeline-error-together-ai-llm-failed", + "call.in-progress.error-providerfault-together-ai-llm-failed", + "call.in-progress.error-vapifault-together-ai-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-together-ai-401-unauthorized", + "call.in-progress.error-vapifault-together-ai-403-model-access-denied", + "call.in-progress.error-vapifault-together-ai-429-exceeded-quota", + "call.in-progress.error-providerfault-together-ai-500-server-error", + "call.in-progress.error-providerfault-together-ai-503-server-overloaded-error", + "pipeline-error-anyscale-400-bad-request-validation-failed", + "pipeline-error-anyscale-401-unauthorized", + "pipeline-error-anyscale-403-model-access-denied", + "pipeline-error-anyscale-429-exceeded-quota", + "pipeline-error-anyscale-500-server-error", + "pipeline-error-anyscale-503-server-overloaded-error", + "pipeline-error-anyscale-llm-failed", + "call.in-progress.error-providerfault-anyscale-llm-failed", + "call.in-progress.error-vapifault-anyscale-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-anyscale-401-unauthorized", + "call.in-progress.error-vapifault-anyscale-403-model-access-denied", + "call.in-progress.error-vapifault-anyscale-429-exceeded-quota", + "call.in-progress.error-providerfault-anyscale-500-server-error", + "call.in-progress.error-providerfault-anyscale-503-server-overloaded-error", + "pipeline-error-openrouter-400-bad-request-validation-failed", + "pipeline-error-openrouter-401-unauthorized", + "pipeline-error-openrouter-403-model-access-denied", + "pipeline-error-openrouter-429-exceeded-quota", + "pipeline-error-openrouter-500-server-error", + "pipeline-error-openrouter-503-server-overloaded-error", + "pipeline-error-openrouter-llm-failed", + "call.in-progress.error-providerfault-openrouter-llm-failed", + "call.in-progress.error-vapifault-openrouter-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-openrouter-401-unauthorized", + "call.in-progress.error-vapifault-openrouter-403-model-access-denied", + "call.in-progress.error-vapifault-openrouter-429-exceeded-quota", + "call.in-progress.error-providerfault-openrouter-500-server-error", + "call.in-progress.error-providerfault-openrouter-503-server-overloaded-error", + "pipeline-error-perplexity-ai-400-bad-request-validation-failed", + "pipeline-error-perplexity-ai-401-unauthorized", + "pipeline-error-perplexity-ai-403-model-access-denied", + "pipeline-error-perplexity-ai-429-exceeded-quota", + "pipeline-error-perplexity-ai-500-server-error", + "pipeline-error-perplexity-ai-503-server-overloaded-error", + "pipeline-error-perplexity-ai-llm-failed", + "call.in-progress.error-providerfault-perplexity-ai-llm-failed", + "call.in-progress.error-vapifault-perplexity-ai-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-perplexity-ai-401-unauthorized", + "call.in-progress.error-vapifault-perplexity-ai-403-model-access-denied", + "call.in-progress.error-vapifault-perplexity-ai-429-exceeded-quota", + "call.in-progress.error-providerfault-perplexity-ai-500-server-error", + "call.in-progress.error-providerfault-perplexity-ai-503-server-overloaded-error", + "pipeline-error-deepinfra-400-bad-request-validation-failed", + "pipeline-error-deepinfra-401-unauthorized", + "pipeline-error-deepinfra-403-model-access-denied", + "pipeline-error-deepinfra-429-exceeded-quota", + "pipeline-error-deepinfra-500-server-error", + "pipeline-error-deepinfra-503-server-overloaded-error", + "pipeline-error-deepinfra-llm-failed", + "call.in-progress.error-providerfault-deepinfra-llm-failed", + "call.in-progress.error-vapifault-deepinfra-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-deepinfra-401-unauthorized", + "call.in-progress.error-vapifault-deepinfra-403-model-access-denied", + "call.in-progress.error-vapifault-deepinfra-429-exceeded-quota", + "call.in-progress.error-providerfault-deepinfra-500-server-error", + "call.in-progress.error-providerfault-deepinfra-503-server-overloaded-error", + "pipeline-error-runpod-400-bad-request-validation-failed", + "pipeline-error-runpod-401-unauthorized", + "pipeline-error-runpod-403-model-access-denied", + "pipeline-error-runpod-429-exceeded-quota", + "pipeline-error-runpod-500-server-error", + "pipeline-error-runpod-503-server-overloaded-error", + "pipeline-error-runpod-llm-failed", + "call.in-progress.error-providerfault-runpod-llm-failed", + "call.in-progress.error-vapifault-runpod-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-runpod-401-unauthorized", + "call.in-progress.error-vapifault-runpod-403-model-access-denied", + "call.in-progress.error-vapifault-runpod-429-exceeded-quota", + "call.in-progress.error-providerfault-runpod-500-server-error", + "call.in-progress.error-providerfault-runpod-503-server-overloaded-error", + "pipeline-error-custom-llm-400-bad-request-validation-failed", + "pipeline-error-custom-llm-401-unauthorized", + "pipeline-error-custom-llm-403-model-access-denied", + "pipeline-error-custom-llm-429-exceeded-quota", + "pipeline-error-custom-llm-500-server-error", + "pipeline-error-custom-llm-503-server-overloaded-error", + "pipeline-error-custom-llm-llm-failed", + "call.in-progress.error-providerfault-custom-llm-llm-failed", + "call.in-progress.error-vapifault-custom-llm-400-bad-request-validation-failed", + "call.in-progress.error-vapifault-custom-llm-401-unauthorized", + "call.in-progress.error-vapifault-custom-llm-403-model-access-denied", + "call.in-progress.error-vapifault-custom-llm-429-exceeded-quota", + "call.in-progress.error-providerfault-custom-llm-500-server-error", + "call.in-progress.error-providerfault-custom-llm-503-server-overloaded-error", + "pipeline-error-custom-voice-failed", + "pipeline-error-cartesia-socket-hang-up", + "pipeline-error-cartesia-requested-payment", + "pipeline-error-cartesia-500-server-error", + "pipeline-error-cartesia-502-server-error", + "pipeline-error-cartesia-503-server-error", + "pipeline-error-cartesia-522-server-error", + "call.in-progress.error-vapifault-cartesia-socket-hang-up", + "call.in-progress.error-vapifault-cartesia-requested-payment", + "call.in-progress.error-providerfault-cartesia-500-server-error", + "call.in-progress.error-providerfault-cartesia-503-server-error", + "call.in-progress.error-providerfault-cartesia-522-server-error", + "pipeline-error-eleven-labs-voice-not-found", + "pipeline-error-eleven-labs-quota-exceeded", + "pipeline-error-eleven-labs-unauthorized-access", + "pipeline-error-eleven-labs-unauthorized-to-access-model", + "pipeline-error-eleven-labs-professional-voices-only-for-creator-plus", + "pipeline-error-eleven-labs-blocked-free-plan-and-requested-upgrade", + "pipeline-error-eleven-labs-blocked-concurrent-requests-and-requested-upgrade", + "pipeline-error-eleven-labs-blocked-using-instant-voice-clone-and-requested-upgrade", + "pipeline-error-eleven-labs-system-busy-and-requested-upgrade", + "pipeline-error-eleven-labs-voice-not-fine-tuned", + "pipeline-error-eleven-labs-invalid-api-key", + "pipeline-error-eleven-labs-invalid-voice-samples", + "pipeline-error-eleven-labs-voice-disabled-by-owner", + "pipeline-error-eleven-labs-vapi-voice-disabled-by-owner", + "pipeline-error-eleven-labs-blocked-account-in-probation", + "pipeline-error-eleven-labs-blocked-content-against-their-policy", + "pipeline-error-eleven-labs-missing-samples-for-voice-clone", + "pipeline-error-eleven-labs-voice-not-fine-tuned-and-cannot-be-used", + "pipeline-error-eleven-labs-voice-not-allowed-for-free-users", + "pipeline-error-eleven-labs-max-character-limit-exceeded", + "pipeline-error-eleven-labs-blocked-voice-potentially-against-terms-of-service-and-awaiting-verification", + "pipeline-error-eleven-labs-500-server-error", + "pipeline-error-eleven-labs-503-server-error", + "call.in-progress.error-vapifault-eleven-labs-voice-not-found", + "call.in-progress.error-vapifault-eleven-labs-quota-exceeded", + "call.in-progress.error-vapifault-eleven-labs-unauthorized-access", + "call.in-progress.error-vapifault-eleven-labs-unauthorized-to-access-model", + "call.in-progress.error-vapifault-eleven-labs-professional-voices-only-for-creator-plus", + "call.in-progress.error-vapifault-eleven-labs-blocked-free-plan-and-requested-upgrade", + "call.in-progress.error-vapifault-eleven-labs-blocked-concurrent-requests-and-requested-upgrade", + "call.in-progress.error-vapifault-eleven-labs-blocked-using-instant-voice-clone-and-requested-upgrade", + "call.in-progress.error-vapifault-eleven-labs-system-busy-and-requested-upgrade", + "call.in-progress.error-vapifault-eleven-labs-voice-not-fine-tuned", + "call.in-progress.error-vapifault-eleven-labs-invalid-api-key", + "call.in-progress.error-vapifault-eleven-labs-invalid-voice-samples", + "call.in-progress.error-vapifault-eleven-labs-voice-disabled-by-owner", + "call.in-progress.error-vapifault-eleven-labs-blocked-account-in-probation", + "call.in-progress.error-vapifault-eleven-labs-blocked-content-against-their-policy", + "call.in-progress.error-vapifault-eleven-labs-missing-samples-for-voice-clone", + "call.in-progress.error-vapifault-eleven-labs-voice-not-fine-tuned-and-cannot-be-used", + "call.in-progress.error-vapifault-eleven-labs-voice-not-allowed-for-free-users", + "call.in-progress.error-vapifault-eleven-labs-max-character-limit-exceeded", + "call.in-progress.error-vapifault-eleven-labs-blocked-voice-potentially-against-terms-of-service-and-awaiting-verification", + "call.in-progress.error-providerfault-eleven-labs-500-server-error", + "call.in-progress.error-providerfault-eleven-labs-503-server-error", + "pipeline-error-playht-request-timed-out", + "pipeline-error-playht-invalid-voice", + "pipeline-error-playht-unexpected-error", + "pipeline-error-playht-out-of-credits", + "pipeline-error-playht-invalid-emotion", + "pipeline-error-playht-voice-must-be-a-valid-voice-manifest-uri", + "pipeline-error-playht-401-unauthorized", + "pipeline-error-playht-403-forbidden-out-of-characters", + "pipeline-error-playht-403-forbidden-api-access-not-available", + "pipeline-error-playht-429-exceeded-quota", + "pipeline-error-playht-502-gateway-error", + "pipeline-error-playht-504-gateway-error", + "call.in-progress.error-vapifault-playht-request-timed-out", + "call.in-progress.error-vapifault-playht-invalid-voice", + "call.in-progress.error-vapifault-playht-unexpected-error", + "call.in-progress.error-vapifault-playht-out-of-credits", + "call.in-progress.error-vapifault-playht-invalid-emotion", + "call.in-progress.error-vapifault-playht-voice-must-be-a-valid-voice-manifest-uri", + "call.in-progress.error-vapifault-playht-401-unauthorized", + "call.in-progress.error-vapifault-playht-403-forbidden-out-of-characters", + "call.in-progress.error-vapifault-playht-403-forbidden-api-access-not-available", + "call.in-progress.error-vapifault-playht-429-exceeded-quota", + "call.in-progress.error-providerfault-playht-502-gateway-error", + "call.in-progress.error-providerfault-playht-504-gateway-error", + "pipeline-error-custom-transcriber-failed", + "call.in-progress.error-vapifault-custom-transcriber-failed", + "pipeline-error-eleven-labs-transcriber-failed", + "call.in-progress.error-vapifault-eleven-labs-transcriber-failed", + "pipeline-error-deepgram-returning-400-no-such-model-language-tier-combination", + "pipeline-error-deepgram-returning-401-invalid-credentials", + "pipeline-error-deepgram-returning-403-model-access-denied", + "pipeline-error-deepgram-returning-404-not-found", + "pipeline-error-deepgram-returning-500-invalid-json", + "pipeline-error-deepgram-returning-502-network-error", + "pipeline-error-deepgram-returning-502-bad-gateway-ehostunreach", + "pipeline-error-deepgram-returning-econnreset", + "call.in-progress.error-vapifault-deepgram-returning-400-no-such-model-language-tier-combination", + "call.in-progress.error-vapifault-deepgram-returning-401-invalid-credentials", + "call.in-progress.error-vapifault-deepgram-returning-404-not-found", + "call.in-progress.error-vapifault-deepgram-returning-403-model-access-denied", + "call.in-progress.error-providerfault-deepgram-returning-500-invalid-json", + "call.in-progress.error-providerfault-deepgram-returning-502-network-error", + "call.in-progress.error-providerfault-deepgram-returning-502-bad-gateway-ehostunreach", + "pipeline-error-google-transcriber-failed", + "call.in-progress.error-vapifault-google-transcriber-failed", + "pipeline-error-openai-transcriber-failed", + "call.in-progress.error-vapifault-openai-transcriber-failed", + "call.in-progress.error-warm-transfer-max-duration", + "call.in-progress.error-warm-transfer-assistant-cancelled", + "call.in-progress.error-warm-transfer-silence-timeout", + "call.in-progress.error-warm-transfer-microphone-timeout", + "call.in-progress.error-warm-transfer-hang-timeout", + "call.in-progress.error-warm-transfer-idle-timeout", + "assistant-ended-call", + "assistant-said-end-call-phrase", + "assistant-ended-call-with-hangup-task", + "assistant-ended-call-after-message-spoken", + "assistant-forwarded-call", + "assistant-join-timed-out", + "call.in-progress.error-assistant-did-not-receive-customer-audio", + "call.in-progress.error-transfer-failed", + "customer-busy", + "customer-ended-call", + "customer-ended-call-after-warm-transfer-attempt", + "customer-did-not-answer", + "customer-did-not-give-microphone-permission", + "exceeded-max-duration", + "manually-canceled", + "phone-call-provider-closed-websocket", + "call.forwarding.operator-busy", + "silence-timed-out", + "call.in-progress.error-sip-inbound-call-failed-to-connect", + "call.in-progress.error-providerfault-outbound-sip-403-forbidden", + "call.in-progress.error-providerfault-outbound-sip-407-proxy-authentication-required", + "call.in-progress.error-providerfault-outbound-sip-503-service-unavailable", + "call.in-progress.error-providerfault-outbound-sip-480-temporarily-unavailable", + "call.in-progress.error-sip-outbound-call-failed-to-connect", + "call.ringing.hook-executed-say", + "call.ringing.hook-executed-transfer", + "call.ending.hook-executed-say", + "call.ending.hook-executed-transfer", + "call.ringing.sip-inbound-caller-hungup-before-call-connect", + "call.ringing.error-sip-inbound-call-failed-to-connect", + "twilio-failed-to-connect-call", + "twilio-reported-customer-misdialed", + "vonage-rejected", + "voicemail" ] - }, - "credentials": { - "type": "array", - "description": "These are dynamic credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/CreateAnthropicCredentialDTO", - "title": "AnthropicCredential" - }, - { - "$ref": "#/components/schemas/CreateAnyscaleCredentialDTO", - "title": "AnyscaleCredential" - }, - { - "$ref": "#/components/schemas/CreateAssemblyAICredentialDTO", - "title": "AssemblyAICredential" - }, - { - "$ref": "#/components/schemas/CreateAzureCredentialDTO", - "title": "AzureCredential" - }, - { - "$ref": "#/components/schemas/CreateAzureOpenAICredentialDTO", - "title": "AzureOpenAICredential" - }, - { - "$ref": "#/components/schemas/CreateByoSipTrunkCredentialDTO", - "title": "ByoSipTrunkCredential" - }, - { - "$ref": "#/components/schemas/CreateCartesiaCredentialDTO", - "title": "CartesiaCredential" - }, - { - "$ref": "#/components/schemas/CreateCerebrasCredentialDTO", - "title": "CerebrasCredential" - }, - { - "$ref": "#/components/schemas/CreateCloudflareCredentialDTO", - "title": "CloudflareCredential" - }, - { - "$ref": "#/components/schemas/CreateCustomLLMCredentialDTO", - "title": "CustomLLMCredential" - }, - { - "$ref": "#/components/schemas/CreateDeepgramCredentialDTO", - "title": "DeepgramCredential" - }, - { - "$ref": "#/components/schemas/CreateDeepInfraCredentialDTO", - "title": "DeepInfraCredential" - }, - { - "$ref": "#/components/schemas/CreateDeepSeekCredentialDTO", - "title": "DeepSeekCredential" - }, - { - "$ref": "#/components/schemas/CreateElevenLabsCredentialDTO", - "title": "ElevenLabsCredential" - }, - { - "$ref": "#/components/schemas/CreateGcpCredentialDTO", - "title": "GcpCredential" - }, - { - "$ref": "#/components/schemas/CreateGladiaCredentialDTO", - "title": "GladiaCredential" - }, - { - "$ref": "#/components/schemas/CreateGoHighLevelCredentialDTO", - "title": "GhlCredential" - }, - { - "$ref": "#/components/schemas/CreateGoogleCredentialDTO", - "title": "GoogleCredential" - }, - { - "$ref": "#/components/schemas/CreateGroqCredentialDTO", - "title": "GroqCredential" - }, - { - "$ref": "#/components/schemas/CreateHumeCredentialDTO", - "title": "HumeCredential" - }, - { - "$ref": "#/components/schemas/CreateInflectionAICredentialDTO", - "title": "InflectionAICredential" - }, - { - "$ref": "#/components/schemas/CreateLangfuseCredentialDTO", - "title": "LangfuseCredential" - }, - { - "$ref": "#/components/schemas/CreateLmntCredentialDTO", - "title": "LmntCredential" - }, - { - "$ref": "#/components/schemas/CreateMakeCredentialDTO", - "title": "MakeCredential" - }, - { - "$ref": "#/components/schemas/CreateMistralCredentialDTO", - "title": "MistralCredential" - }, - { - "$ref": "#/components/schemas/CreateNeuphonicCredentialDTO", - "title": "NeuphonicCredential" - }, - { - "$ref": "#/components/schemas/CreateOpenAICredentialDTO", - "title": "OpenAICredential" - }, - { - "$ref": "#/components/schemas/CreateOpenRouterCredentialDTO", - "title": "OpenRouterCredential" - }, - { - "$ref": "#/components/schemas/CreatePerplexityAICredentialDTO", - "title": "PerplexityAICredential" - }, - { - "$ref": "#/components/schemas/CreatePlayHTCredentialDTO", - "title": "PlayHTCredential" - }, - { - "$ref": "#/components/schemas/CreateRimeAICredentialDTO", - "title": "RimeAICredential" - }, - { - "$ref": "#/components/schemas/CreateRunpodCredentialDTO", - "title": "RunpodCredential" - }, - { - "$ref": "#/components/schemas/CreateS3CredentialDTO", - "title": "S3Credential" - }, - { - "$ref": "#/components/schemas/CreateSmallestAICredentialDTO", - "title": "SmallestAICredential" - }, - { - "$ref": "#/components/schemas/CreateSpeechmaticsCredentialDTO", - "title": "SpeechmaticsCredential" - }, - { - "$ref": "#/components/schemas/CreateSupabaseCredentialDTO", - "title": "SupabaseCredential" - }, - { - "$ref": "#/components/schemas/CreateTavusCredentialDTO", - "title": "TavusCredential" - }, - { - "$ref": "#/components/schemas/CreateTogetherAICredentialDTO", - "title": "TogetherAICredential" - }, - { - "$ref": "#/components/schemas/CreateTrieveCredentialDTO", - "title": "TrieveCredential" - }, - { - "$ref": "#/components/schemas/CreateTwilioCredentialDTO", - "title": "TwilioCredential" - }, - { - "$ref": "#/components/schemas/CreateVonageCredentialDTO", - "title": "VonageCredential" - }, - { - "$ref": "#/components/schemas/CreateWebhookCredentialDTO", - "title": "WebhookCredential" - }, - { - "$ref": "#/components/schemas/CreateXAiCredentialDTO", - "title": "XAiCredential" - }, - { - "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", - "title": "GoogleCalendarOAuth2ClientCredential" - }, - { - "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", - "title": "GoogleCalendarOAuth2AuthorizationCredential" - }, - { - "$ref": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", - "title": "GoogleSheetsOAuth2AuthorizationCredential" - }, - { - "$ref": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", - "title": "SlackOAuth2AuthorizationCredential" - }, - { - "$ref": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", - "title": "GoHighLevelMCPCredential" - }, - { - "$ref": "#/components/schemas/CreateInworldCredentialDTO", - "title": "InworldCredential" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "11labs": "#/components/schemas/CreateElevenLabsCredentialDTO", - "anthropic": "#/components/schemas/CreateAnthropicCredentialDTO", - "anyscale": "#/components/schemas/CreateAnyscaleCredentialDTO", - "assembly-ai": "#/components/schemas/CreateAssemblyAICredentialDTO", - "azure-openai": "#/components/schemas/CreateAzureOpenAICredentialDTO", - "azure": "#/components/schemas/CreateAzureCredentialDTO", - "byo-sip-trunk": "#/components/schemas/CreateByoSipTrunkCredentialDTO", - "cartesia": "#/components/schemas/CreateCartesiaCredentialDTO", - "cerebras": "#/components/schemas/CreateCerebrasCredentialDTO", - "cloudflare": "#/components/schemas/CreateCloudflareCredentialDTO", - "custom-llm": "#/components/schemas/CreateCustomLLMCredentialDTO", - "deepgram": "#/components/schemas/CreateDeepgramCredentialDTO", - "deepinfra": "#/components/schemas/CreateDeepInfraCredentialDTO", - "deep-seek": "#/components/schemas/CreateDeepSeekCredentialDTO", - "gcp": "#/components/schemas/CreateGcpCredentialDTO", - "gladia": "#/components/schemas/CreateGladiaCredentialDTO", - "gohighlevel": "#/components/schemas/CreateGoHighLevelCredentialDTO", - "google": "#/components/schemas/CreateGoogleCredentialDTO", - "groq": "#/components/schemas/CreateGroqCredentialDTO", - "inflection-ai": "#/components/schemas/CreateInflectionAICredentialDTO", - "langfuse": "#/components/schemas/CreateLangfuseCredentialDTO", - "lmnt": "#/components/schemas/CreateLmntCredentialDTO", - "make": "#/components/schemas/CreateMakeCredentialDTO", - "openai": "#/components/schemas/CreateOpenAICredentialDTO", - "openrouter": "#/components/schemas/CreateOpenRouterCredentialDTO", - "perplexity-ai": "#/components/schemas/CreatePerplexityAICredentialDTO", - "playht": "#/components/schemas/CreatePlayHTCredentialDTO", - "rime-ai": "#/components/schemas/CreateRimeAICredentialDTO", - "runpod": "#/components/schemas/CreateRunpodCredentialDTO", - "s3": "#/components/schemas/CreateS3CredentialDTO", - "supabase": "#/components/schemas/CreateSupabaseCredentialDTO", - "smallest-ai": "#/components/schemas/CreateSmallestAICredentialDTO", - "tavus": "#/components/schemas/CreateTavusCredentialDTO", - "together-ai": "#/components/schemas/CreateTogetherAICredentialDTO", - "twilio": "#/components/schemas/CreateTwilioCredentialDTO", - "vonage": "#/components/schemas/CreateVonageCredentialDTO", - "webhook": "#/components/schemas/CreateWebhookCredentialDTO", - "xai": "#/components/schemas/CreateXAiCredentialDTO", - "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", - "hume": "#/components/schemas/CreateHumeCredentialDTO", - "mistral": "#/components/schemas/CreateMistralCredentialDTO", - "speechmatics": "#/components/schemas/CreateSpeechmaticsCredentialDTO", - "trieve": "#/components/schemas/CreateTrieveCredentialDTO", - "google.calendar.oauth2-client": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", - "google.calendar.oauth2-authorization": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", - "google.sheets.oauth2-authorization": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", - "slack.oauth2-authorization": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", - "ghl.oauth2-authorization": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", - "inworld": "#/components/schemas/CreateInworldCredentialDTO", - "minimax": "#/components/schemas/CreateMinimaxCredentialDTO" - } + }, + "destination": { + "description": "This is the destination where the call ended up being transferred to. If the call was not transferred, this will be empty.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" } - } + ] }, - "hooks": { - "type": "array", - "description": "This is a set of actions that will be performed on certain events.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/CallHookCallEnding", - "title": "CallHookCallEnding" - }, - { - "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", - "title": "CallHookAssistantSpeechInterrupted" - }, - { - "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", - "title": "CallHookCustomerSpeechInterrupted" - }, - { - "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", - "title": "CallHookCustomerSpeechTimeout" - } - ] - } + "id": { + "type": "string", + "description": "This is the unique identifier for the call." }, - "name": { + "orgId": { "type": "string", - "description": "This is the name of the assistant.\n\nThis is required when you want to transfer between assistants in a call.", - "maxLength": 40 + "description": "This is the unique identifier for the org that this call belongs to." }, - "voicemailMessage": { + "createdAt": { + "format": "date-time", "type": "string", - "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", - "maxLength": 1000 + "description": "This is the ISO 8601 date-time string of when the call was created." }, - "endCallMessage": { + "updatedAt": { + "format": "date-time", "type": "string", - "description": "This is the message that the assistant will say if it ends the call.\n\nIf unspecified, it will hang up without saying anything.", - "maxLength": 1000 + "description": "This is the ISO 8601 date-time string of when the call was last updated." }, - "endCallPhrases": { - "description": "This list contains phrases that, if spoken by the assistant, will trigger the call to be hung up. Case insensitive.", - "type": "array", - "items": { - "type": "string", - "maxLength": 140, - "minLength": 2 - } + "startedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the call was started." }, - "compliancePlan": { - "$ref": "#/components/schemas/CompliancePlan" + "endedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the call was ended." }, - "metadata": { - "type": "object", - "description": "This is for metadata you want to store on the assistant." + "cost": { + "type": "number", + "description": "This is the cost of the call in USD." }, - "backgroundSpeechDenoisingPlan": { - "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nSmart denoising can be combined with or used independently of Fourier denoising.\n\nOrder of precedence:\n- Smart denoising\n- Fourier denoising", + "costBreakdown": { + "description": "This is the cost of the call in USD.", "allOf": [ { - "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" + "$ref": "#/components/schemas/CostBreakdown" } ] }, - "analysisPlan": { - "description": "This is the plan for analysis of assistant's calls. Stored in `call.analysis`.", + "artifactPlan": { + "description": "This is a copy of assistant artifact plan. This isn't actually stored on the call but rather just returned in POST /call/web to enable artifact creation client side.", "allOf": [ { - "$ref": "#/components/schemas/AnalysisPlan" + "$ref": "#/components/schemas/ArtifactPlan" } ] }, - "artifactPlan": { - "description": "This is the plan for artifacts generated during assistant's calls. Stored in `call.artifact`.", + "analysis": { + "description": "This is the analysis of the call. Configure in `assistant.analysisPlan`.", "allOf": [ { - "$ref": "#/components/schemas/ArtifactPlan" + "$ref": "#/components/schemas/Analysis" } ] }, - "startSpeakingPlan": { - "description": "This is the plan for when the assistant should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", + "monitor": { + "description": "This is to real-time monitor the call. Configure in `assistant.monitorPlan`.", "allOf": [ { - "$ref": "#/components/schemas/StartSpeakingPlan" + "$ref": "#/components/schemas/Monitor" } ] }, - "stopSpeakingPlan": { - "description": "This is the plan for when assistant should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", + "artifact": { + "description": "These are the artifacts created from the call. Configure in `assistant.artifactPlan`.", "allOf": [ { - "$ref": "#/components/schemas/StopSpeakingPlan" + "$ref": "#/components/schemas/Artifact" } ] }, - "monitorPlan": { - "description": "This is the plan for real-time monitoring of the assistant's calls.\n\nUsage:\n- To enable live listening of the assistant's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the assistant's calls, set `monitorPlan.controlEnabled` to `true`.", + "phoneCallProviderId": { + "type": "string", + "description": "The ID of the call as provided by the phone number service. callSid in Twilio. conversationUuid in Vonage. callControlId in Telnyx.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "deprecated": true + }, + "campaignId": { + "type": "string", + "description": "This is the campaign ID that the call belongs to." + }, + "assistantId": { + "type": "string", + "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" + }, + "assistant": { + "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", "allOf": [ { - "$ref": "#/components/schemas/MonitorPlan" + "$ref": "#/components/schemas/CreateAssistantDTO" } ] }, - "credentialIds": { - "description": "These are the credentials that will be used for the assistant calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", - "type": "array", - "items": { - "type": "string" - } - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server.url\n2. phoneNumber.serverUrl\n3. org.serverUrl", + "assistantOverrides": { + "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/AssistantOverrides" } ] }, - "keypadInputPlan": { - "$ref": "#/components/schemas/KeypadInputPlan" - } - } - }, - "ByoPhoneNumber": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" + }, + "squad": { + "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/CreateSquadDTO" } ] }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "provider": { + "workflowId": { "type": "string", - "description": "This is to bring your own phone numbers from your own SIP trunks or Carriers.", - "enum": [ - "byo-phone-number" - ] + "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" }, - "numberE164CheckEnabled": { - "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true + "workflow": { + "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateWorkflowDTO" + } + ] }, - "id": { - "type": "string", - "description": "This is the unique identifier for the phone number." + "workflowOverrides": { + "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", + "allOf": [ + { + "$ref": "#/components/schemas/WorkflowOverrides" + } + ] }, - "orgId": { + "phoneNumberId": { "type": "string", - "description": "This is the unique identifier for the org that this phone number belongs to." + "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was created." + "phoneNumber": { + "description": "This is the phone number that will be used for the call. To use an existing number, use `phoneNumberId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "allOf": [ + { + "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" + } + ] }, - "updatedAt": { - "format": "date-time", + "customerId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was last updated." + "description": "This is the customer that will be called. To call a transient customer , use `customer` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." }, - "status": { - "type": "string", - "description": "This is the status of the phone number.", - "enum": [ - "active", - "activating", - "blocked" + "customer": { + "description": "This is the customer that will be called. To call an existing customer, use `customerId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateCustomerDTO" + } ] }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is the name of the call. This is just for your own reference.", "maxLength": 40 }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "schedulePlan": { + "description": "This is the schedule plan of the call.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/SchedulePlan" } ] }, - "number": { - "type": "string", - "description": "This is the number of the customer.", - "minLength": 3, - "maxLength": 40 - }, - "credentialId": { - "type": "string", - "description": "This is the credential of your own SIP trunk or Carrier (type `byo-sip-trunk`) which can be used to make calls to this phone number.\n\nYou can add the SIP trunk or Carrier credential in the Provider Credentials page on the Dashboard to get the credentialId." + "transport": { + "type": "object", + "description": "This is the transport of the call." } }, "required": [ - "provider", "id", "orgId", "createdAt", - "updatedAt", - "credentialId" + "updatedAt" ] }, - "TwilioPhoneNumber": { + "CallBatchError": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] + "customer": { + "$ref": "#/components/schemas/CreateCustomerDTO" }, - "hooks": { + "error": { + "type": "string" + } + }, + "required": [ + "customer", + "error" + ] + }, + "CallBatchResponse": { + "type": "object", + "properties": { + "results": { + "description": "This is the list of calls that were created.", "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] + "$ref": "#/components/schemas/Call" } }, - "provider": { - "type": "string", - "description": "This is to use numbers bought on Twilio.", - "enum": [ - "twilio" - ] - }, - "smsEnabled": { - "type": "boolean", - "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", - "default": true - }, - "id": { - "type": "string", - "description": "This is the unique identifier for the phone number." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the org that this phone number belongs to." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was created." - }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was last updated." - }, - "status": { - "type": "string", - "description": "This is the status of the phone number.", - "enum": [ - "active", - "activating", - "blocked" - ] - }, - "twilioAuthToken": { - "type": "string", - "description": "This is the Twilio Auth Token for the phone number." - }, - "twilioApiKey": { - "type": "string", - "description": "This is the Twilio API Key for the phone number." - }, - "twilioApiSecret": { - "type": "string", - "description": "This is the Twilio API Secret for the phone number." - }, - "name": { - "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 - }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - }, - "number": { - "type": "string", - "description": "These are the digits of the phone number you own on your Twilio." - }, - "twilioAccountSid": { - "type": "string", - "description": "This is the Twilio Account SID for the phone number." + "errors": { + "description": "This is the list of calls that failed to be created.", + "type": "array", + "items": { + "$ref": "#/components/schemas/CallBatchError" + } } }, "required": [ - "provider", - "id", - "orgId", - "createdAt", - "updatedAt", - "number", - "twilioAccountSid" + "results", + "errors" ] }, - "VonagePhoneNumber": { + "CreateCallDTO": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { + "customers": { + "description": "This is used to issue batch calls to multiple customers.\n\nOnly relevant for `outboundPhoneCall`. To call a single customer, use `customer` instead.", "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] + "$ref": "#/components/schemas/CreateCustomerDTO" } }, - "provider": { + "name": { "type": "string", - "description": "This is to use numbers bought on Vonage.", - "enum": [ - "vonage" + "description": "This is the name of the call. This is just for your own reference.", + "maxLength": 40 + }, + "schedulePlan": { + "description": "This is the schedule plan of the call.", + "allOf": [ + { + "$ref": "#/components/schemas/SchedulePlan" + } ] }, - "id": { - "type": "string", - "description": "This is the unique identifier for the phone number." + "transport": { + "type": "object", + "description": "This is the transport of the call." }, - "orgId": { + "assistantId": { "type": "string", - "description": "This is the unique identifier for the org that this phone number belongs to." + "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was created." + "assistant": { + "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } + ] }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was last updated." + "assistantOverrides": { + "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } + ] }, - "status": { + "squadId": { "type": "string", - "description": "This is the status of the phone number.", - "enum": [ - "active", - "activating", - "blocked" + "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" + }, + "squad": { + "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } ] }, - "name": { + "workflowId": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 + "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "workflow": { + "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateWorkflowDTO" + } + ] }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "workflowOverrides": { + "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", + "allOf": [ + { + "$ref": "#/components/schemas/WorkflowOverrides" + } + ] }, - "squadId": { + "phoneNumberId": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "phoneNumber": { + "description": "This is the phone number that will be used for the call. To use an existing number, use `phoneNumberId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" } ] }, - "number": { + "customerId": { "type": "string", - "description": "These are the digits of the phone number you own on your Vonage." + "description": "This is the customer that will be called. To call a transient customer , use `customer` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." }, - "credentialId": { - "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." + "customer": { + "description": "This is the customer that will be called. To call an existing customer, use `customerId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateCustomerDTO" + } + ] } - }, - "required": [ - "provider", - "id", - "orgId", - "createdAt", - "updatedAt", - "number", - "credentialId" - ] + } }, - "SipAuthentication": { + "CallPaginatedResponse": { "type": "object", "properties": { - "realm": { - "type": "string", - "description": "This will be expected in the `realm` field of the `authorization` header of the SIP INVITE. Defaults to sip.vapi.ai." - }, - "username": { - "type": "string", - "description": "This will be expected in the `username` field of the `authorization` header of the SIP INVITE.", - "minLength": 20, - "maxLength": 40 + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Call" + } }, - "password": { - "type": "string", - "description": "This will be expected to generate the `response` field of the `authorization` header of the SIP INVITE, through digest authentication.", - "minLength": 20, - "maxLength": 40 + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" } }, "required": [ - "username", - "password" + "results", + "metadata" ] }, - "VapiPhoneNumber": { + "CreateOutboundCallDTO": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { + "customers": { + "description": "This is used to issue batch calls to multiple customers.\n\nOnly relevant for `outboundPhoneCall`. To call a single customer, use `customer` instead.", "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] + "$ref": "#/components/schemas/CreateCustomerDTO" } }, - "provider": { - "type": "string", - "description": "This is to create free SIP phone numbers on Vapi.", - "enum": [ - "vapi" - ] - }, - "id": { + "name": { "type": "string", - "description": "This is the unique identifier for the phone number." + "description": "This is the name of the call. This is just for your own reference.", + "maxLength": 40 }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the org that this phone number belongs to." + "schedulePlan": { + "description": "This is the schedule plan of the call.", + "allOf": [ + { + "$ref": "#/components/schemas/SchedulePlan" + } + ] }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was created." + "transport": { + "type": "object", + "description": "This is the transport of the call." }, - "updatedAt": { - "format": "date-time", + "assistantId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was last updated." + "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" }, - "status": { - "type": "string", - "description": "This is the status of the phone number.", - "enum": [ - "active", - "activating", - "blocked" + "assistant": { + "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } ] }, - "number": { - "type": "string", - "description": "These are the digits of the phone number you purchased from Vapi." + "assistantOverrides": { + "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } + ] }, - "name": { + "squadId": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 + "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "squad": { + "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] }, "workflowId": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "workflow": { + "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateWorkflowDTO" + } + ] }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "workflowOverrides": { + "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/WorkflowOverrides" } ] }, - "numberDesiredAreaCode": { + "phoneNumberId": { "type": "string", - "description": "This is the area code of the phone number to purchase.", - "minLength": 3, - "maxLength": 3 + "description": "This is the phone number that will be used for the call. To use a transient number, use `phoneNumber` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." }, - "sipUri": { + "phoneNumber": { + "description": "This is the phone number that will be used for the call. To use an existing number, use `phoneNumberId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", + "allOf": [ + { + "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" + } + ] + }, + "customerId": { "type": "string", - "description": "This is the SIP URI of the phone number. You can SIP INVITE this. The assistant attached to this number will answer.\n\nThis is case-insensitive." + "description": "This is the customer that will be called. To call a transient customer , use `customer` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type." }, - "authentication": { - "description": "This enables authentication for incoming SIP INVITE requests to the `sipUri`.\n\nIf not set, any username/password to the 401 challenge of the SIP INVITE will be accepted.", + "customer": { + "description": "This is the customer that will be called. To call an existing customer, use `customerId` instead.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", "allOf": [ { - "$ref": "#/components/schemas/SipAuthentication" + "$ref": "#/components/schemas/CreateCustomerDTO" } ] } - }, - "required": [ - "provider", - "id", - "orgId", - "createdAt", - "updatedAt" - ] + } }, - "TelnyxPhoneNumber": { + "CreateWebCallDTO": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, + "assistantId": { + "type": "string", + "description": "This is the assistant ID that will be used for the call. To use a transient assistant, use `assistant` instead.\n\nTo start a call with:\n- Assistant, use `assistantId` or `assistant`\n- Squad, use `squadId` or `squad`\n- Workflow, use `workflowId` or `workflow`" + }, + "assistant": { + "description": "This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.\n\nTo start a call with:\n- Assistant, use `assistant`\n- Squad, use `squad`\n- Workflow, use `workflow`", + "allOf": [ { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/CreateAssistantDTO" } ] }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "provider": { - "type": "string", - "description": "This is to use numbers bought on Telnyx.", - "enum": [ - "telnyx" + "assistantOverrides": { + "description": "These are the overrides for the `assistant` or `assistantId`'s settings and template variables.", + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } ] }, - "id": { - "type": "string", - "description": "This is the unique identifier for the phone number." - }, - "orgId": { + "squadId": { "type": "string", - "description": "This is the unique identifier for the org that this phone number belongs to." + "description": "This is the squad that will be used for the call. To use a transient squad, use `squad` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was created." + "squad": { + "description": "This is a squad that will be used for the call. To use an existing squad, use `squadId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] }, - "updatedAt": { - "format": "date-time", + "workflowId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the phone number was last updated." + "description": "This is the workflow that will be used for the call. To use a transient workflow, use `workflow` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`" }, - "status": { - "type": "string", - "description": "This is the status of the phone number.", - "enum": [ - "active", - "activating", - "blocked" + "workflow": { + "description": "This is a workflow that will be used for the call. To use an existing workflow, use `workflowId` instead.\n\nTo start a call with:\n- Assistant, use `assistant` or `assistantId`\n- Squad, use `squad` or `squadId`\n- Workflow, use `workflow` or `workflowId`", + "allOf": [ + { + "$ref": "#/components/schemas/CreateWorkflowDTO" + } ] }, + "workflowOverrides": { + "description": "These are the overrides for the `workflow` or `workflowId`'s settings and template variables.", + "allOf": [ + { + "$ref": "#/components/schemas/WorkflowOverrides" + } + ] + } + } + }, + "UpdateCallDTO": { + "type": "object", + "properties": { "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is the name of the call. This is just for your own reference.", "maxLength": 40 - }, - "assistantId": { + } + } + }, + "DeveloperMessage": { + "type": "object", + "properties": { + "role": { "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the role of the message author", + "default": "developer", + "enum": [ + "developer" + ] }, - "workflowId": { + "content": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the content of the developer message", + "maxLength": 10000 }, - "squadId": { + "name": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "description": "This is an optional name for the participant", + "maxLength": 40 }, - "number": { + "metadata": { + "type": "object", + "description": "This is an optional metadata for the message" + } + }, + "required": [ + "role", + "content" + ] + }, + "SystemMessage": { + "type": "object", + "properties": { + "role": { "type": "string", - "description": "These are the digits of the phone number you own on your Telnyx." + "description": "The role of the system in the conversation." }, - "credentialId": { + "message": { "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." + "description": "The message content from the system." + }, + "time": { + "type": "number", + "description": "The timestamp when the message was sent." + }, + "secondsFromStart": { + "type": "number", + "description": "The number of seconds from the start of the conversation." } }, "required": [ - "provider", - "id", - "orgId", - "createdAt", - "updatedAt", - "number", - "credentialId" + "role", + "message", + "time", + "secondsFromStart" ] }, - "CreateByoPhoneNumberDTO": { + "UserMessage": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } + "role": { + "type": "string", + "description": "The role of the user in the conversation." }, - "provider": { + "message": { "type": "string", - "description": "This is to bring your own phone numbers from your own SIP trunks or Carriers.", - "enum": [ - "byo-phone-number" - ] + "description": "The message content from the user." }, - "numberE164CheckEnabled": { + "time": { + "type": "number", + "description": "The timestamp when the message was sent." + }, + "endTime": { + "type": "number", + "description": "The timestamp when the message ended." + }, + "secondsFromStart": { + "type": "number", + "description": "The number of seconds from the start of the conversation." + }, + "duration": { + "type": "number", + "description": "The duration of the message in seconds." + }, + "isFiltered": { "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true + "description": "Indicates if the message was filtered for security reasons." }, - "number": { - "type": "string", - "description": "This is the number of the customer.", - "minLength": 3, - "maxLength": 40 + "detectedThreats": { + "description": "List of detected security threats if the message was filtered.", + "type": "array", + "items": { + "type": "string" + } }, - "credentialId": { + "originalMessage": { "type": "string", - "description": "This is the credential of your own SIP trunk or Carrier (type `byo-sip-trunk`) which can be used to make calls to this phone number.\n\nYou can add the SIP trunk or Carrier credential in the Provider Credentials page on the Dashboard to get the credentialId." + "description": "The original message before filtering (only included if content was filtered)." + } + }, + "required": [ + "role", + "message", + "time", + "endTime", + "secondsFromStart" + ] + }, + "ToolCallFunction": { + "type": "object", + "properties": { + "arguments": { + "type": "string", + "description": "This is the arguments to call the function with" }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is the name of the function to call", "maxLength": 40 - }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { + } + }, + "required": [ + "arguments", + "name" + ] + }, + "ToolCall": { + "type": "object", + "properties": { + "id": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the ID of the tool call" }, - "squadId": { + "type": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the type of tool" }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "function": { + "description": "This is the function that was called", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/ToolCallFunction" } ] } }, "required": [ - "provider", - "credentialId" + "id", + "type", + "function" ] }, - "CreateTwilioPhoneNumberDTO": { + "AssistantMessage": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "provider": { + "role": { "type": "string", - "description": "This is to use numbers bought on Twilio.", + "description": "This is the role of the message author", + "default": "assistant", "enum": [ - "twilio" + "assistant" ] }, - "smsEnabled": { - "type": "boolean", - "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", - "default": true - }, - "number": { - "type": "string", - "description": "These are the digits of the phone number you own on your Twilio." - }, - "twilioAccountSid": { - "type": "string", - "description": "This is the Twilio Account SID for the phone number." - }, - "twilioAuthToken": { + "content": { "type": "string", - "description": "This is the Twilio Auth Token for the phone number." + "description": "This is the content of the assistant message", + "maxLength": 10000 }, - "twilioApiKey": { + "refusal": { "type": "string", - "description": "This is the Twilio API Key for the phone number." + "description": "This is the refusal message generated by the model", + "maxLength": 10000 }, - "twilioApiSecret": { - "type": "string", - "description": "This is the Twilio API Secret for the phone number." + "tool_calls": { + "description": "This is the tool calls generated by the model", + "type": "array", + "items": { + "$ref": "#/components/schemas/ToolCall" + } }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is an optional name for the participant", "maxLength": 40 }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "metadata": { + "type": "object", + "description": "This is an optional metadata for the message" } }, "required": [ - "provider", - "number", - "twilioAccountSid" + "role" ] }, - "CreateVonagePhoneNumberDTO": { + "ToolMessage": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "provider": { + "role": { "type": "string", - "description": "This is to use numbers bought on Vonage.", + "description": "This is the role of the message author", + "default": "tool", "enum": [ - "vonage" + "tool" ] }, - "number": { + "content": { "type": "string", - "description": "These are the digits of the phone number you own on your Vonage." + "description": "This is the content of the tool message", + "maxLength": 10000 }, - "credentialId": { + "tool_call_id": { "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." + "description": "This is the ID of the tool call this message is responding to" }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is an optional name for the participant", "maxLength": 40 }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { + "metadata": { + "type": "object", + "description": "This is an optional metadata for the message" + } + }, + "required": [ + "role", + "content", + "tool_call_id" + ] + }, + "FunctionCall": { + "type": "object", + "properties": { + "arguments": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the arguments to call the function with" }, - "squadId": { + "name": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "description": "This is the name of the function to call", + "maxLength": 40 } }, "required": [ - "provider", - "number", - "credentialId" + "arguments", + "name" ] }, - "CreateVapiPhoneNumberDTO": { + "Chat": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead." + }, + "assistant": { + "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead.", + "allOf": [ { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/CreateAssistantDTO" } ] }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "provider": { - "type": "string", - "description": "This is to create free SIP phone numbers on Vapi.", - "enum": [ - "vapi" - ] - }, - "numberDesiredAreaCode": { - "type": "string", - "description": "This is the area code of the phone number to purchase.", - "minLength": 3, - "maxLength": 3 - }, - "sipUri": { - "type": "string", - "description": "This is the SIP URI of the phone number. You can SIP INVITE this. The assistant attached to this number will answer.\n\nThis is case-insensitive." - }, - "authentication": { - "description": "This enables authentication for incoming SIP INVITE requests to the `sipUri`.\n\nIf not set, any username/password to the 401 challenge of the SIP INVITE will be accepted.", + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in chat contexts - other assistant properties cannot be overridden.", "allOf": [ { - "$ref": "#/components/schemas/SipAuthentication" + "$ref": "#/components/schemas/AssistantOverrides" } ] }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is the name of the chat. This is just for your own reference.", "maxLength": 40 }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "squadId": { + "sessionId": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - } - }, - "required": [ - "provider" - ] - }, - "CreateTelnyxPhoneNumberDTO": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "input": { + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", "oneOf": [ { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" + "type": "string", + "title": "String" }, { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] + }, + "title": "MessageArray" } + ], + "examples": [ + "Hello, how can you help me?", + [ + { + "role": "user", + "content": "Hello, how can you help me?" + } + ] ] }, - "hooks": { + "stream": { + "type": "boolean", + "description": "This is a flag that determines whether the response should be streamed.\nWhen true, the response will be sent as chunks of text.", + "default": false + }, + "previousChatId": { + "type": "string", + "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the chat." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the org that this chat belongs to." + }, + "messages": { "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", + "description": "This is an array of messages used as context for the chat.\nUsed to provide message history for multi-turn conversations.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" }, { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" } ] } }, - "provider": { - "type": "string", - "description": "This is to use numbers bought on Telnyx.", - "enum": [ - "telnyx" - ] - }, - "number": { - "type": "string", - "description": "These are the digits of the phone number you own on your Telnyx." - }, - "credentialId": { - "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." - }, - "name": { - "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 - }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "output": { + "type": "array", + "description": "This is the output messages generated by the system in response to the input.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] + } }, - "workflowId": { + "createdAt": { + "format": "date-time", "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the ISO 8601 date-time string of when the chat was created." }, - "squadId": { + "updatedAt": { + "format": "date-time", "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] - } - }, - "required": [ - "provider", - "number", - "credentialId" - ] - }, - "UpdateByoPhoneNumberDTO": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] + "description": "This is the ISO 8601 date-time string of when the chat was last updated." }, - "hooks": { + "costs": { "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", + "description": "These are the costs of individual components of the chat in USD.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" + "$ref": "#/components/schemas/ModelCost", + "title": "ModelCost" }, { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" + "$ref": "#/components/schemas/ChatCost", + "title": "ChatCost" } ] } }, - "numberE164CheckEnabled": { - "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true - }, - "name": { - "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 - }, + "cost": { + "type": "number", + "description": "This is the cost of the chat in USD." + } + }, + "required": [ + "id", + "orgId", + "createdAt", + "updatedAt" + ] + }, + "CreateChatDTO": { + "type": "object", + "properties": { "assistantId": { "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead." }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "assistant": { + "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } + ] }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in chat contexts - other assistant properties cannot be overridden.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/AssistantOverrides" } ] }, - "number": { + "name": { "type": "string", - "description": "This is the number of the customer.", - "minLength": 3, + "description": "This is the name of the chat. This is just for your own reference.", "maxLength": 40 }, - "credentialId": { + "sessionId": { "type": "string", - "description": "This is the credential of your own SIP trunk or Carrier (type `byo-sip-trunk`) which can be used to make calls to this phone number.\n\nYou can add the SIP trunk or Carrier credential in the Provider Credentials page on the Dashboard to get the credentialId." - } - } - }, - "UpdateTwilioPhoneNumberDTO": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." + }, + "input": { + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.\nThis field is REQUIRED for chat creation.", "oneOf": [ { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" + "type": "string", + "title": "String" }, { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] }, + "title": "MessageArray" + } + ], + "examples": [ + "Hello, how can you help me?", + [ { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" + "role": "user", + "content": "Hello, how can you help me?" } ] - } + ] }, - "smsEnabled": { + "stream": { "type": "boolean", - "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", - "default": true + "description": "This is a flag that determines whether the response should be streamed.\nWhen true, the response will be sent as chunks of text.", + "default": false }, - "name": { + "previousChatId": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 - }, + "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." + } + }, + "required": [ + "input" + ] + }, + "GetChatPaginatedDTO": { + "type": "object", + "properties": { "assistantId": { "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the unique identifier for the assistant that will be used for the chat." }, "workflowId": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the unique identifier for the workflow that will be used for the chat." }, - "squadId": { + "sessionId": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "description": "This is the unique identifier for the session that will be used for the chat." }, - "number": { - "type": "string", - "description": "These are the digits of the phone number you own on your Twilio." + "page": { + "type": "number", + "description": "This is the page number to return. Defaults to 1.", + "minimum": 1 }, - "twilioAccountSid": { + "sortOrder": { "type": "string", - "description": "This is the Twilio Account SID for the phone number." + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "enum": [ + "ASC", + "DESC" + ] }, - "twilioAuthToken": { - "type": "string", - "description": "This is the Twilio Auth Token for the phone number." + "limit": { + "type": "number", + "description": "This is the maximum number of items to return. Defaults to 100.", + "minimum": 0, + "maximum": 1000 }, - "twilioApiKey": { + "createdAtGt": { + "format": "date-time", "type": "string", - "description": "This is the Twilio API Key for the phone number." + "description": "This will return items where the createdAt is greater than the specified value." }, - "twilioApiSecret": { + "createdAtLt": { + "format": "date-time", "type": "string", - "description": "This is the Twilio API Secret for the phone number." - } - } - }, - "UpdateVonagePhoneNumberDTO": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } + "description": "This will return items where the createdAt is less than the specified value." }, - "name": { + "createdAtGe": { + "format": "date-time", "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 + "description": "This will return items where the createdAt is greater than or equal to the specified value." }, - "assistantId": { + "createdAtLe": { + "format": "date-time", "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This will return items where the createdAt is less than or equal to the specified value." }, - "workflowId": { + "updatedAtGt": { + "format": "date-time", "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This will return items where the updatedAt is greater than the specified value." }, - "squadId": { + "updatedAtLt": { + "format": "date-time", "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "description": "This will return items where the updatedAt is less than the specified value." }, - "number": { + "updatedAtGe": { + "format": "date-time", "type": "string", - "description": "These are the digits of the phone number you own on your Vonage." + "description": "This will return items where the updatedAt is greater than or equal to the specified value." }, - "credentialId": { + "updatedAtLe": { + "format": "date-time", "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." + "description": "This will return items where the updatedAt is less than or equal to the specified value." } } }, - "UpdateVapiPhoneNumberDTO": { + "ChatPaginatedResponse": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" - } - ] - }, - "hooks": { + "results": { "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] + "$ref": "#/components/schemas/Chat" } }, - "name": { + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" + } + }, + "required": [ + "results", + "metadata" + ] + }, + "CreateChatStreamResponse": { + "type": "object", + "properties": { + "id": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", - "maxLength": 40 + "description": "This is the unique identifier for the streaming response." }, - "assistantId": { + "sessionId": { "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the ID of the session that will be used for the chat.\nHelps track conversation context across multiple messages." }, - "workflowId": { + "path": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the path to the content being updated.\nFormat: `chat.output[{contentIndex}].content` where contentIndex identifies the specific content item.", + "example": "chat.output[0].content" }, - "squadId": { + "delta": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the incremental content chunk being streamed." + } + }, + "required": [ + "id", + "path", + "delta" + ] + }, + "OpenAIResponsesRequest": { + "type": "object", + "properties": { + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead." }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "assistant": { + "description": "This is the assistant that will be used for the chat. To use an existing assistant, use `assistantId` instead.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/CreateAssistantDTO" } ] }, - "sipUri": { - "type": "string", - "description": "This is the SIP URI of the phone number. You can SIP INVITE this. The assistant attached to this number will answer.\n\nThis is case-insensitive." - }, - "authentication": { - "description": "This enables authentication for incoming SIP INVITE requests to the `sipUri`.\n\nIf not set, any username/password to the 401 challenge of the SIP INVITE will be accepted.", + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in chat contexts - other assistant properties cannot be overridden.", "allOf": [ { - "$ref": "#/components/schemas/SipAuthentication" - } - ] - } - } - }, - "UpdateTelnyxPhoneNumberDTO": { - "type": "object", - "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/AssistantOverrides" } ] }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is the name of the chat. This is just for your own reference.", "maxLength": 40 }, - "assistantId": { - "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "workflowId": { - "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." - }, - "squadId": { + "sessionId": { "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", - "allOf": [ + "input": { + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.\nThis field is REQUIRED for chat creation.", + "oneOf": [ { - "$ref": "#/components/schemas/Server" + "type": "string", + "title": "String" + }, + { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] + }, + "title": "MessageArray" } + ], + "examples": [ + "Hello, how can you help me?", + [ + { + "role": "user", + "content": "Hello, how can you help me?" + } + ] ] }, - "number": { - "type": "string", - "description": "These are the digits of the phone number you own on your Telnyx." + "stream": { + "type": "boolean", + "description": "Whether to stream the response or not.", + "default": true }, - "credentialId": { + "previousChatId": { "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." + "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." + } + }, + "required": [ + "input" + ] + }, + "ChatAssistantOverrides": { + "type": "object", + "properties": { + "variableValues": { + "type": "object", + "description": "Variable values for template substitution", + "example": { + "name": "John", + "company": "ACME Corp" + } } } }, - "ImportVonagePhoneNumberDTO": { + "CreateWebCustomerDTO": { "type": "object", "properties": { - "fallbackDestination": { - "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "NumberTransferDestination" - }, + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true + }, + "extension": { + "type": "string", + "description": "This is the extension that will be dialed after the call is answered.", + "maxLength": 10, + "example": null + }, + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", + "allOf": [ { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "SipTransferDestination" + "$ref": "#/components/schemas/ChatAssistantOverrides" } ] }, - "hooks": { - "type": "array", - "description": "This is the hooks that will be used for incoming calls to this phone number.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/PhoneNumberHookCallRinging", - "title": "PhoneNumberHookCallRinging" - }, - { - "$ref": "#/components/schemas/PhoneNumberHookCallEnding", - "title": "PhoneNumberHookCallEnding" - } - ] - } - }, - "vonagePhoneNumber": { + "number": { "type": "string", - "description": "These are the digits of the phone number you own on your Vonage.", - "deprecated": true + "description": "This is the number of the customer.", + "minLength": 3, + "maxLength": 40 }, - "credentialId": { + "sipUri": { "type": "string", - "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." + "description": "This is the SIP URI of the customer." }, "name": { "type": "string", - "description": "This is the name of the phone number. This is just for your own reference.", + "description": "This is the name of the customer. This is just for your own reference.\n\nFor SIP inbound calls, this is extracted from the `From` SIP header with format `\"Display Name\" `.", + "maxLength": 40 + }, + "email": { + "type": "string", + "description": "This is the email of the customer.", "maxLength": 40 }, + "externalId": { + "type": "string", + "description": "This is the external ID of the customer.", + "maxLength": 40 + } + } + }, + "CreateWebChatDTO": { + "type": "object", + "properties": { "assistantId": { "type": "string", - "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "The assistant ID to use for this chat" }, - "workflowId": { + "sessionId": { "type": "string", - "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "description": "This is the ID of the session that will be used for the chat.\nIf provided, the conversation will continue from the previous state.\nIf not provided or expired, a new session will be created." }, - "squadId": { - "type": "string", - "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", + "allOf": [ + { + "$ref": "#/components/schemas/ChatAssistantOverrides" + } + ] }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", + "customer": { + "description": "This is the customer information for the chat.\nUsed to automatically manage sessions for repeat customers.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/CreateWebCustomerDTO" + } + ] + }, + "input": { + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", + "oneOf": [ + { + "type": "string", + "title": "String" + }, + { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] + }, + "title": "MessageArray" } + ], + "examples": [ + "Hello, how can you help me?", + [ + { + "role": "user", + "content": "Hello, how can you help me?" + } + ] ] + }, + "stream": { + "type": "boolean", + "description": "This is a flag that determines whether the response should be streamed.\nWhen true, the response will be sent as chunks of text.", + "default": false } }, "required": [ - "vonagePhoneNumber", - "credentialId" + "assistantId", + "input" ] }, - "PhoneNumberPaginatedResponse": { + "WebChat": { "type": "object", "properties": { - "results": { + "id": { + "type": "string", + "description": "This is the unique identifier for the chat." + }, + "sessionId": { + "type": "string", + "description": "This is the ID of the session for the chat. Send it in the next chat request to continue the conversation." + }, + "output": { "type": "array", - "description": "A list of phone numbers, which can be of any provider type.", + "description": "This is the output messages generated by the system in response to the input.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ByoPhoneNumber" + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" }, { - "$ref": "#/components/schemas/TwilioPhoneNumber" + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" }, { - "$ref": "#/components/schemas/VonagePhoneNumber" + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" }, { - "$ref": "#/components/schemas/VapiPhoneNumber" + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" }, { - "$ref": "#/components/schemas/TelnyxPhoneNumber" + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" } ] } - }, - "metadata": { - "description": "Metadata about the pagination.", - "allOf": [ - { - "$ref": "#/components/schemas/PaginationMeta" - } - ] } }, "required": [ - "results", - "metadata" + "id", + "output" ] }, - "ApiRequestTool": { + "OpenAIWebChatRequest": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "apiRequest" - ], - "description": "The type of tool. \"apiRequest\" for API request tool." - }, - "method": { - "type": "string", - "enum": [ - "POST", - "GET", - "PUT", - "PATCH", - "DELETE" - ] - }, - "timeoutSeconds": { - "type": "number", - "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20", - "minimum": 1, - "maximum": 300, - "example": 20 - }, - "id": { - "type": "string", - "description": "This is the unique identifier for the tool." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." - }, - "createdAt": { - "format": "date-time", + "assistantId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "The assistant ID to use for this chat" }, - "updatedAt": { - "format": "date-time", + "sessionId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ID of the session that will be used for the chat.\nIf provided, the conversation will continue from the previous state.\nIf not provided or expired, a new session will be created." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/ChatAssistantOverrides" } ] }, - "name": { - "type": "string", - "description": "This is the name of the tool. This will be passed to the model.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 40.", - "maxLength": 40, - "pattern": "/^[a-zA-Z0-9_-]{1,40}$/" - }, - "description": { - "type": "string", - "description": "This is the description of the tool. This will be passed to the model.", - "maxLength": 1000 - }, - "url": { - "type": "string", - "description": "This is where the request will be sent." - }, - "body": { - "description": "This is the body of the request.", + "customer": { + "description": "This is the customer information for the chat.\nUsed to automatically manage sessions for repeat customers.", "allOf": [ { - "$ref": "#/components/schemas/JsonSchema" + "$ref": "#/components/schemas/CreateWebCustomerDTO" } ] }, - "headers": { - "description": "These are the headers to send with the request.", - "allOf": [ + "input": { + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", + "oneOf": [ { - "$ref": "#/components/schemas/JsonSchema" - } - ] - }, - "backoffPlan": { - "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)", - "allOf": [ + "type": "string", + "title": "String" + }, { - "$ref": "#/components/schemas/BackoffPlan" + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] + }, + "title": "MessageArray" } + ], + "examples": [ + "Hello, how can you help me?", + [ + { + "role": "user", + "content": "Hello, how can you help me?" + } + ] ] }, - "variableExtractionPlan": { - "description": "This is the plan to extract variables from the tool's response. These will be accessible during the call and stored in `call.artifact.variableValues` after the call.\n\nUsage:\n1. Use `aliases` to extract variables from the tool's response body. (Most common case)\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{customer.name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{customer.age}}\"\n }\n ]\n}\n```\n\nThe tool response body is made available to the liquid template.\n\n2. Use `aliases` to extract variables from the tool's response body if the response is an array.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{$[0].name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{$[0].age}}\"\n }\n ]\n}\n```\n\n$ is a shorthand for the tool's response body. `$[0]` is the first item in the array. `$[n]` is the nth item in the array. Note, $ is available regardless of the response body type (both object and array).\n\n3. Use `aliases` to extract variables from the tool's response headers.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{tool.response.headers.customer-name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{tool.response.headers.customer-age}}\"\n }\n ]\n}\n```\n\n`tool.response` is made available to the liquid template. Particularly, both `tool.response.headers` and `tool.response.body` are available. Note, `tool.response` is available regardless of the response body type (both object and array).\n\n4. Use `schema` to extract a large portion of the tool's response body.\n\n4.1. If you hit example.com and it returns `{\"name\": \"John\", \"age\": 30}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n }\n }\n }\n}\n```\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n4.2. If you hit example.com and it returns `{\"name\": {\"first\": \"John\", \"last\": \"Doe\"}}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"object\",\n \"properties\": {\n \"first\": {\n \"type\": \"string\"\n },\n \"last\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n4.3. If you hit example.com and it returns `[\"94123\", \"94124\"]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"zipCodes\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4.4. If you hit example.com and it returns `[{\"name\": \"John\", \"age\": 30, \"zipCodes\": [\"94123\", \"94124\"]}, {\"name\": \"Jane\", \"age\": 25, \"zipCodes\": [\"94125\", \"94126\"]}]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"people\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n },\n \"zipCodes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.\n\nNote: Both `aliases` and `schema` can be used together.", - "allOf": [ - { - "$ref": "#/components/schemas/VariableExtractionPlan" - } - ] + "stream": { + "type": "boolean", + "description": "Whether to stream the response or not.", + "default": true } }, "required": [ - "type", - "method", - "id", - "orgId", - "createdAt", - "updatedAt", - "url" + "assistantId", + "input" ] }, - "DtmfTool": { + "ResponseOutputText": { "type": "object", "properties": { - "messages": { + "annotations": { + "default": [], + "description": "Annotations in the text output", "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] + "type": "object" } }, + "text": { + "type": "string", + "description": "The text output from the model" + }, "type": { "type": "string", + "default": "output_text", + "description": "The type of the output text", "enum": [ - "dtmf" - ], - "description": "The type of tool. \"dtmf\" for DTMF tool." - }, + "output_text" + ] + } + }, + "required": [ + "annotations", + "text", + "type" + ] + }, + "ResponseOutputMessage": { + "type": "object", + "properties": { "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "The unique ID of the output message" }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "content": { + "description": "Content of the output message", + "type": "array", + "items": { + "$ref": "#/components/schemas/ResponseOutputText" + } }, - "createdAt": { - "format": "date-time", + "role": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "default": "assistant", + "description": "The role of the output message", + "enum": [ + "assistant" + ] }, - "updatedAt": { - "format": "date-time", + "status": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "The status of the message", + "enum": [ + "in_progress", + "completed", + "incomplete" + ] }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } + "type": { + "type": "string", + "default": "message", + "description": "The type of the output message", + "enum": [ + "message" ] } }, "required": [ - "type", "id", - "orgId", - "createdAt", - "updatedAt" + "content", + "role", + "status", + "type" ] }, - "EndCallTool": { + "ResponseObject": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "endCall" - ], - "description": "The type of tool. \"endCall\" for End Call tool." - }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "Unique identifier for this Response" }, - "orgId": { + "object": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "default": "response", + "description": "The object type", + "enum": [ + "response" + ] }, - "createdAt": { - "format": "date-time", + "created_at": { + "type": "number", + "description": "Unix timestamp (in seconds) of when this Response was created" + }, + "status": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "Status of the response", + "enum": [ + "completed", + "failed", + "in_progress", + "incomplete" + ] }, - "updatedAt": { - "format": "date-time", + "error": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "nullable": true, + "default": null, + "description": "Error message if the response failed" }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "output": { + "description": "Output messages from the model", + "type": "array", + "items": { + "$ref": "#/components/schemas/ResponseOutputMessage" + } } }, "required": [ - "type", "id", - "orgId", - "createdAt", - "updatedAt" + "object", + "created_at", + "status", + "output" ] }, - "FunctionTool": { + "ResponseTextDeltaEvent": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } + "content_index": { + "type": "number", + "description": "Index of the content part" + }, + "delta": { + "type": "string", + "description": "Text delta being added" }, - "type": { + "item_id": { "type": "string", - "enum": [ - "function" - ], - "description": "The type of tool. \"function\" for Function tool." + "description": "ID of the output item" }, - "async": { - "type": "boolean", - "example": false, - "description": "This determines if the tool is async.\n\n If async, the assistant will move forward without waiting for your server to respond. This is useful if you just want to trigger something on your server.\n\n If sync, the assistant will wait for your server to respond. This is useful if want assistant to respond with the result from your server.\n\n Defaults to synchronous (`false`)." + "output_index": { + "type": "number", + "description": "Index of the output item" }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } + "type": { + "type": "string", + "default": "response.output_text.delta", + "description": "Event type", + "enum": [ + "response.output_text.delta" ] + } + }, + "required": [ + "content_index", + "delta", + "item_id", + "output_index", + "type" + ] + }, + "ResponseTextDoneEvent": { + "type": "object", + "properties": { + "content_index": { + "type": "number", + "description": "Index of the content part" }, - "id": { + "item_id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "ID of the output item" }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "output_index": { + "type": "number", + "description": "Index of the output item" }, - "createdAt": { - "format": "date-time", + "text": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "Complete text content" }, - "updatedAt": { - "format": "date-time", + "type": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "default": "response.output_text.done", + "description": "Event type", + "enum": [ + "response.output_text.done" + ] + } + }, + "required": [ + "content_index", + "item_id", + "output_index", + "text", + "type" + ] + }, + "ResponseCompletedEvent": { + "type": "object", + "properties": { + "response": { + "description": "The completed response", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/ResponseObject" } ] }, - "function": { - "description": "This is the function definition of the tool.", - "allOf": [ - { - "$ref": "#/components/schemas/OpenAIFunction" - } + "type": { + "type": "string", + "default": "response.completed", + "description": "Event type", + "enum": [ + "response.completed" ] } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" + "response", + "type" ] }, - "GhlTool": { + "ResponseErrorEvent": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, "type": { "type": "string", + "default": "error", + "description": "Event type", "enum": [ - "ghl" - ], - "description": "The type of tool. \"ghl\" for GHL tool." - }, - "id": { - "type": "string", - "description": "This is the unique identifier for the tool." + "error" + ] }, - "orgId": { + "code": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "Error code", + "example": "ERR_SOMETHING" }, - "createdAt": { - "format": "date-time", + "message": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "Error message", + "example": "Something went wrong" }, - "updatedAt": { - "format": "date-time", + "param": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "nullable": true, + "description": "Parameter that caused the error" }, - "metadata": { - "$ref": "#/components/schemas/GhlToolMetadata" + "sequence_number": { + "type": "number", + "description": "Sequence number of the event", + "example": 1 } }, "required": [ "type", - "id", - "orgId", - "createdAt", - "updatedAt", - "metadata" + "code", + "message", + "sequence_number" ] }, - "MakeTool": { + "CreateCampaignDTO": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "enum": [ - "make" - ], - "description": "The type of tool. \"make\" for Make tool." - }, - "id": { + "name": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the name of the campaign. This is just for your own reference.", + "example": "Q2 Sales Campaign" }, - "orgId": { + "assistantId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the assistant ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." }, - "createdAt": { - "format": "date-time", + "workflowId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the workflow ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." }, - "updatedAt": { - "format": "date-time", + "phoneNumberId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the phone number ID that will be used for the campaign calls." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "schedulePlan": { + "description": "This is the schedule plan for the campaign.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/SchedulePlan" } ] }, - "metadata": { - "$ref": "#/components/schemas/MakeToolMetadata" + "customers": { + "description": "These are the customers that will be called in the campaign.", + "type": "array", + "items": { + "$ref": "#/components/schemas/CreateCustomerDTO" + } } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt", - "metadata" + "name", + "phoneNumberId", + "customers" ] }, - "TransferCallTool": { + "Campaign": { "type": "object", "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { + "status": { "type": "string", + "description": "This is the status of the campaign.", "enum": [ - "transferCall" + "scheduled", + "in-progress", + "ended" ] }, - "destinations": { - "type": "array", - "description": "These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TransferDestinationAssistant", - "title": "Assistant" - }, - { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "Number" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "Sip" - } - ] - } + "endedReason": { + "type": "string", + "description": "This is the explanation for how the campaign ended.", + "enum": [ + "campaign.scheduled.ended-by-user", + "campaign.in-progress.ended-by-user", + "campaign.ended.success" + ] }, - "id": { + "name": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the name of the campaign. This is just for your own reference.", + "example": "Q2 Sales Campaign" }, - "orgId": { + "assistantId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the assistant ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." }, - "createdAt": { - "format": "date-time", + "workflowId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the workflow ID that will be used for the campaign calls. Note: Either assistantId or workflowId can be used, but not both." }, - "updatedAt": { - "format": "date-time", + "phoneNumberId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the phone number ID that will be used for the campaign calls." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "schedulePlan": { + "description": "This is the schedule plan for the campaign.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/SchedulePlan" } ] - } - }, - "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" - ] - }, - "HandoffTool": { - "type": "object", - "properties": { - "messages": { - "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] - } - }, - "type": { - "type": "string", - "description": "This is the type of the tool.\nWhen you're using handoff tool, we recommend adding this to your system prompt\n---\n# System context\n\nYou are part of a multi-agent system designed to make agent coordination and execution easy. Agents uses two primary abstraction: **Agents** and **Handoffs**. An agent encompasses instructions and tools and can hand off a conversation to another agent when appropriate. Handoffs are achieved by calling a handoff function, generally named `handoff_to_`. Handoffs between agents are handled seamlessly in the background; do not mention or draw attention to these handoffs in your conversation with the user.\n\n# Agent context\n\n{put your agent system prompt here}\n---", - "enum": [ - "handoff" - ] }, - "destinations": { + "customers": { + "description": "These are the customers that will be called in the campaign.", "type": "array", - "description": "These are the destinations that the call can be handed off to.\n\nUsage:\n1. Single destination\n\nUse `assistantId` to handoff the call to a saved assistant, or `assistantName` to handoff the call to an assistant in the same squad.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\", // or \"assistantName\": \"Assistant123\"\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2. Multiple destinations\n\n2.1. Multiple Tools, Each With One Destination (OpenAI recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n ],\n },\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2.2. One Tool, Multiple Destinations (Anthropic recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3. Dynamic destination\n\n3.1 To determine the destination dynamically, supply a `dynamic` handoff destination type and a `server` object.\n VAPI will send a handoff-destination-request webhook to the `server.url`.\n The response from the server will be used as the destination (if valid).\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3.2. To pass custom parameters to the server, you can use the `function` object.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n },\n }\n ],\n \"function\": {\n \"name\": \"handoff\",\n \"description\": \"Call this function when the customer is ready to be handed off to the next assistant\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"destination\": {\n \"type\": \"string\",\n \"description\": \"Use dynamic when customer is ready to be handed off to the next assistant\",\n \"enum\": [\"dynamic\"]\n },\n \"customerAreaCode\": {\n \"type\": \"number\",\n \"description\": \"Area code of the customer\"\n },\n \"customerIntent\": {\n \"type\": \"string\",\n \"enum\": [\"new-customer\", \"existing-customer\"],\n \"description\": \"Use new-customer when customer is a new customer, existing-customer when customer is an existing customer\"\n },\n \"customerSentiment\": {\n \"type\": \"string\",\n \"enum\": [\"positive\", \"negative\", \"neutral\"],\n \"description\": \"Use positive when customer is happy, negative when customer is unhappy, neutral when customer is neutral\"\n }\n }\n }\n }\n }\n ]\n}\n```\n\nThe properties `customerAreaCode`, `customerIntent`, and `customerSentiment` will be passed to the server in the webhook request body.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/HandoffDestinationAssistant", - "title": "Assistant" - }, - { - "$ref": "#/components/schemas/HandoffDestinationDynamic", - "title": "Dynamic" - } - ] + "$ref": "#/components/schemas/CreateCustomerDTO" } }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the campaign." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the unique identifier for the org that this campaign belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the ISO 8601 date-time string of when the campaign was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ISO 8601 date-time string of when the campaign was last updated." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "calls": { + "type": "object", + "description": "This is a map of call IDs to campaign call details." + }, + "callsCounterScheduled": { + "type": "number", + "description": "This is the number of calls that have been scheduled." + }, + "callsCounterQueued": { + "type": "number", + "description": "This is the number of calls that have been queued." + }, + "callsCounterInProgress": { + "type": "number", + "description": "This is the number of calls that have been in progress." + }, + "callsCounterEndedVoicemail": { + "type": "number", + "description": "This is the number of calls whose ended reason is 'voicemail'." + }, + "callsCounterEnded": { + "type": "number", + "description": "This is the number of calls that have ended." } }, "required": [ - "type", + "status", + "name", + "phoneNumberId", + "customers", "id", "orgId", "createdAt", - "updatedAt" + "updatedAt", + "calls", + "callsCounterScheduled", + "callsCounterQueued", + "callsCounterInProgress", + "callsCounterEndedVoicemail", + "callsCounterEnded" ] }, - "OutputTool": { + "CampaignPaginatedResponse": { "type": "object", "properties": { - "messages": { + "results": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" - }, - { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" - } - ] + "$ref": "#/components/schemas/Campaign" } }, - "type": { + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" + } + }, + "required": [ + "results", + "metadata" + ] + }, + "UpdateCampaignDTO": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This is the name of the campaign. This is just for your own reference." + }, + "assistantId": { + "type": "string", + "description": "This is the assistant ID that will be used for the campaign calls.\nCan only be updated if campaign is not in progress or has ended." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow ID that will be used for the campaign calls.\nCan only be updated if campaign is not in progress or has ended." + }, + "phoneNumberId": { + "type": "string", + "description": "This is the phone number ID that will be used for the campaign calls.\nCan only be updated if campaign is not in progress or has ended." + }, + "schedulePlan": { + "description": "This is the schedule plan for the campaign.\nCan only be updated if campaign is not in progress or has ended.", + "allOf": [ + { + "$ref": "#/components/schemas/SchedulePlan" + } + ] + }, + "status": { "type": "string", + "description": "This is the status of the campaign.\nCan only be updated to 'ended' if you want to end the campaign.\nWhen set to 'ended', it will delete all scheduled calls. Calls in progress will be allowed to complete.", "enum": [ - "output" - ], - "description": "The type of tool. \"output\" for Output tool." - }, + "ended" + ] + } + } + }, + "Session": { + "type": "object", + "properties": { "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the session." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the unique identifier for the organization that owns this session." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the ISO 8601 timestamp indicating when the session was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ISO 8601 timestamp indicating when the session was last updated." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "name": { + "type": "string", + "description": "This is a user-defined name for the session. Maximum length is 40 characters.", + "maxLength": 40 + }, + "status": { + "type": "string", + "description": "This is the current status of the session. Can be either 'active' or 'completed'.", + "enum": [ + "active", + "completed" + ] + }, + "expirationSeconds": { + "type": "number", + "description": "Session expiration time in seconds. Defaults to 24 hours (86400 seconds) if not set.", + "minimum": 60, + "maximum": 2592000, + "example": 86400 + }, + "assistantId": { + "type": "string", + "description": "This is the ID of the assistant associated with this session. Use this when referencing an existing assistant." + }, + "assistant": { + "description": "This is the assistant configuration for this session. Use this when creating a new assistant configuration.\nIf assistantId is provided, this will be ignored.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/CreateAssistantDTO" } ] - } - }, - "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" - ] - }, - "BashTool": { - "type": "object", - "properties": { + }, "messages": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is an array of chat messages in the session.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" }, { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" }, { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" } ] } }, - "type": { - "type": "string", - "enum": [ - "bash" - ], - "description": "The type of tool. \"bash\" for Bash tool." - }, - "subType": { - "type": "string", - "enum": [ - "bash_20241022" - ], - "description": "The sub type of tool." - }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "customer": { + "description": "This is the customer information associated with this session.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/CreateCustomerDTO" } ] }, - "id": { - "type": "string", - "description": "This is the unique identifier for the tool." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." - }, - "updatedAt": { - "format": "date-time", + "phoneNumberId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ID of the phone number associated with this session." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "phoneNumber": { + "description": "This is the phone number configuration for this session.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" } ] - }, - "name": { - "type": "string", - "description": "The name of the tool, fixed to 'bash'", - "default": "bash", - "enum": [ - "bash" - ] } }, "required": [ - "type", - "subType", "id", "orgId", "createdAt", - "updatedAt", - "name" + "updatedAt" ] }, - "ComputerTool": { + "CreateSessionDTO": { "type": "object", "properties": { + "name": { + "type": "string", + "description": "This is a user-defined name for the session. Maximum length is 40 characters.", + "maxLength": 40 + }, + "status": { + "type": "string", + "description": "This is the current status of the session. Can be either 'active' or 'completed'.", + "enum": [ + "active", + "completed" + ] + }, + "expirationSeconds": { + "type": "number", + "description": "Session expiration time in seconds. Defaults to 24 hours (86400 seconds) if not set.", + "minimum": 60, + "maximum": 2592000, + "example": 86400 + }, + "assistantId": { + "type": "string", + "description": "This is the ID of the assistant associated with this session. Use this when referencing an existing assistant." + }, + "assistant": { + "description": "This is the assistant configuration for this session. Use this when creating a new assistant configuration.\nIf assistantId is provided, this will be ignored.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } + ] + }, "messages": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is an array of chat messages in the session.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" }, { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" }, { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" } ] } }, - "type": { - "type": "string", - "enum": [ - "computer" - ], - "description": "The type of tool. \"computer\" for Computer tool." - }, - "subType": { - "type": "string", - "enum": [ - "computer_20241022" - ], - "description": "The sub type of tool." - }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "customer": { + "description": "This is the customer information associated with this session.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/CreateCustomerDTO" } ] }, - "id": { - "type": "string", - "description": "This is the unique identifier for the tool." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." - }, - "updatedAt": { - "format": "date-time", + "phoneNumberId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ID of the phone number associated with this session." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "phoneNumber": { + "description": "This is the phone number configuration for this session.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/ImportTwilioPhoneNumberDTO" } ] - }, + } + } + }, + "UpdateSessionDTO": { + "type": "object", + "properties": { "name": { "type": "string", - "description": "The name of the tool, fixed to 'computer'", - "default": "computer", + "description": "This is the new name for the session. Maximum length is 40 characters.", + "maxLength": 40 + }, + "status": { + "type": "string", + "description": "This is the new status for the session.", "enum": [ - "computer" + "active", + "completed" ] }, - "displayWidthPx": { - "type": "number", - "description": "The display width in pixels" - }, - "displayHeightPx": { + "expirationSeconds": { "type": "number", - "description": "The display height in pixels" + "description": "Session expiration time in seconds. Defaults to 24 hours (86400 seconds) if not set.", + "minimum": 60, + "maximum": 2592000, + "example": 86400 }, - "displayNumber": { - "type": "number", - "description": "Optional display number" - } - }, - "required": [ - "type", - "subType", - "id", - "orgId", - "createdAt", - "updatedAt", - "name", - "displayWidthPx", - "displayHeightPx" - ] - }, - "TextEditorTool": { - "type": "object", - "properties": { "messages": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the updated array of chat messages.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" }, { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" }, { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" } ] } + } + } + }, + "GetSessionPaginatedDTO": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This is the name of the session to filter by." }, - "type": { + "assistantId": { "type": "string", - "enum": [ - "textEditor" - ], - "description": "The type of tool. \"textEditor\" for Text Editor tool." + "description": "This is the ID of the assistant to filter sessions by." }, - "subType": { + "workflowId": { "type": "string", - "enum": [ - "text_editor_20241022" - ], - "description": "The sub type of tool." + "description": "This is the ID of the workflow to filter sessions by." }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } + "page": { + "type": "number", + "description": "This is the page number to return. Defaults to 1.", + "minimum": 1 + }, + "sortOrder": { + "type": "string", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "enum": [ + "ASC", + "DESC" ] }, - "id": { + "limit": { + "type": "number", + "description": "This is the maximum number of items to return. Defaults to 100.", + "minimum": 0, + "maximum": 1000 + }, + "createdAtGt": { + "format": "date-time", "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This will return items where the createdAt is greater than the specified value." }, - "orgId": { + "createdAtLt": { + "format": "date-time", "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This will return items where the createdAt is less than the specified value." }, - "createdAt": { + "createdAtGe": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This will return items where the createdAt is greater than or equal to the specified value." }, - "updatedAt": { + "createdAtLe": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This will return items where the createdAt is less than or equal to the specified value." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "updatedAtGt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is greater than the specified value." }, - "name": { + "updatedAtLt": { + "format": "date-time", "type": "string", - "description": "The name of the tool, fixed to 'str_replace_editor'", - "default": "str_replace_editor", - "enum": [ - "str_replace_editor" - ] + "description": "This will return items where the updatedAt is less than the specified value." + }, + "updatedAtGe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is greater than or equal to the specified value." + }, + "updatedAtLe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is less than or equal to the specified value." + } + } + }, + "SessionPaginatedResponse": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Session" + } + }, + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" } }, "required": [ - "type", - "subType", - "id", - "orgId", - "createdAt", - "updatedAt", - "name" + "results", + "metadata" ] }, - "QueryTool": { + "ByoPhoneNumber": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to bring your own phone numbers from your own SIP trunks or Carriers.", "enum": [ - "query" - ], - "description": "The type of tool. \"query\" for Query tool." + "byo-phone-number" + ] }, - "knowledgeBases": { - "description": "The knowledge bases to query", - "type": "array", - "items": { - "$ref": "#/components/schemas/KnowledgeBase" - } + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the phone number." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the org that this phone number belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the phone number was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the phone number was last updated." + }, + "status": { + "type": "string", + "description": "This is the status of the phone number.", + "enum": [ + "active", + "activating", + "blocked" + ] + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "orgId": { + "assistantId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "createdAt": { - "format": "date-time", + "workflowId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "updatedAt": { - "format": "date-time", + "squadId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] + }, + "number": { + "type": "string", + "description": "This is the number of the customer.", + "minLength": 3, + "maxLength": 40 + }, + "credentialId": { + "type": "string", + "description": "This is the credential of your own SIP trunk or Carrier (type `byo-sip-trunk`) which can be used to make calls to this phone number.\n\nYou can add the SIP trunk or Carrier credential in the Provider Credentials page on the Dashboard to get the credentialId." } }, "required": [ - "type", + "provider", "id", "orgId", "createdAt", - "updatedAt" + "updatedAt", + "credentialId" ] }, - "GoogleCalendarCreateEventTool": { + "TwilioPhoneNumber": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to use numbers bought on Twilio.", "enum": [ - "google.calendar.event.create" - ], - "description": "The type of tool. \"google.calendar.event.create\" for Google Calendar Create Event tool." + "twilio" + ] + }, + "smsEnabled": { + "type": "boolean", + "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", + "default": true }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the phone number." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the unique identifier for the org that this phone number belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the ISO 8601 date-time string of when the phone number was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ISO 8601 date-time string of when the phone number was last updated." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "status": { + "type": "string", + "description": "This is the status of the phone number.", + "enum": [ + "active", + "activating", + "blocked" + ] + }, + "twilioAuthToken": { + "type": "string", + "description": "This is the Twilio Auth Token for the phone number." + }, + "twilioApiKey": { + "type": "string", + "description": "This is the Twilio API Key for the phone number." + }, + "twilioApiSecret": { + "type": "string", + "description": "This is the Twilio API Secret for the phone number." + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 + }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] + }, + "number": { + "type": "string", + "description": "These are the digits of the phone number you own on your Twilio." + }, + "twilioAccountSid": { + "type": "string", + "description": "This is the Twilio Account SID for the phone number." } }, "required": [ - "type", + "provider", "id", "orgId", "createdAt", - "updatedAt" + "updatedAt", + "number", + "twilioAccountSid" ] }, - "GoogleSheetsRowAppendTool": { + "VonagePhoneNumber": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to use numbers bought on Vonage.", "enum": [ - "google.sheets.row.append" - ], - "description": "The type of tool. \"google.sheets.row.append\" for Google Sheets Row Append tool." + "vonage" + ] }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the phone number." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the unique identifier for the org that this phone number belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the ISO 8601 date-time string of when the phone number was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ISO 8601 date-time string of when the phone number was last updated." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "status": { + "type": "string", + "description": "This is the status of the phone number.", + "enum": [ + "active", + "activating", + "blocked" + ] + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 + }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] + }, + "number": { + "type": "string", + "description": "These are the digits of the phone number you own on your Vonage." + }, + "credentialId": { + "type": "string", + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." } }, "required": [ - "type", + "provider", "id", "orgId", "createdAt", - "updatedAt" + "updatedAt", + "number", + "credentialId" ] }, - "GoogleCalendarCheckAvailabilityTool": { + "SipAuthentication": { "type": "object", "properties": { - "messages": { + "realm": { + "type": "string", + "description": "This will be expected in the `realm` field of the `authorization` header of the SIP INVITE. Defaults to sip.vapi.ai." + }, + "username": { + "type": "string", + "description": "This will be expected in the `username` field of the `authorization` header of the SIP INVITE.", + "minLength": 20, + "maxLength": 40 + }, + "password": { + "type": "string", + "description": "This will be expected to generate the `response` field of the `authorization` header of the SIP INVITE, through digest authentication.", + "minLength": 20, + "maxLength": 40 + } + }, + "required": [ + "username", + "password" + ] + }, + "VapiPhoneNumber": { + "type": "object", + "properties": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to create free SIP phone numbers on Vapi.", "enum": [ - "google.calendar.availability.check" - ], - "description": "The type of tool. \"google.calendar.availability.check\" for Google Calendar Check Availability tool." + "vapi" + ] }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the phone number." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the unique identifier for the org that this phone number belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the ISO 8601 date-time string of when the phone number was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ISO 8601 date-time string of when the phone number was last updated." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "status": { + "type": "string", + "description": "This is the status of the phone number.", + "enum": [ + "active", + "activating", + "blocked" + ] + }, + "number": { + "type": "string", + "description": "These are the digits of the phone number you purchased from Vapi." + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 + }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" + } + ] + }, + "numberDesiredAreaCode": { + "type": "string", + "description": "This is the area code of the phone number to purchase.", + "minLength": 3, + "maxLength": 3 + }, + "sipUri": { + "type": "string", + "description": "This is the SIP URI of the phone number. You can SIP INVITE this. The assistant attached to this number will answer.\n\nThis is case-insensitive." + }, + "authentication": { + "description": "This enables authentication for incoming SIP INVITE requests to the `sipUri`.\n\nIf not set, any username/password to the 401 challenge of the SIP INVITE will be accepted.", + "allOf": [ + { + "$ref": "#/components/schemas/SipAuthentication" } ] } }, "required": [ - "type", + "provider", "id", "orgId", "createdAt", "updatedAt" ] }, - "SlackSendMessageTool": { + "TelnyxPhoneNumber": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to use numbers bought on Telnyx.", "enum": [ - "slack.message.send" - ], - "description": "The type of tool. \"slack.message.send\" for Slack Send Message tool." + "telnyx" + ] }, "id": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the unique identifier for the phone number." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the unique identifier for the org that this phone number belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the ISO 8601 date-time string of when the phone number was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the ISO 8601 date-time string of when the phone number was last updated." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "status": { + "type": "string", + "description": "This is the status of the phone number.", + "enum": [ + "active", + "activating", + "blocked" + ] + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 + }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] + }, + "number": { + "type": "string", + "description": "These are the digits of the phone number you own on your Telnyx." + }, + "credentialId": { + "type": "string", + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." } }, "required": [ - "type", + "provider", "id", "orgId", "createdAt", - "updatedAt" + "updatedAt", + "number", + "credentialId" ] }, - "SmsTool": { + "CreateByoPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to bring your own phone numbers from your own SIP trunks or Carriers.", "enum": [ - "sms" - ], - "description": "The type of tool. \"sms\" for Twilio SMS sending tool." + "byo-phone-number" + ] }, - "id": { + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true + }, + "number": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the number of the customer.", + "minLength": 3, + "maxLength": 40 }, - "orgId": { + "credentialId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the credential of your own SIP trunk or Carrier (type `byo-sip-trunk`) which can be used to make calls to this phone number.\n\nYou can add the SIP trunk or Carrier credential in the Provider Credentials page on the Dashboard to get the credentialId." }, - "createdAt": { - "format": "date-time", + "name": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "updatedAt": { - "format": "date-time", + "assistantId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" + "provider", + "credentialId" ] }, - "McpTool": { + "CreateTwilioPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to use numbers bought on Twilio.", "enum": [ - "mcp" - ], - "description": "The type of tool. \"mcp\" for MCP tool." - }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } + "twilio" ] }, - "id": { + "smsEnabled": { + "type": "boolean", + "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", + "default": true + }, + "number": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "These are the digits of the phone number you own on your Twilio." }, - "orgId": { + "twilioAccountSid": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the Twilio Account SID for the phone number." }, - "createdAt": { - "format": "date-time", + "twilioAuthToken": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the Twilio Auth Token for the phone number." }, - "updatedAt": { - "format": "date-time", + "twilioApiKey": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the Twilio API Key for the phone number." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "twilioApiSecret": { + "type": "string", + "description": "This is the Twilio API Secret for the phone number." + }, + "name": { + "type": "string", + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 + }, + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] - }, - "metadata": { - "$ref": "#/components/schemas/McpToolMetadata" } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" + "provider", + "number", + "twilioAccountSid" ] }, - "GoHighLevelCalendarAvailabilityTool": { + "CreateVonagePhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to use numbers bought on Vonage.", "enum": [ - "gohighlevel.calendar.availability.check" - ], - "description": "The type of tool. \"gohighlevel.calendar.availability.check\" for GoHighLevel Calendar Availability Check tool." + "vonage" + ] }, - "id": { + "number": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "These are the digits of the phone number you own on your Vonage." }, - "orgId": { + "credentialId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." }, - "createdAt": { - "format": "date-time", + "name": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "updatedAt": { - "format": "date-time", + "assistantId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" + "provider", + "number", + "credentialId" ] }, - "GoHighLevelCalendarEventCreateTool": { + "CreateVapiPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to create free SIP phone numbers on Vapi.", "enum": [ - "gohighlevel.calendar.event.create" - ], - "description": "The type of tool. \"gohighlevel.calendar.event.create\" for GoHighLevel Calendar Event Create tool." + "vapi" + ] }, - "id": { + "numberDesiredAreaCode": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the area code of the phone number to purchase.", + "minLength": 3, + "maxLength": 3 }, - "orgId": { + "sipUri": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the SIP URI of the phone number. You can SIP INVITE this. The assistant attached to this number will answer.\n\nThis is case-insensitive." }, - "createdAt": { - "format": "date-time", + "authentication": { + "description": "This enables authentication for incoming SIP INVITE requests to the `sipUri`.\n\nIf not set, any username/password to the 401 challenge of the SIP INVITE will be accepted.", + "allOf": [ + { + "$ref": "#/components/schemas/SipAuthentication" + } + ] + }, + "name": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "updatedAt": { - "format": "date-time", + "assistantId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" + "provider" ] }, - "GoHighLevelContactCreateTool": { + "CreateTelnyxPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "provider": { "type": "string", + "description": "This is to use numbers bought on Telnyx.", "enum": [ - "gohighlevel.contact.create" - ], - "description": "The type of tool. \"gohighlevel.contact.create\" for GoHighLevel Contact Create tool." + "telnyx" + ] }, - "id": { + "number": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "These are the digits of the phone number you own on your Telnyx." }, - "orgId": { + "credentialId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." }, - "createdAt": { - "format": "date-time", + "name": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "updatedAt": { - "format": "date-time", + "assistantId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] } }, "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" + "provider", + "number", + "credentialId" ] }, - "GoHighLevelContactGetTool": { + "UpdateByoPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { - "type": "string", - "enum": [ - "gohighlevel.contact.get" - ], - "description": "The type of tool. \"gohighlevel.contact.get\" for GoHighLevel Contact Get tool." + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true }, - "id": { + "name": { "type": "string", - "description": "This is the unique identifier for the tool." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "orgId": { + "assistantId": { "type": "string", - "description": "This is the unique identifier for the organization that this tool belongs to." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "createdAt": { - "format": "date-time", + "workflowId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was created." + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "updatedAt": { - "format": "date-time", + "squadId": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the tool was last updated." + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] - } - }, - "required": [ - "type", - "id", - "orgId", - "createdAt", - "updatedAt" - ] + }, + "number": { + "type": "string", + "description": "This is the number of the customer.", + "minLength": 3, + "maxLength": 40 + }, + "credentialId": { + "type": "string", + "description": "This is the credential of your own SIP trunk or Carrier (type `byo-sip-trunk`) which can be used to make calls to this phone number.\n\nYou can add the SIP trunk or Carrier credential in the Provider Credentials page on the Dashboard to get the credentialId." + } + } }, - "CreateApiRequestToolDTO": { + "UpdateTwilioPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { - "type": "string", - "enum": [ - "apiRequest" - ], - "description": "The type of tool. \"apiRequest\" for API request tool." + "smsEnabled": { + "type": "boolean", + "description": "Controls whether Vapi sets the messaging webhook URL on the Twilio number during import.\n\nIf set to `false`, Vapi will not update the Twilio messaging URL, leaving it as is.\nIf `true` or omitted (default), Vapi will configure both the voice and messaging URLs.\n\n@default true", + "default": true }, - "method": { + "name": { "type": "string", - "enum": [ - "POST", - "GET", - "PUT", - "PATCH", - "DELETE" - ] - }, - "timeoutSeconds": { - "type": "number", - "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20", - "minimum": 1, - "maximum": 300, - "example": 20 + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "name": { + "assistantId": { "type": "string", - "description": "This is the name of the tool. This will be passed to the model.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 40.", - "maxLength": 40, - "pattern": "/^[a-zA-Z0-9_-]{1,40}$/" + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "description": { + "workflowId": { "type": "string", - "description": "This is the description of the tool. This will be passed to the model.", - "maxLength": 1000 + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "url": { + "squadId": { "type": "string", - "description": "This is where the request will be sent." + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, - "body": { - "description": "This is the body of the request.", + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/JsonSchema" + "$ref": "#/components/schemas/Server" } ] }, - "headers": { - "description": "These are the headers to send with the request.", - "allOf": [ - { - "$ref": "#/components/schemas/JsonSchema" - } - ] + "number": { + "type": "string", + "description": "These are the digits of the phone number you own on your Twilio." }, - "backoffPlan": { - "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)", - "allOf": [ - { - "$ref": "#/components/schemas/BackoffPlan" - } - ] + "twilioAccountSid": { + "type": "string", + "description": "This is the Twilio Account SID for the phone number." }, - "variableExtractionPlan": { - "description": "This is the plan to extract variables from the tool's response. These will be accessible during the call and stored in `call.artifact.variableValues` after the call.\n\nUsage:\n1. Use `aliases` to extract variables from the tool's response body. (Most common case)\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{customer.name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{customer.age}}\"\n }\n ]\n}\n```\n\nThe tool response body is made available to the liquid template.\n\n2. Use `aliases` to extract variables from the tool's response body if the response is an array.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{$[0].name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{$[0].age}}\"\n }\n ]\n}\n```\n\n$ is a shorthand for the tool's response body. `$[0]` is the first item in the array. `$[n]` is the nth item in the array. Note, $ is available regardless of the response body type (both object and array).\n\n3. Use `aliases` to extract variables from the tool's response headers.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{tool.response.headers.customer-name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{tool.response.headers.customer-age}}\"\n }\n ]\n}\n```\n\n`tool.response` is made available to the liquid template. Particularly, both `tool.response.headers` and `tool.response.body` are available. Note, `tool.response` is available regardless of the response body type (both object and array).\n\n4. Use `schema` to extract a large portion of the tool's response body.\n\n4.1. If you hit example.com and it returns `{\"name\": \"John\", \"age\": 30}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n }\n }\n }\n}\n```\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n4.2. If you hit example.com and it returns `{\"name\": {\"first\": \"John\", \"last\": \"Doe\"}}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"object\",\n \"properties\": {\n \"first\": {\n \"type\": \"string\"\n },\n \"last\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n4.3. If you hit example.com and it returns `[\"94123\", \"94124\"]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"zipCodes\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4.4. If you hit example.com and it returns `[{\"name\": \"John\", \"age\": 30, \"zipCodes\": [\"94123\", \"94124\"]}, {\"name\": \"Jane\", \"age\": 25, \"zipCodes\": [\"94125\", \"94126\"]}]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"people\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n },\n \"zipCodes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.\n\nNote: Both `aliases` and `schema` can be used together.", - "allOf": [ - { - "$ref": "#/components/schemas/VariableExtractionPlan" - } - ] + "twilioAuthToken": { + "type": "string", + "description": "This is the Twilio Auth Token for the phone number." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "twilioApiKey": { + "type": "string", + "description": "This is the Twilio API Key for the phone number." + }, + "twilioApiSecret": { + "type": "string", + "description": "This is the Twilio API Secret for the phone number." } - }, - "required": [ - "type", - "method", - "url" - ] + } }, - "CreateOutputToolDTO": { + "UpdateVonagePhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "name": { "type": "string", - "enum": [ - "output" - ], - "description": "The type of tool. \"output\" for Output tool." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] + }, + "number": { + "type": "string", + "description": "These are the digits of the phone number you own on your Vonage." + }, + "credentialId": { + "type": "string", + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." } - }, - "required": [ - "type" - ] + } }, - "CreateBashToolDTO": { + "UpdateVapiPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "name": { "type": "string", - "enum": [ - "bash" - ], - "description": "The type of tool. \"bash\" for Bash tool." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "subType": { + "assistantId": { "type": "string", - "enum": [ - "bash_20241022" - ], - "description": "The sub type of tool." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { "$ref": "#/components/schemas/Server" } ] }, - "name": { + "sipUri": { "type": "string", - "description": "The name of the tool, fixed to 'bash'", - "default": "bash", - "enum": [ - "bash" - ] + "description": "This is the SIP URI of the phone number. You can SIP INVITE this. The assistant attached to this number will answer.\n\nThis is case-insensitive." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "authentication": { + "description": "This enables authentication for incoming SIP INVITE requests to the `sipUri`.\n\nIf not set, any username/password to the 401 challenge of the SIP INVITE will be accepted.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/SipAuthentication" } ] } - }, - "required": [ - "type", - "subType", - "name" - ] + } }, - "CreateComputerToolDTO": { + "UpdateTelnyxPhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "name": { "type": "string", - "enum": [ - "computer" - ], - "description": "The type of tool. \"computer\" for Computer tool." + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "subType": { + "assistantId": { "type": "string", - "enum": [ - "computer_20241022" - ], - "description": "The sub type of tool." + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." }, "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { "$ref": "#/components/schemas/Server" } ] }, - "name": { + "number": { "type": "string", - "description": "The name of the tool, fixed to 'computer'", - "default": "computer", - "enum": [ - "computer" - ] - }, - "displayWidthPx": { - "type": "number", - "description": "The display width in pixels" - }, - "displayHeightPx": { - "type": "number", - "description": "The display height in pixels" - }, - "displayNumber": { - "type": "number", - "description": "Optional display number" + "description": "These are the digits of the phone number you own on your Telnyx." }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] + "credentialId": { + "type": "string", + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." } - }, - "required": [ - "type", - "subType", - "name", - "displayWidthPx", - "displayHeightPx" - ] + } }, - "CreateTextEditorToolDTO": { + "ImportVonagePhoneNumberDTO": { "type": "object", "properties": { - "messages": { + "fallbackDestination": { + "description": "This is the fallback destination an inbound call will be transferred to if:\n1. `assistantId` is not set\n2. `squadId` is not set\n3. and, `assistant-request` message to the `serverUrl` fails\n\nIf this is not set and above conditions are met, the inbound call is hung up with an error message.", + "oneOf": [ + { + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "NumberTransferDestination" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "SipTransferDestination" + } + ] + }, + "hooks": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "This is the hooks that will be used for incoming calls to this phone number.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" - }, - { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" - }, - { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/PhoneNumberHookCallRinging", + "title": "PhoneNumberHookCallRinging" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/PhoneNumberHookCallEnding", + "title": "PhoneNumberHookCallEnding" } ] } }, - "type": { + "vonagePhoneNumber": { "type": "string", - "enum": [ - "textEditor" - ], - "description": "The type of tool. \"textEditor\" for Text Editor tool." + "description": "These are the digits of the phone number you own on your Vonage.", + "deprecated": true }, - "subType": { + "credentialId": { "type": "string", - "enum": [ - "text_editor_20241022" - ], - "description": "The sub type of tool." - }, - "server": { - "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", - "allOf": [ - { - "$ref": "#/components/schemas/Server" - } - ] + "description": "This is the credential you added in dashboard.vapi.ai/keys. This is used to configure the number to send inbound calls to Vapi, make outbound calls and do live call updates like transfers and hangups." }, "name": { "type": "string", - "description": "The name of the tool, fixed to 'str_replace_editor'", - "default": "str_replace_editor", - "enum": [ - "str_replace_editor" - ] + "description": "This is the name of the phone number. This is just for your own reference.", + "maxLength": 40 }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "assistantId": { + "type": "string", + "description": "This is the assistant that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId` nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "workflowId": { + "type": "string", + "description": "This is the workflow that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for incoming calls to this phone number.\n\nIf neither `assistantId`, `squadId`, nor `workflowId` is set, `assistant-request` will be sent to your Server URL. Check `ServerMessage` and `ServerMessageResponse` for the shape of the message and response that is expected." + }, + "server": { + "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. assistant.server\n2. phoneNumber.server\n3. org.server", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/Server" } ] } }, "required": [ - "type", - "subType", - "name" + "vonagePhoneNumber", + "credentialId" ] }, - "CreateSmsToolDTO": { + "PhoneNumberPaginatedResponse": { "type": "object", "properties": { - "messages": { + "results": { "type": "array", - "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "description": "A list of phone numbers, which can be of any provider type.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ToolMessageStart", - "title": "ToolMessageStart" + "$ref": "#/components/schemas/ByoPhoneNumber" }, { - "$ref": "#/components/schemas/ToolMessageComplete", - "title": "ToolMessageComplete" + "$ref": "#/components/schemas/TwilioPhoneNumber" }, { - "$ref": "#/components/schemas/ToolMessageFailed", - "title": "ToolMessageFailed" + "$ref": "#/components/schemas/VonagePhoneNumber" }, { - "$ref": "#/components/schemas/ToolMessageDelayed", - "title": "ToolMessageDelayed" + "$ref": "#/components/schemas/VapiPhoneNumber" + }, + { + "$ref": "#/components/schemas/TelnyxPhoneNumber" } ] } }, - "type": { - "type": "string", - "enum": [ - "sms" - ], - "description": "The type of tool. \"sms\" for Twilio SMS sending tool." - }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "metadata": { + "description": "Metadata about the pagination.", "allOf": [ { - "$ref": "#/components/schemas/ToolRejectionPlan" + "$ref": "#/components/schemas/PaginationMeta" } ] } }, "required": [ - "type" + "results", + "metadata" ] }, - "UpdateApiRequestToolDTO": { + "ApiRequestTool": { "type": "object", "properties": { "messages": { @@ -35345,6 +32432,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "apiRequest" + ], + "description": "The type of tool. \"apiRequest\" for API request tool." + }, "method": { "type": "string", "enum": [ @@ -35362,6 +32456,29 @@ "maximum": 300, "example": 20 }, + "credentialId": { + "type": "string", + "description": "The credential ID for API request authentication", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35417,9 +32534,18 @@ } ] } - } + }, + "required": [ + "type", + "method", + "id", + "orgId", + "createdAt", + "updatedAt", + "url" + ] }, - "UpdateDtmfToolDTO": { + "DtmfTool": { "type": "object", "properties": { "messages": { @@ -35446,6 +32572,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "dtmf" + ], + "description": "The type of tool. \"dtmf\" for DTMF tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35454,9 +32605,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateEndCallToolDTO": { + "EndCallTool": { "type": "object", "properties": { "messages": { @@ -35483,6 +32641,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "endCall" + ], + "description": "The type of tool. \"endCall\" for End Call tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35491,9 +32674,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateFunctionToolDTO": { + "FunctionTool": { "type": "object", "properties": { "messages": { @@ -35520,6 +32710,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "function" + ], + "description": "The type of tool. \"function\" for Function tool." + }, "async": { "type": "boolean", "example": false, @@ -35533,6 +32730,24 @@ } ] }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35549,9 +32764,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGhlToolDTO": { + "GhlTool": { "type": "object", "properties": { "messages": { @@ -35578,6 +32800,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "ghl" + ], + "description": "The type of tool. \"ghl\" for GHL tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35589,9 +32836,17 @@ "metadata": { "$ref": "#/components/schemas/GhlToolMetadata" } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt", + "metadata" + ] }, - "UpdateMakeToolDTO": { + "MakeTool": { "type": "object", "properties": { "messages": { @@ -35618,6 +32873,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "make" + ], + "description": "The type of tool. \"make\" for Make tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35629,9 +32909,17 @@ "metadata": { "$ref": "#/components/schemas/MakeToolMetadata" } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt", + "metadata" + ] }, - "UpdateHandoffToolDTO": { + "TransferCallTool": { "type": "object", "properties": { "messages": { @@ -35658,22 +32946,50 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "transferCall" + ] + }, "destinations": { "type": "array", - "description": "These are the destinations that the call can be handed off to.\n\nUsage:\n1. Single destination\n\nUse `assistantId` to handoff the call to a saved assistant, or `assistantName` to handoff the call to an assistant in the same squad.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\", // or \"assistantName\": \"Assistant123\"\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2. Multiple destinations\n\n2.1. Multiple Tools, Each With One Destination (OpenAI recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n ],\n },\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2.2. One Tool, Multiple Destinations (Anthropic recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3. Dynamic destination\n\n3.1 To determine the destination dynamically, supply a `dynamic` handoff destination type and a `server` object.\n VAPI will send a handoff-destination-request webhook to the `server.url`.\n The response from the server will be used as the destination (if valid).\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3.2. To pass custom parameters to the server, you can use the `function` object.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n },\n }\n ],\n \"function\": {\n \"name\": \"handoff\",\n \"description\": \"Call this function when the customer is ready to be handed off to the next assistant\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"destination\": {\n \"type\": \"string\",\n \"description\": \"Use dynamic when customer is ready to be handed off to the next assistant\",\n \"enum\": [\"dynamic\"]\n },\n \"customerAreaCode\": {\n \"type\": \"number\",\n \"description\": \"Area code of the customer\"\n },\n \"customerIntent\": {\n \"type\": \"string\",\n \"enum\": [\"new-customer\", \"existing-customer\"],\n \"description\": \"Use new-customer when customer is a new customer, existing-customer when customer is an existing customer\"\n },\n \"customerSentiment\": {\n \"type\": \"string\",\n \"enum\": [\"positive\", \"negative\", \"neutral\"],\n \"description\": \"Use positive when customer is happy, negative when customer is unhappy, neutral when customer is neutral\"\n }\n }\n }\n }\n }\n ]\n}\n```\n\nThe properties `customerAreaCode`, `customerIntent`, and `customerSentiment` will be passed to the server in the webhook request body.", + "description": "These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/HandoffDestinationAssistant", + "$ref": "#/components/schemas/TransferDestinationAssistant", "title": "Assistant" }, { - "$ref": "#/components/schemas/HandoffDestinationDynamic", - "title": "Dynamic" + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "Number" + }, + { + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "Sip" } ] } }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35682,9 +32998,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateTransferCallToolDTO": { + "HandoffTool": { "type": "object", "properties": { "messages": { @@ -35711,26 +33034,47 @@ ] } }, + "type": { + "type": "string", + "description": "This is the type of the tool.\nWhen you're using handoff tool, we recommend adding this to your system prompt\n---\n# System context\n\nYou are part of a multi-agent system designed to make agent coordination and execution easy. Agents uses two primary abstraction: **Agents** and **Handoffs**. An agent encompasses instructions and tools and can hand off a conversation to another agent when appropriate. Handoffs are achieved by calling a handoff function, generally named `handoff_to_`. Handoffs between agents are handled seamlessly in the background; do not mention or draw attention to these handoffs in your conversation with the user.\n\n# Agent context\n\n{put your agent system prompt here}\n---", + "enum": [ + "handoff" + ] + }, "destinations": { "type": "array", - "description": "These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.", + "description": "These are the destinations that the call can be handed off to.\n\nUsage:\n1. Single destination\n\nUse `assistantId` to handoff the call to a saved assistant, or `assistantName` to handoff the call to an assistant in the same squad.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\", // or \"assistantName\": \"Assistant123\"\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2. Multiple destinations\n\n2.1. Multiple Tools, Each With One Destination (OpenAI recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n ],\n },\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2.2. One Tool, Multiple Destinations (Anthropic recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3. Dynamic destination\n\n3.1 To determine the destination dynamically, supply a `dynamic` handoff destination type and a `server` object.\n VAPI will send a handoff-destination-request webhook to the `server.url`.\n The response from the server will be used as the destination (if valid).\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3.2. To pass custom parameters to the server, you can use the `function` object.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n },\n }\n ],\n \"function\": {\n \"name\": \"handoff\",\n \"description\": \"Call this function when the customer is ready to be handed off to the next assistant\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"destination\": {\n \"type\": \"string\",\n \"description\": \"Use dynamic when customer is ready to be handed off to the next assistant\",\n \"enum\": [\"dynamic\"]\n },\n \"customerAreaCode\": {\n \"type\": \"number\",\n \"description\": \"Area code of the customer\"\n },\n \"customerIntent\": {\n \"type\": \"string\",\n \"enum\": [\"new-customer\", \"existing-customer\"],\n \"description\": \"Use new-customer when customer is a new customer, existing-customer when customer is an existing customer\"\n },\n \"customerSentiment\": {\n \"type\": \"string\",\n \"enum\": [\"positive\", \"negative\", \"neutral\"],\n \"description\": \"Use positive when customer is happy, negative when customer is unhappy, neutral when customer is neutral\"\n }\n }\n }\n }\n }\n ]\n}\n```\n\nThe properties `customerAreaCode`, `customerIntent`, and `customerSentiment` will be passed to the server in the webhook request body.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/TransferDestinationAssistant", + "$ref": "#/components/schemas/HandoffDestinationAssistant", "title": "Assistant" }, { - "$ref": "#/components/schemas/TransferDestinationNumber", - "title": "Number" - }, - { - "$ref": "#/components/schemas/TransferDestinationSip", - "title": "Sip" + "$ref": "#/components/schemas/HandoffDestinationDynamic", + "title": "Dynamic" } ] } }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35739,9 +33083,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateOutputToolDTO": { + "OutputTool": { "type": "object", "properties": { "messages": { @@ -35768,6 +33119,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "output" + ], + "description": "The type of tool. \"output\" for Output tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35776,9 +33152,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateBashToolDTO": { + "BashTool": { "type": "object", "properties": { "messages": { @@ -35805,6 +33188,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "bash" + ], + "description": "The type of tool. \"bash\" for Bash tool." + }, "subType": { "type": "string", "enum": [ @@ -35820,6 +33210,24 @@ } ] }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35836,9 +33244,18 @@ "bash" ] } - } + }, + "required": [ + "type", + "subType", + "id", + "orgId", + "createdAt", + "updatedAt", + "name" + ] }, - "UpdateComputerToolDTO": { + "ComputerTool": { "type": "object", "properties": { "messages": { @@ -35865,6 +33282,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "computer" + ], + "description": "The type of tool. \"computer\" for Computer tool." + }, "subType": { "type": "string", "enum": [ @@ -35880,6 +33304,24 @@ } ] }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35908,9 +33350,20 @@ "type": "number", "description": "Optional display number" } - } + }, + "required": [ + "type", + "subType", + "id", + "orgId", + "createdAt", + "updatedAt", + "name", + "displayWidthPx", + "displayHeightPx" + ] }, - "UpdateTextEditorToolDTO": { + "TextEditorTool": { "type": "object", "properties": { "messages": { @@ -35937,6 +33390,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "textEditor" + ], + "description": "The type of tool. \"textEditor\" for Text Editor tool." + }, "subType": { "type": "string", "enum": [ @@ -35952,6 +33412,24 @@ } ] }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -35968,9 +33446,18 @@ "str_replace_editor" ] } - } + }, + "required": [ + "type", + "subType", + "id", + "orgId", + "createdAt", + "updatedAt", + "name" + ] }, - "UpdateQueryToolDTO": { + "QueryTool": { "type": "object", "properties": { "messages": { @@ -35997,6 +33484,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "query" + ], + "description": "The type of tool. \"query\" for Query tool." + }, "knowledgeBases": { "description": "The knowledge bases to query", "type": "array", @@ -36004,6 +33498,24 @@ "$ref": "#/components/schemas/KnowledgeBase" } }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36012,9 +33524,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoogleCalendarCreateEventToolDTO": { + "GoogleCalendarCreateEventTool": { "type": "object", "properties": { "messages": { @@ -36041,6 +33560,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "google.calendar.event.create" + ], + "description": "The type of tool. \"google.calendar.event.create\" for Google Calendar Create Event tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36049,9 +33593,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoogleSheetsRowAppendToolDTO": { + "GoogleSheetsRowAppendTool": { "type": "object", "properties": { "messages": { @@ -36078,6 +33629,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "google.sheets.row.append" + ], + "description": "The type of tool. \"google.sheets.row.append\" for Google Sheets Row Append tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36086,9 +33662,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoogleCalendarCheckAvailabilityToolDTO": { + "GoogleCalendarCheckAvailabilityTool": { "type": "object", "properties": { "messages": { @@ -36115,6 +33698,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "google.calendar.availability.check" + ], + "description": "The type of tool. \"google.calendar.availability.check\" for Google Calendar Check Availability tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36123,9 +33731,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateSlackSendMessageToolDTO": { + "SlackSendMessageTool": { "type": "object", "properties": { "messages": { @@ -36152,6 +33767,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "slack.message.send" + ], + "description": "The type of tool. \"slack.message.send\" for Slack Send Message tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36160,9 +33800,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateSmsToolDTO": { + "SmsTool": { "type": "object", "properties": { "messages": { @@ -36189,6 +33836,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "sms" + ], + "description": "The type of tool. \"sms\" for Twilio SMS sending tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36197,9 +33869,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateMcpToolDTO": { + "McpTool": { "type": "object", "properties": { "messages": { @@ -36226,6 +33905,13 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "mcp" + ], + "description": "The type of tool. \"mcp\" for MCP tool." + }, "server": { "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ @@ -36234,6 +33920,24 @@ } ] }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36245,9 +33949,16 @@ "metadata": { "$ref": "#/components/schemas/McpToolMetadata" } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoHighLevelCalendarAvailabilityToolDTO": { + "GoHighLevelCalendarAvailabilityTool": { "type": "object", "properties": { "messages": { @@ -36274,6 +33985,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "gohighlevel.calendar.availability.check" + ], + "description": "The type of tool. \"gohighlevel.calendar.availability.check\" for GoHighLevel Calendar Availability Check tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36282,9 +34018,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoHighLevelCalendarEventCreateToolDTO": { + "GoHighLevelCalendarEventCreateTool": { "type": "object", "properties": { "messages": { @@ -36311,6 +34054,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "gohighlevel.calendar.event.create" + ], + "description": "The type of tool. \"gohighlevel.calendar.event.create\" for GoHighLevel Calendar Event Create tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36319,9 +34087,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoHighLevelContactCreateToolDTO": { + "GoHighLevelContactCreateTool": { "type": "object", "properties": { "messages": { @@ -36348,6 +34123,31 @@ ] } }, + "type": { + "type": "string", + "enum": [ + "gohighlevel.contact.create" + ], + "description": "The type of tool. \"gohighlevel.contact.create\" for GoHighLevel Contact Create tool." + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the tool." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the organization that this tool belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, "rejectionPlan": { "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ @@ -36356,9 +34156,16 @@ } ] } - } + }, + "required": [ + "type", + "id", + "orgId", + "createdAt", + "updatedAt" + ] }, - "UpdateGoHighLevelContactGetToolDTO": { + "GoHighLevelContactGetTool": { "type": "object", "properties": { "messages": { @@ -36385,1623 +34192,2160 @@ ] } }, - "rejectionPlan": { - "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", - "allOf": [ - { - "$ref": "#/components/schemas/ToolRejectionPlan" - } - ] - } - } - }, - "CreateFileDTO": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "This is the File you want to upload for use with the Knowledge Base.", - "format": "binary" - } - }, - "required": [ - "file" - ] - }, - "File": { - "type": "object", - "properties": { - "object": { + "type": { "type": "string", "enum": [ - "file" - ] - }, - "status": { - "enum": [ - "processing", - "done", - "failed" + "gohighlevel.contact.get" ], - "type": "string" - }, - "name": { - "type": "string", - "description": "This is the name of the file. This is just for your own reference.", - "maxLength": 40 - }, - "originalName": { - "type": "string" - }, - "bytes": { - "type": "number" - }, - "purpose": { - "type": "string" - }, - "mimetype": { - "type": "string" - }, - "key": { - "type": "string" - }, - "path": { - "type": "string" - }, - "bucket": { - "type": "string" - }, - "url": { - "type": "string" - }, - "parsedTextUrl": { - "type": "string" - }, - "parsedTextBytes": { - "type": "number" - }, - "metadata": { - "type": "object" + "description": "The type of tool. \"gohighlevel.contact.get\" for GoHighLevel Contact Get tool." }, "id": { "type": "string", - "description": "This is the unique identifier for the file." + "description": "This is the unique identifier for the tool." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the org that this file belongs to." + "description": "This is the unique identifier for the organization that this tool belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the file was created." + "description": "This is the ISO 8601 date-time string of when the tool was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the file was last updated." + "description": "This is the ISO 8601 date-time string of when the tool was last updated." + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] } }, "required": [ + "type", "id", "orgId", "createdAt", "updatedAt" ] }, - "UpdateFileDTO": { + "CreateApiRequestToolDTO": { "type": "object", "properties": { - "name": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "type": { "type": "string", - "description": "This is the name of the file. This is just for your own reference.", - "minLength": 1, - "maxLength": 40 - } - } - }, - "TrieveKnowledgeBaseSearchPlan": { - "type": "object", - "properties": { - "topK": { - "type": "number", - "description": "Specifies the number of top chunks to return. This corresponds to the `page_size` parameter in Trieve." + "enum": [ + "apiRequest" + ], + "description": "The type of tool. \"apiRequest\" for API request tool." }, - "removeStopWords": { - "type": "boolean", - "description": "If true, stop words (specified in server/src/stop-words.txt in the git repo) will be removed. This will preserve queries that are entirely stop words." + "method": { + "type": "string", + "enum": [ + "POST", + "GET", + "PUT", + "PATCH", + "DELETE" + ] }, - "scoreThreshold": { + "timeoutSeconds": { "type": "number", - "description": "This is the score threshold to filter out chunks with a score below the threshold for cosine distance metric. For Manhattan Distance, Euclidean Distance, and Dot Product, it will filter out scores above the threshold distance. This threshold applies before weight and bias modifications. If not specified, this defaults to no threshold. A threshold of 0 will default to no threshold." + "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20", + "minimum": 1, + "maximum": 300, + "example": 20 }, - "searchType": { + "credentialId": { "type": "string", - "description": "This is the search method used when searching for relevant chunks from the vector store.", - "enum": [ - "fulltext", - "semantic", - "hybrid", - "bm25" - ] - } - }, - "required": [ - "searchType" - ] - }, - "TrieveKnowledgeBase": { - "type": "object", - "properties": { - "provider": { + "description": "The credential ID for API request authentication", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "name": { "type": "string", - "description": "This knowledge base is provided by Trieve.\n\nTo learn more about Trieve, visit https://trieve.ai.", - "enum": [ - "trieve" - ] + "description": "This is the name of the tool. This will be passed to the model.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 40.", + "maxLength": 40, + "pattern": "/^[a-zA-Z0-9_-]{1,40}$/" }, - "name": { + "description": { "type": "string", - "description": "This is the name of the knowledge base." + "description": "This is the description of the tool. This will be passed to the model.", + "maxLength": 1000 }, - "searchPlan": { - "description": "This is the searching plan used when searching for relevant chunks from the vector store.\n\nYou should configure this if you're running into these issues:\n- Too much unnecessary context is being fed as knowledge base context.\n- Not enough relevant context is being fed as knowledge base context.", + "url": { + "type": "string", + "description": "This is where the request will be sent." + }, + "body": { + "description": "This is the body of the request.", "allOf": [ { - "$ref": "#/components/schemas/TrieveKnowledgeBaseSearchPlan" + "$ref": "#/components/schemas/JsonSchema" } ] }, - "createPlan": { - "description": "This is the plan if you want us to create/import a new vector store using Trieve.", - "oneOf": [ + "headers": { + "description": "These are the headers to send with the request.", + "allOf": [ { - "$ref": "#/components/schemas/TrieveKnowledgeBaseImport", - "title": "Import" + "$ref": "#/components/schemas/JsonSchema" } ] }, - "id": { - "type": "string", - "description": "This is the id of the knowledge base." + "backoffPlan": { + "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)", + "allOf": [ + { + "$ref": "#/components/schemas/BackoffPlan" + } + ] }, - "orgId": { - "type": "string", - "description": "This is the org id of the knowledge base." + "variableExtractionPlan": { + "description": "This is the plan to extract variables from the tool's response. These will be accessible during the call and stored in `call.artifact.variableValues` after the call.\n\nUsage:\n1. Use `aliases` to extract variables from the tool's response body. (Most common case)\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{customer.name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{customer.age}}\"\n }\n ]\n}\n```\n\nThe tool response body is made available to the liquid template.\n\n2. Use `aliases` to extract variables from the tool's response body if the response is an array.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{$[0].name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{$[0].age}}\"\n }\n ]\n}\n```\n\n$ is a shorthand for the tool's response body. `$[0]` is the first item in the array. `$[n]` is the nth item in the array. Note, $ is available regardless of the response body type (both object and array).\n\n3. Use `aliases` to extract variables from the tool's response headers.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{tool.response.headers.customer-name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{tool.response.headers.customer-age}}\"\n }\n ]\n}\n```\n\n`tool.response` is made available to the liquid template. Particularly, both `tool.response.headers` and `tool.response.body` are available. Note, `tool.response` is available regardless of the response body type (both object and array).\n\n4. Use `schema` to extract a large portion of the tool's response body.\n\n4.1. If you hit example.com and it returns `{\"name\": \"John\", \"age\": 30}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n }\n }\n }\n}\n```\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n4.2. If you hit example.com and it returns `{\"name\": {\"first\": \"John\", \"last\": \"Doe\"}}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"object\",\n \"properties\": {\n \"first\": {\n \"type\": \"string\"\n },\n \"last\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n4.3. If you hit example.com and it returns `[\"94123\", \"94124\"]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"zipCodes\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4.4. If you hit example.com and it returns `[{\"name\": \"John\", \"age\": 30, \"zipCodes\": [\"94123\", \"94124\"]}, {\"name\": \"Jane\", \"age\": 25, \"zipCodes\": [\"94125\", \"94126\"]}]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"people\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n },\n \"zipCodes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.\n\nNote: Both `aliases` and `schema` can be used together.", + "allOf": [ + { + "$ref": "#/components/schemas/VariableExtractionPlan" + } + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] } }, "required": [ - "provider", - "id", - "orgId" + "type", + "method", + "url" ] }, - "CustomKnowledgeBase": { + "CreateOutputToolDTO": { "type": "object", "properties": { - "provider": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "type": { "type": "string", - "description": "This knowledge base is bring your own knowledge base implementation.", "enum": [ - "custom-knowledge-base" - ] + "output" + ], + "description": "The type of tool. \"output\" for Output tool." }, - "server": { - "description": "This is where the knowledge base request will be sent.\n\nRequest Example:\n\nPOST https://{server.url}\nContent-Type: application/json\n\n{\n \"messsage\": {\n \"type\": \"knowledge-base-request\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Why is ocean blue?\"\n }\n ],\n ...other metadata about the call...\n }\n}\n\nResponse Expected:\n```\n{\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"The ocean is blue because water absorbs everything but blue.\",\n }, // YOU CAN RETURN THE EXACT RESPONSE TO SPEAK\n \"documents\": [\n {\n \"content\": \"The ocean is blue primarily because water absorbs colors in the red part of the light spectrum and scatters the blue light, making it more visible to our eyes.\",\n \"similarity\": 1\n },\n {\n \"content\": \"Blue light is scattered more by the water molecules than other colors, enhancing the blue appearance of the ocean.\",\n \"similarity\": .5\n }\n ] // OR, YOU CAN RETURN AN ARRAY OF DOCUMENTS THAT WILL BE SENT TO THE MODEL\n}\n```", + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] - }, - "id": { - "type": "string", - "description": "This is the id of the knowledge base." - }, - "orgId": { - "type": "string", - "description": "This is the org id of the knowledge base." } }, "required": [ - "provider", - "server", - "id", - "orgId" + "type" ] }, - "CreateTrieveKnowledgeBaseDTO": { + "CreateBashToolDTO": { "type": "object", "properties": { - "provider": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "type": { "type": "string", - "description": "This knowledge base is provided by Trieve.\n\nTo learn more about Trieve, visit https://trieve.ai.", "enum": [ - "trieve" - ] + "bash" + ], + "description": "The type of tool. \"bash\" for Bash tool." }, - "name": { + "subType": { "type": "string", - "description": "This is the name of the knowledge base." + "enum": [ + "bash_20241022" + ], + "description": "The sub type of tool." }, - "searchPlan": { - "description": "This is the searching plan used when searching for relevant chunks from the vector store.\n\nYou should configure this if you're running into these issues:\n- Too much unnecessary context is being fed as knowledge base context.\n- Not enough relevant context is being fed as knowledge base context.", + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ { - "$ref": "#/components/schemas/TrieveKnowledgeBaseSearchPlan" + "$ref": "#/components/schemas/Server" } ] }, - "createPlan": { - "description": "This is the plan if you want us to create/import a new vector store using Trieve.", - "oneOf": [ + "name": { + "type": "string", + "description": "The name of the tool, fixed to 'bash'", + "default": "bash", + "enum": [ + "bash" + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ { - "$ref": "#/components/schemas/TrieveKnowledgeBaseImport", - "title": "Import" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] } }, "required": [ - "provider" + "type", + "subType", + "name" ] }, - "UpdateTrieveKnowledgeBaseDTO": { + "CreateComputerToolDTO": { "type": "object", "properties": { - "name": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "type": { "type": "string", - "description": "This is the name of the knowledge base." + "enum": [ + "computer" + ], + "description": "The type of tool. \"computer\" for Computer tool." }, - "searchPlan": { - "description": "This is the searching plan used when searching for relevant chunks from the vector store.\n\nYou should configure this if you're running into these issues:\n- Too much unnecessary context is being fed as knowledge base context.\n- Not enough relevant context is being fed as knowledge base context.", - "allOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBaseSearchPlan" - } - ] + "subType": { + "type": "string", + "enum": [ + "computer_20241022" + ], + "description": "The sub type of tool." }, - "createPlan": { - "description": "This is the plan if you want us to create/import a new vector store using Trieve.", - "oneOf": [ - { - "$ref": "#/components/schemas/TrieveKnowledgeBaseImport", - "title": "Import" - } - ] - } - } - }, - "UpdateCustomKnowledgeBaseDTO": { - "type": "object", - "properties": { "server": { - "description": "This is where the knowledge base request will be sent.\n\nRequest Example:\n\nPOST https://{server.url}\nContent-Type: application/json\n\n{\n \"messsage\": {\n \"type\": \"knowledge-base-request\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Why is ocean blue?\"\n }\n ],\n ...other metadata about the call...\n }\n}\n\nResponse Expected:\n```\n{\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"The ocean is blue because water absorbs everything but blue.\",\n }, // YOU CAN RETURN THE EXACT RESPONSE TO SPEAK\n \"documents\": [\n {\n \"content\": \"The ocean is blue primarily because water absorbs colors in the red part of the light spectrum and scatters the blue light, making it more visible to our eyes.\",\n \"similarity\": 1\n },\n {\n \"content\": \"Blue light is scattered more by the water molecules than other colors, enhancing the blue appearance of the ocean.\",\n \"similarity\": .5\n }\n ] // OR, YOU CAN RETURN AN ARRAY OF DOCUMENTS THAT WILL BE SENT TO THE MODEL\n}\n```", + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ { "$ref": "#/components/schemas/Server" } ] - } - } - }, - "TrieveKnowledgeBaseChunkPlan": { - "type": "object", - "properties": { - "fileIds": { - "description": "These are the file ids that will be used to create the vector store. To upload files, use the `POST /files` endpoint.", - "type": "array", - "items": { - "type": "string" - } }, - "websites": { - "description": "These are the websites that will be used to create the vector store.", - "type": "array", - "items": { - "type": "string" - } + "name": { + "type": "string", + "description": "The name of the tool, fixed to 'computer'", + "default": "computer", + "enum": [ + "computer" + ] }, - "targetSplitsPerChunk": { + "displayWidthPx": { "type": "number", - "description": "This is an optional field which allows you to specify the number of splits you want per chunk. If not specified, the default 20 is used. However, you may want to use a different number." + "description": "The display width in pixels" }, - "splitDelimiters": { - "description": "This is an optional field which allows you to specify the delimiters to use when splitting the file before chunking the text. If not specified, the default [.!?\\n] are used to split into sentences. However, you may want to use spaces or other delimiters.", - "type": "array", - "items": { - "type": "string" - } + "displayHeightPx": { + "type": "number", + "description": "The display height in pixels" }, - "rebalanceChunks": { - "type": "boolean", - "description": "This is an optional field which allows you to specify whether or not to rebalance the chunks created from the file. If not specified, the default true is used. If true, Trieve will evenly distribute remainder splits across chunks such that 66 splits with a target_splits_per_chunk of 20 will result in 3 chunks with 22 splits each." - } - } - }, - "TrieveKnowledgeBaseCreate": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "This is to create a new dataset on Trieve.", - "enum": [ - "create" - ] + "displayNumber": { + "type": "number", + "description": "Optional display number" }, - "chunkPlans": { - "description": "These are the chunk plans used to create the dataset.", - "type": "array", - "items": { - "$ref": "#/components/schemas/TrieveKnowledgeBaseChunkPlan" - } - } - }, - "required": [ - "type", - "chunkPlans" - ] - }, - "TrieveKnowledgeBaseImport": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "This is to import an existing dataset from Trieve.", - "enum": [ - "import" + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } ] - }, - "providerId": { - "type": "string", - "description": "This is the `datasetId` of the dataset on your Trieve account." } }, "required": [ "type", - "providerId" + "subType", + "name", + "displayWidthPx", + "displayHeightPx" ] }, - "Workflow": { + "CreateTextEditorToolDTO": { "type": "object", "properties": { - "nodes": { + "messages": { "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ConversationNode", - "title": "ConversationNode" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/ToolNode", - "title": "ToolNode" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } ] } }, - "model": { - "description": "This is the model for the workflow.\n\nThis can be overridden at node level using `nodes[n].model`.", - "oneOf": [ - { - "$ref": "#/components/schemas/WorkflowOpenAIModel", - "title": "WorkflowOpenAIModel" - }, - { - "$ref": "#/components/schemas/WorkflowAnthropicModel", - "title": "WorkflowAnthropicModel" - }, - { - "$ref": "#/components/schemas/WorkflowGoogleModel", - "title": "WorkflowGoogleModel" - }, - { - "$ref": "#/components/schemas/WorkflowCustomModel", - "title": "WorkflowCustomModel" - } - ] - }, - "transcriber": { - "description": "This is the transcriber for the workflow.\n\nThis can be overridden at node level using `nodes[n].transcriber`.", - "oneOf": [ - { - "$ref": "#/components/schemas/AssemblyAITranscriber", - "title": "AssemblyAITranscriber" - }, - { - "$ref": "#/components/schemas/AzureSpeechTranscriber", - "title": "AzureSpeechTranscriber" - }, - { - "$ref": "#/components/schemas/CustomTranscriber", - "title": "CustomTranscriber" - }, - { - "$ref": "#/components/schemas/DeepgramTranscriber", - "title": "DeepgramTranscriber" - }, - { - "$ref": "#/components/schemas/ElevenLabsTranscriber", - "title": "ElevenLabsTranscriber" - }, - { - "$ref": "#/components/schemas/GladiaTranscriber", - "title": "GladiaTranscriber" - }, - { - "$ref": "#/components/schemas/GoogleTranscriber", - "title": "GoogleTranscriber" - }, - { - "$ref": "#/components/schemas/SpeechmaticsTranscriber", - "title": "SpeechmaticsTranscriber" - }, - { - "$ref": "#/components/schemas/TalkscriberTranscriber", - "title": "TalkscriberTranscriber" - }, - { - "$ref": "#/components/schemas/OpenAITranscriber", - "title": "OpenAITranscriber" - }, - { - "$ref": "#/components/schemas/CartesiaTranscriber", - "title": "CartesiaTranscriber" - } - ] - }, - "voice": { - "description": "This is the voice for the workflow.\n\nThis can be overridden at node level using `nodes[n].voice`.", - "oneOf": [ - { - "$ref": "#/components/schemas/AzureVoice", - "title": "AzureVoice" - }, - { - "$ref": "#/components/schemas/CartesiaVoice", - "title": "CartesiaVoice" - }, - { - "$ref": "#/components/schemas/CustomVoice", - "title": "CustomVoice" - }, - { - "$ref": "#/components/schemas/DeepgramVoice", - "title": "DeepgramVoice" - }, - { - "$ref": "#/components/schemas/ElevenLabsVoice", - "title": "ElevenLabsVoice" - }, - { - "$ref": "#/components/schemas/HumeVoice", - "title": "HumeVoice" - }, - { - "$ref": "#/components/schemas/LMNTVoice", - "title": "LMNTVoice" - }, - { - "$ref": "#/components/schemas/NeuphonicVoice", - "title": "NeuphonicVoice" - }, - { - "$ref": "#/components/schemas/OpenAIVoice", - "title": "OpenAIVoice" - }, - { - "$ref": "#/components/schemas/PlayHTVoice", - "title": "PlayHTVoice" - }, - { - "$ref": "#/components/schemas/RimeAIVoice", - "title": "RimeAIVoice" - }, - { - "$ref": "#/components/schemas/SmallestAIVoice", - "title": "SmallestAIVoice" - }, - { - "$ref": "#/components/schemas/TavusVoice", - "title": "TavusVoice" - }, - { - "$ref": "#/components/schemas/VapiVoice", - "title": "VapiVoice" - }, - { - "$ref": "#/components/schemas/SesameVoice", - "title": "SesameVoice" - }, - { - "$ref": "#/components/schemas/InworldVoice", - "title": "InworldVoice" - }, - { - "$ref": "#/components/schemas/MinimaxVoice", - "title": "MinimaxVoice" - } - ] + "type": { + "type": "string", + "enum": [ + "textEditor" + ], + "description": "The type of tool. \"textEditor\" for Text Editor tool." }, - "observabilityPlan": { - "description": "This is the plan for observability of workflow's calls.\n\nCurrently, only Langfuse is supported.", - "oneOf": [ - { - "$ref": "#/components/schemas/LangfuseObservabilityPlan", - "title": "Langfuse" - } + "subType": { + "type": "string", + "enum": [ + "text_editor_20241022" ], + "description": "The sub type of tool." + }, + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ { - "$ref": "#/components/schemas/LangfuseObservabilityPlan" + "$ref": "#/components/schemas/Server" } ] }, - "backgroundSound": { - "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", - "oneOf": [ - { - "type": "enum", - "enum": [ - "off", - "office" - ], - "example": "office" - }, + "name": { + "type": "string", + "description": "The name of the tool, fixed to 'str_replace_editor'", + "default": "str_replace_editor", + "enum": [ + "str_replace_editor" + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ { - "type": "string", - "format": "uri", - "example": "https://www.soundjay.com/ambient/sounds/people-in-lounge-1.mp3" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] - }, - "hooks": { + } + }, + "required": [ + "type", + "subType", + "name" + ] + }, + "CreateSmsToolDTO": { + "type": "object", + "properties": { + "messages": { "type": "array", - "description": "This is a set of actions that will be performed on certain events.", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/CallHookCallEnding", - "title": "CallHookCallEnding" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", - "title": "CallHookAssistantSpeechInterrupted" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", - "title": "CallHookCustomerSpeechInterrupted" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", - "title": "CallHookCustomerSpeechTimeout" + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } ] } }, - "credentials": { + "type": { + "type": "string", + "enum": [ + "sms" + ], + "description": "The type of tool. \"sms\" for Twilio SMS sending tool." + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + }, + "required": [ + "type" + ] + }, + "UpdateApiRequestToolDTO": { + "type": "object", + "properties": { + "messages": { "type": "array", - "description": "These are dynamic credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/CreateAnthropicCredentialDTO", - "title": "AnthropicCredential" - }, - { - "$ref": "#/components/schemas/CreateAnyscaleCredentialDTO", - "title": "AnyscaleCredential" - }, - { - "$ref": "#/components/schemas/CreateAssemblyAICredentialDTO", - "title": "AssemblyAICredential" - }, - { - "$ref": "#/components/schemas/CreateAzureCredentialDTO", - "title": "AzureCredential" - }, - { - "$ref": "#/components/schemas/CreateAzureOpenAICredentialDTO", - "title": "AzureOpenAICredential" - }, - { - "$ref": "#/components/schemas/CreateByoSipTrunkCredentialDTO", - "title": "ByoSipTrunkCredential" - }, - { - "$ref": "#/components/schemas/CreateCartesiaCredentialDTO", - "title": "CartesiaCredential" - }, - { - "$ref": "#/components/schemas/CreateCerebrasCredentialDTO", - "title": "CerebrasCredential" - }, - { - "$ref": "#/components/schemas/CreateCloudflareCredentialDTO", - "title": "CloudflareCredential" - }, - { - "$ref": "#/components/schemas/CreateCustomLLMCredentialDTO", - "title": "CustomLLMCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateDeepgramCredentialDTO", - "title": "DeepgramCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateDeepInfraCredentialDTO", - "title": "DeepInfraCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateDeepSeekCredentialDTO", - "title": "DeepSeekCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "method": { + "type": "string", + "enum": [ + "POST", + "GET", + "PUT", + "PATCH", + "DELETE" + ] + }, + "timeoutSeconds": { + "type": "number", + "description": "This is the timeout in seconds for the request. Defaults to 20 seconds.\n\n@default 20", + "minimum": 1, + "maximum": 300, + "example": 20 + }, + "credentialId": { + "type": "string", + "description": "The credential ID for API request authentication", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + }, + "name": { + "type": "string", + "description": "This is the name of the tool. This will be passed to the model.\n\nMust be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 40.", + "maxLength": 40, + "pattern": "/^[a-zA-Z0-9_-]{1,40}$/" + }, + "description": { + "type": "string", + "description": "This is the description of the tool. This will be passed to the model.", + "maxLength": 1000 + }, + "url": { + "type": "string", + "description": "This is where the request will be sent." + }, + "body": { + "description": "This is the body of the request.", + "allOf": [ + { + "$ref": "#/components/schemas/JsonSchema" + } + ] + }, + "headers": { + "description": "These are the headers to send with the request.", + "allOf": [ + { + "$ref": "#/components/schemas/JsonSchema" + } + ] + }, + "backoffPlan": { + "description": "This is the backoff plan if the request fails. Defaults to undefined (the request will not be retried).\n\n@default undefined (the request will not be retried)", + "allOf": [ + { + "$ref": "#/components/schemas/BackoffPlan" + } + ] + }, + "variableExtractionPlan": { + "description": "This is the plan to extract variables from the tool's response. These will be accessible during the call and stored in `call.artifact.variableValues` after the call.\n\nUsage:\n1. Use `aliases` to extract variables from the tool's response body. (Most common case)\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{customer.name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{customer.age}}\"\n }\n ]\n}\n```\n\nThe tool response body is made available to the liquid template.\n\n2. Use `aliases` to extract variables from the tool's response body if the response is an array.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{$[0].name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{$[0].age}}\"\n }\n ]\n}\n```\n\n$ is a shorthand for the tool's response body. `$[0]` is the first item in the array. `$[n]` is the nth item in the array. Note, $ is available regardless of the response body type (both object and array).\n\n3. Use `aliases` to extract variables from the tool's response headers.\n\n```json\n{\n \"aliases\": [\n {\n \"key\": \"customerName\",\n \"value\": \"{{tool.response.headers.customer-name}}\"\n },\n {\n \"key\": \"customerAge\",\n \"value\": \"{{tool.response.headers.customer-age}}\"\n }\n ]\n}\n```\n\n`tool.response` is made available to the liquid template. Particularly, both `tool.response.headers` and `tool.response.body` are available. Note, `tool.response` is available regardless of the response body type (both object and array).\n\n4. Use `schema` to extract a large portion of the tool's response body.\n\n4.1. If you hit example.com and it returns `{\"name\": \"John\", \"age\": 30}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n }\n }\n }\n}\n```\nThese will be extracted as `{{ name }}` and `{{ age }}` respectively. To emphasize, object properties are extracted as direct global variables.\n\n4.2. If you hit example.com and it returns `{\"name\": {\"first\": \"John\", \"last\": \"Doe\"}}`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"object\",\n \"properties\": {\n \"first\": {\n \"type\": \"string\"\n },\n \"last\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThese will be extracted as `{{ name }}`. And, `{{ name.first }}` and `{{ name.last }}` will be accessible.\n\n4.3. If you hit example.com and it returns `[\"94123\", \"94124\"]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"zipCodes\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n}\n```\n\nThis will be extracted as `{{ zipCodes }}`. To access the array items, you can use `{{ zipCodes[0] }}` and `{{ zipCodes[1] }}`.\n\n4.4. If you hit example.com and it returns `[{\"name\": \"John\", \"age\": 30, \"zipCodes\": [\"94123\", \"94124\"]}, {\"name\": \"Jane\", \"age\": 25, \"zipCodes\": [\"94125\", \"94126\"]}]`, then you can specify the schema as:\n\n```json\n{\n \"schema\": {\n \"type\": \"array\",\n \"title\": \"people\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"age\": {\n \"type\": \"number\"\n },\n \"zipCodes\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n```\n\nThis will be extracted as `{{ people }}`. To access the array items, you can use `{{ people[n].name }}`, `{{ people[n].age }}`, `{{ people[n].zipCodes }}`, `{{ people[n].zipCodes[0] }}` and `{{ people[n].zipCodes[1] }}`.\n\nNote: Both `aliases` and `schema` can be used together.", + "allOf": [ + { + "$ref": "#/components/schemas/VariableExtractionPlan" + } + ] + } + } + }, + "UpdateDtmfToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateElevenLabsCredentialDTO", - "title": "ElevenLabsCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateGcpCredentialDTO", - "title": "GcpCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateGladiaCredentialDTO", - "title": "GladiaCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateGoHighLevelCredentialDTO", - "title": "GhlCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateEndCallToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateGoogleCredentialDTO", - "title": "GoogleCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateGroqCredentialDTO", - "title": "GroqCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateHumeCredentialDTO", - "title": "HumeCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateInflectionAICredentialDTO", - "title": "InflectionAICredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateFunctionToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateLangfuseCredentialDTO", - "title": "LangfuseCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateLmntCredentialDTO", - "title": "LmntCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateMakeCredentialDTO", - "title": "MakeCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateMistralCredentialDTO", - "title": "MistralCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "async": { + "type": "boolean", + "example": false, + "description": "This determines if the tool is async.\n\n If async, the assistant will move forward without waiting for your server to respond. This is useful if you just want to trigger something on your server.\n\n If sync, the assistant will wait for your server to respond. This is useful if want assistant to respond with the result from your server.\n\n Defaults to synchronous (`false`)." + }, + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "allOf": [ + { + "$ref": "#/components/schemas/Server" + } + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + }, + "function": { + "description": "This is the function definition of the tool.", + "allOf": [ + { + "$ref": "#/components/schemas/OpenAIFunction" + } + ] + } + } + }, + "UpdateGhlToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateNeuphonicCredentialDTO", - "title": "NeuphonicCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateOpenAICredentialDTO", - "title": "OpenAICredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateOpenRouterCredentialDTO", - "title": "OpenRouterCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreatePerplexityAICredentialDTO", - "title": "PerplexityAICredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + }, + "metadata": { + "$ref": "#/components/schemas/GhlToolMetadata" + } + } + }, + "UpdateMakeToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreatePlayHTCredentialDTO", - "title": "PlayHTCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateRimeAICredentialDTO", - "title": "RimeAICredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateRunpodCredentialDTO", - "title": "RunpodCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateS3CredentialDTO", - "title": "S3Credential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + }, + "metadata": { + "$ref": "#/components/schemas/MakeToolMetadata" + } + } + }, + "UpdateHandoffToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateSmallestAICredentialDTO", - "title": "SmallestAICredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateSpeechmaticsCredentialDTO", - "title": "SpeechmaticsCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateSupabaseCredentialDTO", - "title": "SupabaseCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateTavusCredentialDTO", - "title": "TavusCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "destinations": { + "type": "array", + "description": "These are the destinations that the call can be handed off to.\n\nUsage:\n1. Single destination\n\nUse `assistantId` to handoff the call to a saved assistant, or `assistantName` to handoff the call to an assistant in the same squad.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\", // or \"assistantName\": \"Assistant123\"\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2. Multiple destinations\n\n2.1. Multiple Tools, Each With One Destination (OpenAI recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n ],\n },\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n2.2. One Tool, Multiple Destinations (Anthropic recommended)\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-123\",\n \"description\": \"customer wants to be handed off to assistant-123\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n },\n {\n \"type\": \"assistant\",\n \"assistantId\": \"assistant-456\",\n \"description\": \"customer wants to be handed off to assistant-456\",\n \"contextEngineeringPlan\": {\n \"type\": \"all\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3. Dynamic destination\n\n3.1 To determine the destination dynamically, supply a `dynamic` handoff destination type and a `server` object.\n VAPI will send a handoff-destination-request webhook to the `server.url`.\n The response from the server will be used as the destination (if valid).\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n }\n }\n ],\n }\n ]\n}\n```\n\n3.2. To pass custom parameters to the server, you can use the `function` object.\n\n```json\n{\n \"tools\": [\n {\n \"type\": \"handoff\",\n \"destinations\": [\n {\n \"type\": \"dynamic\",\n \"server\": {\n \"url\": \"https://example.com\"\n },\n }\n ],\n \"function\": {\n \"name\": \"handoff\",\n \"description\": \"Call this function when the customer is ready to be handed off to the next assistant\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"destination\": {\n \"type\": \"string\",\n \"description\": \"Use dynamic when customer is ready to be handed off to the next assistant\",\n \"enum\": [\"dynamic\"]\n },\n \"customerAreaCode\": {\n \"type\": \"number\",\n \"description\": \"Area code of the customer\"\n },\n \"customerIntent\": {\n \"type\": \"string\",\n \"enum\": [\"new-customer\", \"existing-customer\"],\n \"description\": \"Use new-customer when customer is a new customer, existing-customer when customer is an existing customer\"\n },\n \"customerSentiment\": {\n \"type\": \"string\",\n \"enum\": [\"positive\", \"negative\", \"neutral\"],\n \"description\": \"Use positive when customer is happy, negative when customer is unhappy, neutral when customer is neutral\"\n }\n }\n }\n }\n }\n ]\n}\n```\n\nThe properties `customerAreaCode`, `customerIntent`, and `customerSentiment` will be passed to the server in the webhook request body.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateTogetherAICredentialDTO", - "title": "TogetherAICredential" + "$ref": "#/components/schemas/HandoffDestinationAssistant", + "title": "Assistant" }, { - "$ref": "#/components/schemas/CreateTrieveCredentialDTO", - "title": "TrieveCredential" - }, + "$ref": "#/components/schemas/HandoffDestinationDynamic", + "title": "Dynamic" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateTransferCallToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateTwilioCredentialDTO", - "title": "TwilioCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateVonageCredentialDTO", - "title": "VonageCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateWebhookCredentialDTO", - "title": "WebhookCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateXAiCredentialDTO", - "title": "XAiCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "destinations": { + "type": "array", + "description": "These are the destinations that the call can be transferred to. If no destinations are provided, server.url will be used to get the transfer destination once the tool is called.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", - "title": "GoogleCalendarOAuth2ClientCredential" + "$ref": "#/components/schemas/TransferDestinationAssistant", + "title": "Assistant" }, { - "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", - "title": "GoogleCalendarOAuth2AuthorizationCredential" + "$ref": "#/components/schemas/TransferDestinationNumber", + "title": "Number" }, { - "$ref": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", - "title": "GoogleSheetsOAuth2AuthorizationCredential" + "$ref": "#/components/schemas/TransferDestinationSip", + "title": "Sip" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateOutputToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", - "title": "SlackOAuth2AuthorizationCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", - "title": "GoHighLevelMCPCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateInworldCredentialDTO", - "title": "InworldCredential" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "11labs": "#/components/schemas/CreateElevenLabsCredentialDTO", - "anthropic": "#/components/schemas/CreateAnthropicCredentialDTO", - "anyscale": "#/components/schemas/CreateAnyscaleCredentialDTO", - "assembly-ai": "#/components/schemas/CreateAssemblyAICredentialDTO", - "azure-openai": "#/components/schemas/CreateAzureOpenAICredentialDTO", - "azure": "#/components/schemas/CreateAzureCredentialDTO", - "byo-sip-trunk": "#/components/schemas/CreateByoSipTrunkCredentialDTO", - "cartesia": "#/components/schemas/CreateCartesiaCredentialDTO", - "cerebras": "#/components/schemas/CreateCerebrasCredentialDTO", - "cloudflare": "#/components/schemas/CreateCloudflareCredentialDTO", - "custom-llm": "#/components/schemas/CreateCustomLLMCredentialDTO", - "deepgram": "#/components/schemas/CreateDeepgramCredentialDTO", - "deepinfra": "#/components/schemas/CreateDeepInfraCredentialDTO", - "deep-seek": "#/components/schemas/CreateDeepSeekCredentialDTO", - "gcp": "#/components/schemas/CreateGcpCredentialDTO", - "gladia": "#/components/schemas/CreateGladiaCredentialDTO", - "gohighlevel": "#/components/schemas/CreateGoHighLevelCredentialDTO", - "google": "#/components/schemas/CreateGoogleCredentialDTO", - "groq": "#/components/schemas/CreateGroqCredentialDTO", - "inflection-ai": "#/components/schemas/CreateInflectionAICredentialDTO", - "langfuse": "#/components/schemas/CreateLangfuseCredentialDTO", - "lmnt": "#/components/schemas/CreateLmntCredentialDTO", - "make": "#/components/schemas/CreateMakeCredentialDTO", - "openai": "#/components/schemas/CreateOpenAICredentialDTO", - "openrouter": "#/components/schemas/CreateOpenRouterCredentialDTO", - "perplexity-ai": "#/components/schemas/CreatePerplexityAICredentialDTO", - "playht": "#/components/schemas/CreatePlayHTCredentialDTO", - "rime-ai": "#/components/schemas/CreateRimeAICredentialDTO", - "runpod": "#/components/schemas/CreateRunpodCredentialDTO", - "s3": "#/components/schemas/CreateS3CredentialDTO", - "supabase": "#/components/schemas/CreateSupabaseCredentialDTO", - "smallest-ai": "#/components/schemas/CreateSmallestAICredentialDTO", - "tavus": "#/components/schemas/CreateTavusCredentialDTO", - "together-ai": "#/components/schemas/CreateTogetherAICredentialDTO", - "twilio": "#/components/schemas/CreateTwilioCredentialDTO", - "vonage": "#/components/schemas/CreateVonageCredentialDTO", - "webhook": "#/components/schemas/CreateWebhookCredentialDTO", - "xai": "#/components/schemas/CreateXAiCredentialDTO", - "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", - "hume": "#/components/schemas/CreateHumeCredentialDTO", - "mistral": "#/components/schemas/CreateMistralCredentialDTO", - "speechmatics": "#/components/schemas/CreateSpeechmaticsCredentialDTO", - "trieve": "#/components/schemas/CreateTrieveCredentialDTO", - "google.calendar.oauth2-client": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", - "google.calendar.oauth2-authorization": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", - "google.sheets.oauth2-authorization": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", - "slack.oauth2-authorization": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", - "ghl.oauth2-authorization": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", - "inworld": "#/components/schemas/CreateInworldCredentialDTO", - "minimax": "#/components/schemas/CreateMinimaxCredentialDTO" + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } - } + ] } }, - "id": { - "type": "string" - }, - "orgId": { - "type": "string" - }, - "createdAt": { - "format": "date-time", - "type": "string" - }, - "updatedAt": { - "format": "date-time", - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 80 - }, - "edges": { + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateBashToolDTO": { + "type": "object", + "properties": { + "messages": { "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { - "$ref": "#/components/schemas/Edge" + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] } }, - "globalPrompt": { + "subType": { "type": "string", - "maxLength": 5000 + "enum": [ + "bash_20241022" + ], + "description": "The sub type of tool." }, "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. tool.server\n2. workflow.server / assistant.server\n3. phoneNumber.server\n4. org.server", + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ { "$ref": "#/components/schemas/Server" } ] }, - "compliancePlan": { - "description": "This is the compliance plan for the workflow. It allows you to configure HIPAA and other compliance settings.", + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/CompliancePlan" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] }, - "analysisPlan": { - "description": "This is the plan for analysis of workflow's calls. Stored in `call.analysis`.", - "allOf": [ - { - "$ref": "#/components/schemas/AnalysisPlan" - } + "name": { + "type": "string", + "description": "The name of the tool, fixed to 'bash'", + "default": "bash", + "enum": [ + "bash" ] + } + } + }, + "UpdateComputerToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } }, - "artifactPlan": { - "description": "This is the plan for artifacts generated during workflow's calls. Stored in `call.artifact`.", - "allOf": [ - { - "$ref": "#/components/schemas/ArtifactPlan" - } - ] + "subType": { + "type": "string", + "enum": [ + "computer_20241022" + ], + "description": "The sub type of tool." }, - "startSpeakingPlan": { - "description": "This is the plan for when the workflow nodes should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ { - "$ref": "#/components/schemas/StartSpeakingPlan" + "$ref": "#/components/schemas/Server" } ] }, - "stopSpeakingPlan": { - "description": "This is the plan for when workflow nodes should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/StopSpeakingPlan" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] }, - "monitorPlan": { - "description": "This is the plan for real-time monitoring of the workflow's calls.\n\nUsage:\n- To enable live listening of the workflow's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the workflow's calls, set `monitorPlan.controlEnabled` to `true`.", - "allOf": [ - { - "$ref": "#/components/schemas/MonitorPlan" - } + "name": { + "type": "string", + "description": "The name of the tool, fixed to 'computer'", + "default": "computer", + "enum": [ + "computer" ] }, - "backgroundSpeechDenoisingPlan": { - "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nBoth can be used together. Order of precedence:\n- Smart denoising\n- Fourier denoising", - "allOf": [ - { - "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" - } - ] + "displayWidthPx": { + "type": "number", + "description": "The display width in pixels" }, - "credentialIds": { - "description": "These are the credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", - "type": "array", - "items": { - "type": "string" - } + "displayHeightPx": { + "type": "number", + "description": "The display height in pixels" }, - "keypadInputPlan": { - "description": "This is the plan for keypad input handling during workflow calls.", - "allOf": [ - { - "$ref": "#/components/schemas/KeypadInputPlan" - } - ] + "displayNumber": { + "type": "number", + "description": "Optional display number" } - }, - "required": [ - "nodes", - "id", - "orgId", - "createdAt", - "updatedAt", - "name", - "edges" - ] + } }, - "UpdateWorkflowDTO": { + "UpdateTextEditorToolDTO": { "type": "object", "properties": { - "nodes": { + "messages": { "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/ConversationNode", - "title": "ConversationNode" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/ToolNode", - "title": "ToolNode" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } ] } }, - "model": { - "description": "This is the model for the workflow.\n\nThis can be overridden at node level using `nodes[n].model`.", - "oneOf": [ - { - "$ref": "#/components/schemas/WorkflowOpenAIModel", - "title": "WorkflowOpenAIModel" - }, - { - "$ref": "#/components/schemas/WorkflowAnthropicModel", - "title": "WorkflowAnthropicModel" - }, - { - "$ref": "#/components/schemas/WorkflowGoogleModel", - "title": "WorkflowGoogleModel" - }, - { - "$ref": "#/components/schemas/WorkflowCustomModel", - "title": "WorkflowCustomModel" - } - ] - }, - "transcriber": { - "description": "This is the transcriber for the workflow.\n\nThis can be overridden at node level using `nodes[n].transcriber`.", - "oneOf": [ - { - "$ref": "#/components/schemas/AssemblyAITranscriber", - "title": "AssemblyAITranscriber" - }, - { - "$ref": "#/components/schemas/AzureSpeechTranscriber", - "title": "AzureSpeechTranscriber" - }, - { - "$ref": "#/components/schemas/CustomTranscriber", - "title": "CustomTranscriber" - }, - { - "$ref": "#/components/schemas/DeepgramTranscriber", - "title": "DeepgramTranscriber" - }, - { - "$ref": "#/components/schemas/ElevenLabsTranscriber", - "title": "ElevenLabsTranscriber" - }, - { - "$ref": "#/components/schemas/GladiaTranscriber", - "title": "GladiaTranscriber" - }, - { - "$ref": "#/components/schemas/GoogleTranscriber", - "title": "GoogleTranscriber" - }, - { - "$ref": "#/components/schemas/SpeechmaticsTranscriber", - "title": "SpeechmaticsTranscriber" - }, - { - "$ref": "#/components/schemas/TalkscriberTranscriber", - "title": "TalkscriberTranscriber" - }, - { - "$ref": "#/components/schemas/OpenAITranscriber", - "title": "OpenAITranscriber" - }, - { - "$ref": "#/components/schemas/CartesiaTranscriber", - "title": "CartesiaTranscriber" - } - ] - }, - "voice": { - "description": "This is the voice for the workflow.\n\nThis can be overridden at node level using `nodes[n].voice`.", - "oneOf": [ - { - "$ref": "#/components/schemas/AzureVoice", - "title": "AzureVoice" - }, - { - "$ref": "#/components/schemas/CartesiaVoice", - "title": "CartesiaVoice" - }, - { - "$ref": "#/components/schemas/CustomVoice", - "title": "CustomVoice" - }, - { - "$ref": "#/components/schemas/DeepgramVoice", - "title": "DeepgramVoice" - }, - { - "$ref": "#/components/schemas/ElevenLabsVoice", - "title": "ElevenLabsVoice" - }, - { - "$ref": "#/components/schemas/HumeVoice", - "title": "HumeVoice" - }, - { - "$ref": "#/components/schemas/LMNTVoice", - "title": "LMNTVoice" - }, - { - "$ref": "#/components/schemas/NeuphonicVoice", - "title": "NeuphonicVoice" - }, - { - "$ref": "#/components/schemas/OpenAIVoice", - "title": "OpenAIVoice" - }, - { - "$ref": "#/components/schemas/PlayHTVoice", - "title": "PlayHTVoice" - }, - { - "$ref": "#/components/schemas/RimeAIVoice", - "title": "RimeAIVoice" - }, - { - "$ref": "#/components/schemas/SmallestAIVoice", - "title": "SmallestAIVoice" - }, - { - "$ref": "#/components/schemas/TavusVoice", - "title": "TavusVoice" - }, - { - "$ref": "#/components/schemas/VapiVoice", - "title": "VapiVoice" - }, - { - "$ref": "#/components/schemas/SesameVoice", - "title": "SesameVoice" - }, - { - "$ref": "#/components/schemas/InworldVoice", - "title": "InworldVoice" - }, - { - "$ref": "#/components/schemas/MinimaxVoice", - "title": "MinimaxVoice" - } - ] - }, - "observabilityPlan": { - "description": "This is the plan for observability of workflow's calls.\n\nCurrently, only Langfuse is supported.", - "oneOf": [ - { - "$ref": "#/components/schemas/LangfuseObservabilityPlan", - "title": "Langfuse" - } + "subType": { + "type": "string", + "enum": [ + "text_editor_20241022" ], + "description": "The sub type of tool." + }, + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", "allOf": [ { - "$ref": "#/components/schemas/LangfuseObservabilityPlan" + "$ref": "#/components/schemas/Server" } ] - }, - "backgroundSound": { - "description": "This is the background sound in the call. Default for phone calls is 'office' and default for web calls is 'off'.\nYou can also provide a custom sound by providing a URL to an audio file.", - "oneOf": [ - { - "type": "enum", - "enum": [ - "off", - "office" - ], - "example": "office" - }, + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ { - "type": "string", - "format": "uri", - "example": "https://www.soundjay.com/ambient/sounds/people-in-lounge-1.mp3" + "$ref": "#/components/schemas/ToolRejectionPlan" } ] }, - "hooks": { + "name": { + "type": "string", + "description": "The name of the tool, fixed to 'str_replace_editor'", + "default": "str_replace_editor", + "enum": [ + "str_replace_editor" + ] + } + } + }, + "UpdateQueryToolDTO": { + "type": "object", + "properties": { + "messages": { "type": "array", - "description": "This is a set of actions that will be performed on certain events.", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/CallHookCallEnding", - "title": "CallHookCallEnding" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CallHookAssistantSpeechInterrupted", - "title": "CallHookAssistantSpeechInterrupted" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CallHookCustomerSpeechInterrupted", - "title": "CallHookCustomerSpeechInterrupted" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CallHookCustomerSpeechTimeout", - "title": "CallHookCustomerSpeechTimeout" + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } ] } }, - "credentials": { + "knowledgeBases": { + "description": "The knowledge bases to query", "type": "array", - "description": "These are dynamic credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can supplement an additional credentials using this. Dynamic credentials override existing credentials.", + "items": { + "$ref": "#/components/schemas/KnowledgeBase" + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateGoogleCalendarCreateEventToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", "items": { "oneOf": [ { - "$ref": "#/components/schemas/CreateAnthropicCredentialDTO", - "title": "AnthropicCredential" - }, - { - "$ref": "#/components/schemas/CreateAnyscaleCredentialDTO", - "title": "AnyscaleCredential" - }, - { - "$ref": "#/components/schemas/CreateAssemblyAICredentialDTO", - "title": "AssemblyAICredential" - }, - { - "$ref": "#/components/schemas/CreateAzureCredentialDTO", - "title": "AzureCredential" - }, - { - "$ref": "#/components/schemas/CreateAzureOpenAICredentialDTO", - "title": "AzureOpenAICredential" - }, - { - "$ref": "#/components/schemas/CreateByoSipTrunkCredentialDTO", - "title": "ByoSipTrunkCredential" - }, - { - "$ref": "#/components/schemas/CreateCartesiaCredentialDTO", - "title": "CartesiaCredential" - }, - { - "$ref": "#/components/schemas/CreateCerebrasCredentialDTO", - "title": "CerebrasCredential" - }, - { - "$ref": "#/components/schemas/CreateCloudflareCredentialDTO", - "title": "CloudflareCredential" - }, - { - "$ref": "#/components/schemas/CreateCustomLLMCredentialDTO", - "title": "CustomLLMCredential" - }, - { - "$ref": "#/components/schemas/CreateDeepgramCredentialDTO", - "title": "DeepgramCredential" - }, - { - "$ref": "#/components/schemas/CreateDeepInfraCredentialDTO", - "title": "DeepInfraCredential" - }, - { - "$ref": "#/components/schemas/CreateDeepSeekCredentialDTO", - "title": "DeepSeekCredential" - }, - { - "$ref": "#/components/schemas/CreateElevenLabsCredentialDTO", - "title": "ElevenLabsCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateGcpCredentialDTO", - "title": "GcpCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateGladiaCredentialDTO", - "title": "GladiaCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateGoHighLevelCredentialDTO", - "title": "GhlCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateGoogleSheetsRowAppendToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateGoogleCredentialDTO", - "title": "GoogleCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateGroqCredentialDTO", - "title": "GroqCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateHumeCredentialDTO", - "title": "HumeCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateInflectionAICredentialDTO", - "title": "InflectionAICredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateGoogleCalendarCheckAvailabilityToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateLangfuseCredentialDTO", - "title": "LangfuseCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateLmntCredentialDTO", - "title": "LmntCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateMakeCredentialDTO", - "title": "MakeCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateMistralCredentialDTO", - "title": "MistralCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateSlackSendMessageToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateNeuphonicCredentialDTO", - "title": "NeuphonicCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateOpenAICredentialDTO", - "title": "OpenAICredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateOpenRouterCredentialDTO", - "title": "OpenRouterCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreatePerplexityAICredentialDTO", - "title": "PerplexityAICredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateSmsToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreatePlayHTCredentialDTO", - "title": "PlayHTCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateRimeAICredentialDTO", - "title": "RimeAICredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateRunpodCredentialDTO", - "title": "RunpodCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateS3CredentialDTO", - "title": "S3Credential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateMcpToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateSmallestAICredentialDTO", - "title": "SmallestAICredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateSpeechmaticsCredentialDTO", - "title": "SpeechmaticsCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateSupabaseCredentialDTO", - "title": "SupabaseCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateTavusCredentialDTO", - "title": "TavusCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "server": { + "description": "\n This is the server where a `tool-calls` webhook will be sent.\n\n Notes:\n - Webhook is sent to this server when a tool call is made.\n - Webhook contains the call, assistant, and phone number objects.\n - Webhook contains the variables set on the assistant.\n - Webhook is sent to the first available URL in this order: {{tool.server.url}}, {{assistant.server.url}}, {{phoneNumber.server.url}}, {{org.server.url}}.\n - Webhook expects a response with tool call result.", + "allOf": [ + { + "$ref": "#/components/schemas/Server" + } + ] + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + }, + "metadata": { + "$ref": "#/components/schemas/McpToolMetadata" + } + } + }, + "UpdateGoHighLevelCalendarAvailabilityToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateTogetherAICredentialDTO", - "title": "TogetherAICredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateTrieveCredentialDTO", - "title": "TrieveCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateTwilioCredentialDTO", - "title": "TwilioCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateVonageCredentialDTO", - "title": "VonageCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateGoHighLevelCalendarEventCreateToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateWebhookCredentialDTO", - "title": "WebhookCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateXAiCredentialDTO", - "title": "XAiCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", - "title": "GoogleCalendarOAuth2ClientCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", - "title": "GoogleCalendarOAuth2AuthorizationCredential" - }, + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "UpdateGoHighLevelContactCreateToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ { - "$ref": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", - "title": "GoogleSheetsOAuth2AuthorizationCredential" + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" }, { - "$ref": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", - "title": "SlackOAuth2AuthorizationCredential" + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" }, { - "$ref": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", - "title": "GoHighLevelMCPCredential" + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" }, { - "$ref": "#/components/schemas/CreateInworldCredentialDTO", - "title": "InworldCredential" - } - ], - "discriminator": { - "propertyName": "provider", - "mapping": { - "11labs": "#/components/schemas/CreateElevenLabsCredentialDTO", - "anthropic": "#/components/schemas/CreateAnthropicCredentialDTO", - "anyscale": "#/components/schemas/CreateAnyscaleCredentialDTO", - "assembly-ai": "#/components/schemas/CreateAssemblyAICredentialDTO", - "azure-openai": "#/components/schemas/CreateAzureOpenAICredentialDTO", - "azure": "#/components/schemas/CreateAzureCredentialDTO", - "byo-sip-trunk": "#/components/schemas/CreateByoSipTrunkCredentialDTO", - "cartesia": "#/components/schemas/CreateCartesiaCredentialDTO", - "cerebras": "#/components/schemas/CreateCerebrasCredentialDTO", - "cloudflare": "#/components/schemas/CreateCloudflareCredentialDTO", - "custom-llm": "#/components/schemas/CreateCustomLLMCredentialDTO", - "deepgram": "#/components/schemas/CreateDeepgramCredentialDTO", - "deepinfra": "#/components/schemas/CreateDeepInfraCredentialDTO", - "deep-seek": "#/components/schemas/CreateDeepSeekCredentialDTO", - "gcp": "#/components/schemas/CreateGcpCredentialDTO", - "gladia": "#/components/schemas/CreateGladiaCredentialDTO", - "gohighlevel": "#/components/schemas/CreateGoHighLevelCredentialDTO", - "google": "#/components/schemas/CreateGoogleCredentialDTO", - "groq": "#/components/schemas/CreateGroqCredentialDTO", - "inflection-ai": "#/components/schemas/CreateInflectionAICredentialDTO", - "langfuse": "#/components/schemas/CreateLangfuseCredentialDTO", - "lmnt": "#/components/schemas/CreateLmntCredentialDTO", - "make": "#/components/schemas/CreateMakeCredentialDTO", - "openai": "#/components/schemas/CreateOpenAICredentialDTO", - "openrouter": "#/components/schemas/CreateOpenRouterCredentialDTO", - "perplexity-ai": "#/components/schemas/CreatePerplexityAICredentialDTO", - "playht": "#/components/schemas/CreatePlayHTCredentialDTO", - "rime-ai": "#/components/schemas/CreateRimeAICredentialDTO", - "runpod": "#/components/schemas/CreateRunpodCredentialDTO", - "s3": "#/components/schemas/CreateS3CredentialDTO", - "supabase": "#/components/schemas/CreateSupabaseCredentialDTO", - "smallest-ai": "#/components/schemas/CreateSmallestAICredentialDTO", - "tavus": "#/components/schemas/CreateTavusCredentialDTO", - "together-ai": "#/components/schemas/CreateTogetherAICredentialDTO", - "twilio": "#/components/schemas/CreateTwilioCredentialDTO", - "vonage": "#/components/schemas/CreateVonageCredentialDTO", - "webhook": "#/components/schemas/CreateWebhookCredentialDTO", - "xai": "#/components/schemas/CreateXAiCredentialDTO", - "neuphonic": "#/components/schemas/CreateNeuphonicCredentialDTO", - "hume": "#/components/schemas/CreateHumeCredentialDTO", - "mistral": "#/components/schemas/CreateMistralCredentialDTO", - "speechmatics": "#/components/schemas/CreateSpeechmaticsCredentialDTO", - "trieve": "#/components/schemas/CreateTrieveCredentialDTO", - "google.calendar.oauth2-client": "#/components/schemas/CreateGoogleCalendarOAuth2ClientCredentialDTO", - "google.calendar.oauth2-authorization": "#/components/schemas/CreateGoogleCalendarOAuth2AuthorizationCredentialDTO", - "google.sheets.oauth2-authorization": "#/components/schemas/CreateGoogleSheetsOAuth2AuthorizationCredentialDTO", - "slack.oauth2-authorization": "#/components/schemas/CreateSlackOAuth2AuthorizationCredentialDTO", - "ghl.oauth2-authorization": "#/components/schemas/CreateGoHighLevelMCPCredentialDTO", - "inworld": "#/components/schemas/CreateInworldCredentialDTO", - "minimax": "#/components/schemas/CreateMinimaxCredentialDTO" + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" } + ] + } + }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" } + ] + } + } + }, + "UpdateGoHighLevelContactGetToolDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "These are the messages that will be spoken to the user as the tool is running.\n\nFor some tools, this is auto-filled based on special fields like `tool.destinations`. For others like the function tool, these can be custom configured.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ToolMessageStart", + "title": "ToolMessageStart" + }, + { + "$ref": "#/components/schemas/ToolMessageComplete", + "title": "ToolMessageComplete" + }, + { + "$ref": "#/components/schemas/ToolMessageFailed", + "title": "ToolMessageFailed" + }, + { + "$ref": "#/components/schemas/ToolMessageDelayed", + "title": "ToolMessageDelayed" + } + ] } }, + "rejectionPlan": { + "description": "This is the plan to reject a tool call based on the conversation state.\n\n// Example 1: Reject endCall if user didn't say goodbye\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '(?i)\\\\b(bye|goodbye|farewell|see you later|take care)\\\\b',\n target: { position: -1, role: 'user' },\n negate: true // Reject if pattern does NOT match\n }]\n}\n```\n\n// Example 2: Reject transfer if user is actually asking a question\n```json\n{\n conditions: [{\n type: 'regex',\n regex: '\\\\?',\n target: { position: -1, role: 'user' }\n }]\n}\n```\n\n// Example 3: Reject transfer if user didn't mention transfer recently\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 5 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' %}\n{% assign mentioned = false %}\n{% for msg in userMessages %}\n {% if msg.content contains 'transfer' or msg.content contains 'connect' or msg.content contains 'speak to' %}\n {% assign mentioned = true %}\n {% break %}\n {% endif %}\n{% endfor %}\n{% if mentioned %}\n false\n{% else %}\n true\n{% endif %}`\n }]\n}\n```\n\n// Example 4: Reject endCall if the bot is looping and trying to exit\n```json\n{\n conditions: [{\n type: 'liquid',\n liquid: `{% assign recentMessages = messages | last: 6 %}\n{% assign userMessages = recentMessages | where: 'role', 'user' | reverse %}\n{% if userMessages.size < 3 %}\n false\n{% else %}\n {% assign msg1 = userMessages[0].content | downcase %}\n {% assign msg2 = userMessages[1].content | downcase %}\n {% assign msg3 = userMessages[2].content | downcase %}\n {% comment %} Check for repetitive messages {% endcomment %}\n {% if msg1 == msg2 or msg1 == msg3 or msg2 == msg3 %}\n true\n {% comment %} Check for common loop phrases {% endcomment %}\n {% elsif msg1 contains 'cool thanks' or msg2 contains 'cool thanks' or msg3 contains 'cool thanks' %}\n true\n {% elsif msg1 contains 'okay thanks' or msg2 contains 'okay thanks' or msg3 contains 'okay thanks' %}\n true\n {% elsif msg1 contains 'got it' or msg2 contains 'got it' or msg3 contains 'got it' %}\n true\n {% else %}\n false\n {% endif %}\n{% endif %}`\n }]\n}\n```", + "allOf": [ + { + "$ref": "#/components/schemas/ToolRejectionPlan" + } + ] + } + } + }, + "CreateFileDTO": { + "type": "object", + "properties": { + "file": { + "type": "string", + "description": "This is the File you want to upload for use with the Knowledge Base.", + "format": "binary" + } + }, + "required": [ + "file" + ] + }, + "File": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "file" + ] + }, + "status": { + "enum": [ + "processing", + "done", + "failed" + ], + "type": "string" + }, "name": { "type": "string", - "maxLength": 80 + "description": "This is the name of the file. This is just for your own reference.", + "maxLength": 40 }, - "edges": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Edge" - } + "originalName": { + "type": "string" }, - "globalPrompt": { + "bytes": { + "type": "number" + }, + "purpose": { + "type": "string" + }, + "mimetype": { + "type": "string" + }, + "key": { + "type": "string" + }, + "path": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "url": { + "type": "string" + }, + "parsedTextUrl": { + "type": "string" + }, + "parsedTextBytes": { + "type": "number" + }, + "metadata": { + "type": "object" + }, + "id": { "type": "string", - "maxLength": 5000 + "description": "This is the unique identifier for the file." }, - "server": { - "description": "This is where Vapi will send webhooks. You can find all webhooks available along with their shape in ServerMessage schema.\n\nThe order of precedence is:\n\n1. tool.server\n2. workflow.server / assistant.server\n3. phoneNumber.server\n4. org.server", + "orgId": { + "type": "string", + "description": "This is the unique identifier for the org that this file belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the file was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the file was last updated." + } + }, + "required": [ + "id", + "orgId", + "createdAt", + "updatedAt" + ] + }, + "UpdateFileDTO": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This is the name of the file. This is just for your own reference.", + "minLength": 1, + "maxLength": 40 + } + } + }, + "TrieveKnowledgeBaseSearchPlan": { + "type": "object", + "properties": { + "topK": { + "type": "number", + "description": "Specifies the number of top chunks to return. This corresponds to the `page_size` parameter in Trieve." + }, + "removeStopWords": { + "type": "boolean", + "description": "If true, stop words (specified in server/src/stop-words.txt in the git repo) will be removed. This will preserve queries that are entirely stop words." + }, + "scoreThreshold": { + "type": "number", + "description": "This is the score threshold to filter out chunks with a score below the threshold for cosine distance metric. For Manhattan Distance, Euclidean Distance, and Dot Product, it will filter out scores above the threshold distance. This threshold applies before weight and bias modifications. If not specified, this defaults to no threshold. A threshold of 0 will default to no threshold." + }, + "searchType": { + "type": "string", + "description": "This is the search method used when searching for relevant chunks from the vector store.", + "enum": [ + "fulltext", + "semantic", + "hybrid", + "bm25" + ] + } + }, + "required": [ + "searchType" + ] + }, + "TrieveKnowledgeBase": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This knowledge base is provided by Trieve.\n\nTo learn more about Trieve, visit https://trieve.ai.", + "enum": [ + "trieve" + ] + }, + "name": { + "type": "string", + "description": "This is the name of the knowledge base." + }, + "searchPlan": { + "description": "This is the searching plan used when searching for relevant chunks from the vector store.\n\nYou should configure this if you're running into these issues:\n- Too much unnecessary context is being fed as knowledge base context.\n- Not enough relevant context is being fed as knowledge base context.", "allOf": [ { - "$ref": "#/components/schemas/Server" + "$ref": "#/components/schemas/TrieveKnowledgeBaseSearchPlan" } ] }, - "compliancePlan": { - "description": "This is the compliance plan for the workflow. It allows you to configure HIPAA and other compliance settings.", - "allOf": [ + "createPlan": { + "description": "This is the plan if you want us to create/import a new vector store using Trieve.", + "oneOf": [ { - "$ref": "#/components/schemas/CompliancePlan" + "$ref": "#/components/schemas/TrieveKnowledgeBaseImport", + "title": "Import" } ] }, - "analysisPlan": { - "description": "This is the plan for analysis of workflow's calls. Stored in `call.analysis`.", + "id": { + "type": "string", + "description": "This is the id of the knowledge base." + }, + "orgId": { + "type": "string", + "description": "This is the org id of the knowledge base." + } + }, + "required": [ + "provider", + "id", + "orgId" + ] + }, + "CustomKnowledgeBase": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This knowledge base is bring your own knowledge base implementation.", + "enum": [ + "custom-knowledge-base" + ] + }, + "server": { + "description": "This is where the knowledge base request will be sent.\n\nRequest Example:\n\nPOST https://{server.url}\nContent-Type: application/json\n\n{\n \"messsage\": {\n \"type\": \"knowledge-base-request\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Why is ocean blue?\"\n }\n ],\n ...other metadata about the call...\n }\n}\n\nResponse Expected:\n```\n{\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"The ocean is blue because water absorbs everything but blue.\",\n }, // YOU CAN RETURN THE EXACT RESPONSE TO SPEAK\n \"documents\": [\n {\n \"content\": \"The ocean is blue primarily because water absorbs colors in the red part of the light spectrum and scatters the blue light, making it more visible to our eyes.\",\n \"similarity\": 1\n },\n {\n \"content\": \"Blue light is scattered more by the water molecules than other colors, enhancing the blue appearance of the ocean.\",\n \"similarity\": .5\n }\n ] // OR, YOU CAN RETURN AN ARRAY OF DOCUMENTS THAT WILL BE SENT TO THE MODEL\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/AnalysisPlan" + "$ref": "#/components/schemas/Server" } ] }, - "artifactPlan": { - "description": "This is the plan for artifacts generated during workflow's calls. Stored in `call.artifact`.", + "id": { + "type": "string", + "description": "This is the id of the knowledge base." + }, + "orgId": { + "type": "string", + "description": "This is the org id of the knowledge base." + } + }, + "required": [ + "provider", + "server", + "id", + "orgId" + ] + }, + "CreateTrieveKnowledgeBaseDTO": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This knowledge base is provided by Trieve.\n\nTo learn more about Trieve, visit https://trieve.ai.", + "enum": [ + "trieve" + ] + }, + "name": { + "type": "string", + "description": "This is the name of the knowledge base." + }, + "searchPlan": { + "description": "This is the searching plan used when searching for relevant chunks from the vector store.\n\nYou should configure this if you're running into these issues:\n- Too much unnecessary context is being fed as knowledge base context.\n- Not enough relevant context is being fed as knowledge base context.", "allOf": [ { - "$ref": "#/components/schemas/ArtifactPlan" + "$ref": "#/components/schemas/TrieveKnowledgeBaseSearchPlan" } ] }, - "startSpeakingPlan": { - "description": "This is the plan for when the workflow nodes should start talking.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to start talking after the customer is done speaking.\n- The assistant is too fast to start talking after the customer is done speaking.\n- The assistant is so fast that it's actually interrupting the customer.", - "allOf": [ + "createPlan": { + "description": "This is the plan if you want us to create/import a new vector store using Trieve.", + "oneOf": [ { - "$ref": "#/components/schemas/StartSpeakingPlan" + "$ref": "#/components/schemas/TrieveKnowledgeBaseImport", + "title": "Import" } ] + } + }, + "required": [ + "provider" + ] + }, + "UpdateTrieveKnowledgeBaseDTO": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This is the name of the knowledge base." }, - "stopSpeakingPlan": { - "description": "This is the plan for when workflow nodes should stop talking on customer interruption.\n\nYou should configure this if you're running into these issues:\n- The assistant is too slow to recognize customer's interruption.\n- The assistant is too fast to recognize customer's interruption.\n- The assistant is getting interrupted by phrases that are just acknowledgments.\n- The assistant is getting interrupted by background noises.\n- The assistant is not properly stopping -- it starts talking right after getting interrupted.", + "searchPlan": { + "description": "This is the searching plan used when searching for relevant chunks from the vector store.\n\nYou should configure this if you're running into these issues:\n- Too much unnecessary context is being fed as knowledge base context.\n- Not enough relevant context is being fed as knowledge base context.", "allOf": [ { - "$ref": "#/components/schemas/StopSpeakingPlan" + "$ref": "#/components/schemas/TrieveKnowledgeBaseSearchPlan" } ] }, - "monitorPlan": { - "description": "This is the plan for real-time monitoring of the workflow's calls.\n\nUsage:\n- To enable live listening of the workflow's calls, set `monitorPlan.listenEnabled` to `true`.\n- To enable live control of the workflow's calls, set `monitorPlan.controlEnabled` to `true`.", + "createPlan": { + "description": "This is the plan if you want us to create/import a new vector store using Trieve.", + "oneOf": [ + { + "$ref": "#/components/schemas/TrieveKnowledgeBaseImport", + "title": "Import" + } + ] + } + } + }, + "UpdateCustomKnowledgeBaseDTO": { + "type": "object", + "properties": { + "server": { + "description": "This is where the knowledge base request will be sent.\n\nRequest Example:\n\nPOST https://{server.url}\nContent-Type: application/json\n\n{\n \"messsage\": {\n \"type\": \"knowledge-base-request\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"Why is ocean blue?\"\n }\n ],\n ...other metadata about the call...\n }\n}\n\nResponse Expected:\n```\n{\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"The ocean is blue because water absorbs everything but blue.\",\n }, // YOU CAN RETURN THE EXACT RESPONSE TO SPEAK\n \"documents\": [\n {\n \"content\": \"The ocean is blue primarily because water absorbs colors in the red part of the light spectrum and scatters the blue light, making it more visible to our eyes.\",\n \"similarity\": 1\n },\n {\n \"content\": \"Blue light is scattered more by the water molecules than other colors, enhancing the blue appearance of the ocean.\",\n \"similarity\": .5\n }\n ] // OR, YOU CAN RETURN AN ARRAY OF DOCUMENTS THAT WILL BE SENT TO THE MODEL\n}\n```", "allOf": [ { - "$ref": "#/components/schemas/MonitorPlan" + "$ref": "#/components/schemas/Server" } ] + } + } + }, + "TrieveKnowledgeBaseChunkPlan": { + "type": "object", + "properties": { + "fileIds": { + "description": "These are the file ids that will be used to create the vector store. To upload files, use the `POST /files` endpoint.", + "type": "array", + "items": { + "type": "string" + } }, - "backgroundSpeechDenoisingPlan": { - "description": "This enables filtering of noise and background speech while the user is talking.\n\nFeatures:\n- Smart denoising using Krisp\n- Fourier denoising\n\nBoth can be used together. Order of precedence:\n- Smart denoising\n- Fourier denoising", - "allOf": [ + "websites": { + "description": "These are the websites that will be used to create the vector store.", + "type": "array", + "items": { + "type": "string" + } + }, + "targetSplitsPerChunk": { + "type": "number", + "description": "This is an optional field which allows you to specify the number of splits you want per chunk. If not specified, the default 20 is used. However, you may want to use a different number." + }, + "splitDelimiters": { + "description": "This is an optional field which allows you to specify the delimiters to use when splitting the file before chunking the text. If not specified, the default [.!?\\n] are used to split into sentences. However, you may want to use spaces or other delimiters.", + "type": "array", + "items": { + "type": "string" + } + }, + "rebalanceChunks": { + "type": "boolean", + "description": "This is an optional field which allows you to specify whether or not to rebalance the chunks created from the file. If not specified, the default true is used. If true, Trieve will evenly distribute remainder splits across chunks such that 66 splits with a target_splits_per_chunk of 20 will result in 3 chunks with 22 splits each." + } + } + }, + "TrieveKnowledgeBaseCreate": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "This is to create a new dataset on Trieve.", + "enum": [ + "create" + ] + }, + "chunkPlans": { + "description": "These are the chunk plans used to create the dataset.", + "type": "array", + "items": { + "$ref": "#/components/schemas/TrieveKnowledgeBaseChunkPlan" + } + } + }, + "required": [ + "type", + "chunkPlans" + ] + }, + "TrieveKnowledgeBaseImport": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "This is to import an existing dataset from Trieve.", + "enum": [ + "import" + ] + }, + "providerId": { + "type": "string", + "description": "This is the `datasetId` of the dataset on your Trieve account." + } + }, + "required": [ + "type", + "providerId" + ] + }, + "StructuredOutput": { + "type": "object", + "properties": { + "model": { + "description": "This is the model that will be used to extract the structured output.\n\nTo provide your own custom system and user prompts for structured output extraction, populate the messages array with your system and user messages. You can specify liquid templating in your system and user messages.\nBetween the system or user messages, you must reference either 'transcript' or 'messages' with the '{{}}' syntax to access the conversation history.\nBetween the system or user messages, you must reference a variation of the structured output with the '{{}}' syntax to access the structured output definition.\ni.e.:\n{{structuredOutput}}\n{{structuredOutput.name}}\n{{structuredOutput.description}}\n{{structuredOutput.schema}}\n\nIf model is not specified, GPT-4.1 will be used by default for extraction, utilizing default system and user prompts.\nIf messages or required fields are not specified, the default system and user prompts will be used.", + "oneOf": [ { - "$ref": "#/components/schemas/BackgroundSpeechDenoisingPlan" + "$ref": "#/components/schemas/WorkflowOpenAIModel", + "title": "WorkflowOpenAIModel" + }, + { + "$ref": "#/components/schemas/WorkflowAnthropicModel", + "title": "WorkflowAnthropicModel" + }, + { + "$ref": "#/components/schemas/WorkflowGoogleModel", + "title": "WorkflowGoogleModel" + }, + { + "$ref": "#/components/schemas/WorkflowCustomModel", + "title": "WorkflowCustomModel" } ] }, - "credentialIds": { - "description": "These are the credentials that will be used for the workflow calls. By default, all the credentials are available for use in the call but you can provide a subset using this.", + "id": { + "type": "string", + "description": "This is the unique identifier for the structured output." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the org that this structured output belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the structured output was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the structured output was last updated." + }, + "name": { + "type": "string", + "description": "This is the name of the structured output.", + "minLength": 1, + "maxLength": 40 + }, + "description": { + "type": "string", + "description": "This is the description of what the structured output extracts.\n\nUse this to provide context about what data will be extracted and how it will be used." + }, + "assistantIds": { + "description": "These are the assistant IDs that this structured output is linked to.\n\nWhen linked to assistants, this structured output will be available for extraction during those assistant's calls.", "type": "array", "items": { "type": "string" } }, - "keypadInputPlan": { - "description": "This is the plan for keypad input handling during workflow calls.", + "workflowIds": { + "description": "These are the workflow IDs that this structured output is linked to.\n\nWhen linked to workflows, this structured output will be available for extraction during those workflow's execution.", + "type": "array", + "items": { + "type": "string" + } + }, + "schema": { + "description": "This is the JSON Schema definition for the structured output.\n\nDefines the structure and validation rules for the data that will be extracted. Supports all JSON Schema features including:\n- Objects and nested properties\n- Arrays and array validation\n- String, number, boolean, and null types\n- Enums and const values\n- Validation constraints (min/max, patterns, etc.)\n- Composition with allOf, anyOf, oneOf", "allOf": [ { - "$ref": "#/components/schemas/KeypadInputPlan" + "$ref": "#/components/schemas/JsonSchema" + } + ] + } + }, + "required": [ + "id", + "orgId", + "createdAt", + "updatedAt", + "name", + "schema" + ] + }, + "StructuredOutputPaginatedResponse": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/StructuredOutput" + } + }, + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" + } + }, + "required": [ + "results", + "metadata" + ] + }, + "CreateStructuredOutputDTO": { + "type": "object", + "properties": { + "model": { + "description": "This is the model that will be used to extract the structured output.\n\nTo provide your own custom system and user prompts for structured output extraction, populate the messages array with your system and user messages. You can specify liquid templating in your system and user messages.\nBetween the system or user messages, you must reference either 'transcript' or 'messages' with the '{{}}' syntax to access the conversation history.\nBetween the system or user messages, you must reference a variation of the structured output with the '{{}}' syntax to access the structured output definition.\ni.e.:\n{{structuredOutput}}\n{{structuredOutput.name}}\n{{structuredOutput.description}}\n{{structuredOutput.schema}}\n\nIf model is not specified, GPT-4.1 will be used by default for extraction, utilizing default system and user prompts.\nIf messages or required fields are not specified, the default system and user prompts will be used.", + "oneOf": [ + { + "$ref": "#/components/schemas/WorkflowOpenAIModel", + "title": "WorkflowOpenAIModel" + }, + { + "$ref": "#/components/schemas/WorkflowAnthropicModel", + "title": "WorkflowAnthropicModel" + }, + { + "$ref": "#/components/schemas/WorkflowGoogleModel", + "title": "WorkflowGoogleModel" + }, + { + "$ref": "#/components/schemas/WorkflowCustomModel", + "title": "WorkflowCustomModel" } ] - } - } - }, - "Squad": { - "type": "object", - "properties": { + }, "name": { "type": "string", - "description": "This is the name of the squad." - }, - "members": { - "description": "This is the list of assistants that make up the squad.\n\nThe call will start with the first assistant in the list.", - "type": "array", - "items": { - "$ref": "#/components/schemas/SquadMemberDTO" - } + "description": "This is the name of the structured output.", + "minLength": 1, + "maxLength": 40 }, - "membersOverrides": { - "description": "This can be used to override all the assistants' settings and provide values for their template variables.\n\nBoth `membersOverrides` and `members[n].assistantOverrides` can be used together. First, `members[n].assistantOverrides` is applied. Then, `membersOverrides` is applied as a global override.", + "schema": { + "description": "This is the JSON Schema definition for the structured output.\n\nThis is required when creating a structured output. Defines the structure and validation rules for the data that will be extracted. Supports all JSON Schema features including:\n- Objects and nested properties\n- Arrays and array validation\n- String, number, boolean, and null types\n- Enums and const values\n- Validation constraints (min/max, patterns, etc.)\n- Composition with allOf, anyOf, oneOf", "allOf": [ { - "$ref": "#/components/schemas/AssistantOverrides" + "$ref": "#/components/schemas/JsonSchema" } ] }, - "id": { - "type": "string", - "description": "This is the unique identifier for the squad." - }, - "orgId": { + "description": { "type": "string", - "description": "This is the unique identifier for the org that this squad belongs to." + "description": "This is the description of what the structured output extracts.\n\nUse this to provide context about what data will be extracted and how it will be used." }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the squad was created." + "assistantIds": { + "description": "These are the assistant IDs that this structured output is linked to.\n\nWhen linked to assistants, this structured output will be available for extraction during those assistant's calls.", + "type": "array", + "items": { + "type": "string" + } }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the squad was last updated." + "workflowIds": { + "description": "These are the workflow IDs that this structured output is linked to.\n\nWhen linked to workflows, this structured output will be available for extraction during those workflow's execution.", + "type": "array", + "items": { + "type": "string" + } } }, "required": [ - "members", - "id", - "orgId", - "createdAt", - "updatedAt" + "name", + "schema" ] }, - "UpdateSquadDTO": { + "UpdateStructuredOutputDTO": { "type": "object", "properties": { + "model": { + "description": "This is the model that will be used to extract the structured output.\n\nTo provide your own custom system and user prompts for structured output extraction, populate the messages array with your system and user messages. You can specify liquid templating in your system and user messages.\nBetween the system or user messages, you must reference either 'transcript' or 'messages' with the '{{}}' syntax to access the conversation history.\nBetween the system or user messages, you must reference a variation of the structured output with the '{{}}' syntax to access the structured output definition.\ni.e.:\n{{structuredOutput}}\n{{structuredOutput.name}}\n{{structuredOutput.description}}\n{{structuredOutput.schema}}\n\nIf model is not specified, GPT-4.1 will be used by default for extraction, utilizing default system and user prompts.\nIf messages or required fields are not specified, the default system and user prompts will be used.", + "oneOf": [ + { + "$ref": "#/components/schemas/WorkflowOpenAIModel", + "title": "WorkflowOpenAIModel" + }, + { + "$ref": "#/components/schemas/WorkflowAnthropicModel", + "title": "WorkflowAnthropicModel" + }, + { + "$ref": "#/components/schemas/WorkflowGoogleModel", + "title": "WorkflowGoogleModel" + }, + { + "$ref": "#/components/schemas/WorkflowCustomModel", + "title": "WorkflowCustomModel" + } + ] + }, "name": { "type": "string", - "description": "This is the name of the squad." + "description": "This is the name of the structured output.", + "minLength": 1, + "maxLength": 40 }, - "members": { - "description": "This is the list of assistants that make up the squad.\n\nThe call will start with the first assistant in the list.", + "description": { + "type": "string", + "description": "This is the description of what the structured output extracts.\n\nUse this to provide context about what data will be extracted and how it will be used." + }, + "assistantIds": { + "description": "These are the assistant IDs that this structured output is linked to.\n\nWhen linked to assistants, this structured output will be available for extraction during those assistant's calls.", "type": "array", "items": { - "$ref": "#/components/schemas/SquadMemberDTO" + "type": "string" } }, - "membersOverrides": { - "description": "This can be used to override all the assistants' settings and provide values for their template variables.\n\nBoth `membersOverrides` and `members[n].assistantOverrides` can be used together. First, `members[n].assistantOverrides` is applied. Then, `membersOverrides` is applied as a global override.", + "workflowIds": { + "description": "These are the workflow IDs that this structured output is linked to.\n\nWhen linked to workflows, this structured output will be available for extraction during those workflow's execution.", + "type": "array", + "items": { + "type": "string" + } + }, + "schema": { + "description": "This is the JSON Schema definition for the structured output.\n\nDefines the structure and validation rules for the data that will be extracted. Supports all JSON Schema features including:\n- Objects and nested properties\n- Arrays and array validation\n- String, number, boolean, and null types\n- Enums and const values\n- Validation constraints (min/max, patterns, etc.)\n- Composition with allOf, anyOf, oneOf", "allOf": [ { - "$ref": "#/components/schemas/AssistantOverrides" + "$ref": "#/components/schemas/JsonSchema" } ] } - }, - "required": [ - "members" - ] + } }, "TesterPlan": { "type": "object", @@ -38544,781 +36888,244 @@ ], "maxLength": 100 }, - "rubric": { - "type": "string", - "description": "This is the rubric used by the AI scorer.", - "maxLength": 10000 - } - }, - "required": [ - "type", - "rubric" - ] - }, - "TestSuiteTestsPaginatedResponse": { - "type": "object", - "properties": { - "results": { - "type": "array", - "description": "A list of test suite tests.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteTestVoice" - }, - { - "$ref": "#/components/schemas/TestSuiteTestChat" - } - ] - } - }, - "metadata": { - "description": "Metadata about the pagination.", - "allOf": [ - { - "$ref": "#/components/schemas/PaginationMeta" - } - ] - } - }, - "required": [ - "results", - "metadata" - ] - }, - "TestSuiteRunScorerAI": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "This is the type of the scorer, which must be AI.", - "enum": [ - "ai" - ], - "maxLength": 100 - }, - "result": { - "type": "string", - "description": "This is the result of the test suite.", - "enum": [ - "pass", - "fail" - ], - "maxLength": 100 - }, - "reasoning": { - "type": "string", - "description": "This is the reasoning provided by the AI scorer.", - "maxLength": 10000 - }, - "rubric": { - "type": "string", - "description": "This is the rubric used by the AI scorer.", - "maxLength": 10000 - } - }, - "required": [ - "type", - "result", - "reasoning", - "rubric" - ] - }, - "TestSuiteRunTestAttemptCall": { - "type": "object", - "properties": { - "artifact": { - "description": "This is the artifact of the call.", - "allOf": [ - { - "$ref": "#/components/schemas/Artifact" - } - ] - } - }, - "required": [ - "artifact" - ] - }, - "TestSuiteRunTestAttemptMetadata": { - "type": "object", - "properties": { - "sessionId": { - "type": "string", - "description": "This is the session ID for the test attempt." - } - }, - "required": [ - "sessionId" - ] - }, - "TestSuiteRunTestAttempt": { - "type": "object", - "properties": { - "scorerResults": { - "type": "array", - "description": "These are the results of the scorers used to evaluate the test attempt.", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteRunScorerAI", - "title": "AI" - } - ] - } - }, - "call": { - "description": "This is the call made during the test attempt.", - "allOf": [ - { - "$ref": "#/components/schemas/TestSuiteRunTestAttemptCall" - } - ] - }, - "callId": { - "type": "string", - "description": "This is the call ID for the test attempt." - }, - "metadata": { - "description": "This is the metadata for the test attempt.", - "allOf": [ - { - "$ref": "#/components/schemas/TestSuiteRunTestAttemptMetadata" - } - ] - } - }, - "required": [ - "scorerResults" - ] - }, - "TestSuiteRunTestResult": { - "type": "object", - "properties": { - "test": { - "description": "This is the test that was run.", - "oneOf": [ - { - "$ref": "#/components/schemas/TestSuiteTestVoice", - "title": "TestSuiteTestVoice" - } - ] - }, - "attempts": { - "description": "These are the attempts made for this test.", - "type": "array", - "items": { - "$ref": "#/components/schemas/TestSuiteRunTestAttempt" - } - } - }, - "required": [ - "test", - "attempts" - ] - }, - "TestSuiteRun": { - "type": "object", - "properties": { - "status": { - "type": "string", - "description": "This is the current status of the test suite run.", - "enum": [ - "queued", - "in-progress", - "completed", - "failed" - ] - }, - "id": { - "type": "string", - "description": "This is the unique identifier for the test suite run." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the organization this run belongs to." - }, - "testSuiteId": { - "type": "string", - "description": "This is the unique identifier for the test suite this run belongs to." - }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the test suite run was created." - }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "This is the ISO 8601 date-time string of when the test suite run was last updated." - }, - "testResults": { - "description": "These are the results of the tests in this test suite run.", - "type": "array", - "items": { - "$ref": "#/components/schemas/TestSuiteRunTestResult" - } - }, - "name": { - "type": "string", - "description": "This is the name of the test suite run.", - "maxLength": 80 - } - }, - "required": [ - "status", - "id", - "orgId", - "testSuiteId", - "createdAt", - "updatedAt", - "testResults" - ] - }, - "TestSuiteRunsPaginatedResponse": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TestSuiteRun" - } - }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" - } - }, - "required": [ - "results", - "metadata" - ] - }, - "CreateTestSuiteRunDto": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the name of the test suite run.", - "maxLength": 80 - } - } - }, - "UpdateTestSuiteRunDto": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the name of the test suite run.", - "maxLength": 80 - } - } - }, - "TimeRange": { - "type": "object", - "properties": { - "step": { - "type": "string", - "description": "This is the time step for aggregations.\n\nIf not provided, defaults to returning for the entire time range.", - "enum": [ - "second", - "minute", - "hour", - "day", - "week", - "month", - "quarter", - "year", - "decade", - "century", - "millennium" - ] - }, - "start": { - "format": "date-time", - "type": "string", - "description": "This is the start date for the time range.\n\nIf not provided, defaults to the 7 days ago." - }, - "end": { - "format": "date-time", - "type": "string", - "description": "This is the end date for the time range.\n\nIf not provided, defaults to now." - }, - "timezone": { - "type": "string", - "description": "This is the timezone you want to set for the query.\n\nIf not provided, defaults to UTC." - } - } - }, - "AnalyticsOperation": { - "type": "object", - "properties": { - "operation": { - "type": "string", - "description": "This is the aggregation operation you want to perform.", - "enum": [ - "sum", - "avg", - "count", - "min", - "max", - "history" - ] - }, - "column": { - "type": "string", - "description": "This is the columns you want to perform the aggregation operation on.", - "enum": [ - "id", - "cost", - "costBreakdown.llm", - "costBreakdown.stt", - "costBreakdown.tts", - "costBreakdown.vapi", - "costBreakdown.transport", - "costBreakdown.analysisBreakdown.summary", - "costBreakdown.transcriber", - "costBreakdown.ttsCharacters", - "costBreakdown.llmPromptTokens", - "costBreakdown.llmCompletionTokens", - "duration", - "concurrency", - "minutesUsed" - ] - }, - "alias": { - "type": "string", - "description": "This is the alias for column name returned. Defaults to `${operation}${column}`.", - "maxLength": 40 - } - }, - "required": [ - "operation", - "column" - ] - }, - "AnalyticsQuery": { - "type": "object", - "properties": { - "table": { - "type": "string", - "description": "This is the table you want to query.", - "enum": [ - "call", - "subscription" - ] - }, - "groupBy": { - "type": "array", - "description": "This is the list of columns you want to group by.", - "enum": [ - "type", - "assistantId", - "endedReason", - "analysis.successEvaluation", - "status" - ], - "items": { - "type": "string", - "enum": [ - "type", - "assistantId", - "endedReason", - "analysis.successEvaluation", - "status" - ] - } - }, - "name": { + "rubric": { "type": "string", - "description": "This is the name of the query. This will be used to identify the query in the response.", - "maxLength": 40 - }, - "timeRange": { - "description": "This is the time range for the query.", - "allOf": [ - { - "$ref": "#/components/schemas/TimeRange" - } - ] - }, - "operations": { - "description": "This is the list of operations you want to perform.", - "type": "array", - "items": { - "$ref": "#/components/schemas/AnalyticsOperation" - } + "description": "This is the rubric used by the AI scorer.", + "maxLength": 10000 } }, "required": [ - "table", - "name", - "operations" + "type", + "rubric" ] }, - "AnalyticsQueryDTO": { + "TestSuiteTestsPaginatedResponse": { "type": "object", "properties": { - "queries": { - "description": "This is the list of metric queries you want to perform.", + "results": { "type": "array", + "description": "A list of test suite tests.", "items": { - "$ref": "#/components/schemas/AnalyticsQuery" + "oneOf": [ + { + "$ref": "#/components/schemas/TestSuiteTestVoice" + }, + { + "$ref": "#/components/schemas/TestSuiteTestChat" + } + ] } - } - }, - "required": [ - "queries" - ] - }, - "AnalyticsQueryResult": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "This is the unique key for the query." }, - "timeRange": { - "description": "This is the time range for the query.", + "metadata": { + "description": "Metadata about the pagination.", "allOf": [ { - "$ref": "#/components/schemas/TimeRange" + "$ref": "#/components/schemas/PaginationMeta" } ] - }, - "result": { - "description": "This is the result of the query, a list of unique groups with result of their aggregations.\n\nExample:\n\"result\": [\n { \"date\": \"2023-01-01\", \"assistantId\": \"123\", \"endedReason\": \"customer-ended-call\", \"sumDuration\": 120, \"avgCost\": 10.5 },\n { \"date\": \"2023-01-02\", \"assistantId\": \"123\", \"endedReason\": \"customer-did-not-give-microphone-permission\", \"sumDuration\": 0, \"avgCost\": 0 },\n // Additional results\n]", - "type": "array", - "items": { - "type": "object" - } } }, "required": [ - "name", - "timeRange", - "result" + "results", + "metadata" ] }, - "CallLogPrivileged": { + "TestSuiteRunScorerAI": { "type": "object", "properties": { - "callId": { - "type": "string", - "description": "This is the unique identifier for the call." - }, - "orgId": { + "type": { "type": "string", - "description": "This is the unique identifier for the org that this call log belongs to." + "description": "This is the type of the scorer, which must be AI.", + "enum": [ + "ai" + ], + "maxLength": 100 }, - "log": { + "result": { "type": "string", - "description": "This is the log message associated with the call." + "description": "This is the result of the test suite.", + "enum": [ + "pass", + "fail" + ], + "maxLength": 100 }, - "level": { + "reasoning": { "type": "string", - "description": "This is the level of the log message.", - "enum": [ - "INFO", - "LOG", - "WARN", - "ERROR", - "CHECKPOINT" - ] + "description": "This is the reasoning provided by the AI scorer.", + "maxLength": 10000 }, - "time": { - "format": "date-time", + "rubric": { "type": "string", - "description": "This is the ISO 8601 date-time string of when the log was created." + "description": "This is the rubric used by the AI scorer.", + "maxLength": 10000 } }, "required": [ - "callId", - "orgId", - "log", - "level", - "time" + "type", + "result", + "reasoning", + "rubric" ] }, - "CallLogsPaginatedResponse": { + "TestSuiteRunTestAttemptCall": { "type": "object", "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CallLogPrivileged" - } - }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" + "artifact": { + "description": "This is the artifact of the call.", + "allOf": [ + { + "$ref": "#/components/schemas/Artifact" + } + ] } }, "required": [ - "results", - "metadata" + "artifact" ] }, - "Error": { + "TestSuiteRunTestAttemptMetadata": { "type": "object", "properties": { - "message": { - "type": "string" + "sessionId": { + "type": "string", + "description": "This is the session ID for the test attempt." } }, "required": [ - "message" + "sessionId" ] }, - "Log": { + "TestSuiteRunTestAttempt": { "type": "object", "properties": { - "time": { - "type": "string", - "description": "This is the timestamp at which the log was written." - }, - "orgId": { - "type": "string", - "description": "This is the unique identifier for the org that this log belongs to." - }, - "type": { - "type": "string", - "description": "This is the type of the log.", - "enum": [ - "API", - "Webhook", - "Call", - "Provider" - ] - }, - "webhookType": { - "type": "string", - "description": "This is the type of the webhook, given the log is from a webhook." - }, - "resource": { - "type": "string", - "description": "This is the specific resource, relevant only to API logs.", - "enum": [ - "org", - "assistant", - "analytics", - "credential", - "phone-number", - "block", - "voice-library", - "provider", - "tool", - "token", - "template", - "squad", - "call", - "file", - "metric", - "log" - ] - }, - "requestDurationSeconds": { - "type": "number", - "description": "'This is how long the request took.", - "minimum": 0 - }, - "requestStartedAt": { - "type": "string", - "description": "This is the timestamp at which the request began." - }, - "requestFinishedAt": { - "type": "string", - "description": "This is the timestamp at which the request finished." - }, - "requestBody": { - "type": "object", - "description": "This is the body of the request." + "scorerResults": { + "type": "array", + "description": "These are the results of the scorers used to evaluate the test attempt.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/TestSuiteRunScorerAI", + "title": "AI" + } + ] + } }, - "requestHttpMethod": { - "type": "string", - "description": "This is the request method.", - "enum": [ - "POST", - "GET", - "PUT", - "PATCH", - "DELETE" + "call": { + "description": "This is the call made during the test attempt.", + "allOf": [ + { + "$ref": "#/components/schemas/TestSuiteRunTestAttemptCall" + } ] }, - "requestUrl": { - "type": "string", - "description": "This is the request URL." - }, - "requestPath": { - "type": "string", - "description": "This is the request path." - }, - "requestQuery": { - "type": "string", - "description": "This is the request query." - }, - "responseHttpCode": { - "type": "number", - "description": "This the HTTP status code of the response." - }, - "requestIpAddress": { - "type": "string", - "description": "This is the request IP address." - }, - "requestOrigin": { + "callId": { "type": "string", - "description": "This is the origin of the request" - }, - "responseBody": { - "type": "object", - "description": "This is the body of the response." - }, - "requestHeaders": { - "type": "object", - "description": "These are the headers of the request." + "description": "This is the call ID for the test attempt." }, - "error": { - "description": "This is the error, if one occurred.", + "metadata": { + "description": "This is the metadata for the test attempt.", "allOf": [ { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/TestSuiteRunTestAttemptMetadata" } ] - }, - "assistantId": { - "type": "string", - "description": "This is the ID of the assistant." - }, - "phoneNumberId": { - "type": "string", - "description": "This is the ID of the phone number." - }, - "customerId": { - "type": "string", - "description": "This is the ID of the customer." - }, - "squadId": { - "type": "string", - "description": "This is the ID of the squad." - }, - "callId": { - "type": "string", - "description": "This is the ID of the call." } }, "required": [ - "time", - "orgId", - "type" + "scorerResults" ] }, - "LogsPaginatedResponse": { + "TestSuiteRunTestResult": { "type": "object", "properties": { - "results": { + "test": { + "description": "This is the test that was run.", + "oneOf": [ + { + "$ref": "#/components/schemas/TestSuiteTestVoice", + "title": "TestSuiteTestVoice" + } + ] + }, + "attempts": { + "description": "These are the attempts made for this test.", "type": "array", "items": { - "$ref": "#/components/schemas/Log" + "$ref": "#/components/schemas/TestSuiteRunTestAttempt" } - }, - "metadata": { - "$ref": "#/components/schemas/PaginationMeta" } }, "required": [ - "results", - "metadata" + "test", + "attempts" ] }, - "StructuredOutput": { + "TestSuiteRun": { "type": "object", "properties": { - "model": { - "description": "This is the model that will be used to extract the structured output.\n\nTo provide your own custom system and user prompts for structured output extraction, populate the messages array with your system and user messages. You can specify liquid templating in your system and user messages.\nBetween the system or user messages, you must reference either 'transcript' or 'messages' with the '{{}}' syntax to access the conversation history.\nBetween the system or user messages, you must reference a variation of the structured output with the '{{}}' syntax to access the structured output definition.\ni.e.:\n{{structuredOutput}}\n{{structuredOutput.name}}\n{{structuredOutput.description}}\n{{structuredOutput.schema}}\n\nIf model is not specified, GPT-4.1 will be used by default for extraction, utilizing default system and user prompts.\nIf messages or required fields are not specified, the default system and user prompts will be used.", - "oneOf": [ - { - "$ref": "#/components/schemas/WorkflowOpenAIModel", - "title": "WorkflowOpenAIModel" - }, - { - "$ref": "#/components/schemas/WorkflowAnthropicModel", - "title": "WorkflowAnthropicModel" - }, - { - "$ref": "#/components/schemas/WorkflowGoogleModel", - "title": "WorkflowGoogleModel" - }, - { - "$ref": "#/components/schemas/WorkflowCustomModel", - "title": "WorkflowCustomModel" - } + "status": { + "type": "string", + "description": "This is the current status of the test suite run.", + "enum": [ + "queued", + "in-progress", + "completed", + "failed" ] }, "id": { "type": "string", - "description": "This is the unique identifier for the structured output." + "description": "This is the unique identifier for the test suite run." }, "orgId": { "type": "string", - "description": "This is the unique identifier for the org that this structured output belongs to." + "description": "This is the unique identifier for the organization this run belongs to." + }, + "testSuiteId": { + "type": "string", + "description": "This is the unique identifier for the test suite this run belongs to." }, "createdAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the structured output was created." + "description": "This is the ISO 8601 date-time string of when the test suite run was created." }, "updatedAt": { "format": "date-time", "type": "string", - "description": "This is the ISO 8601 date-time string of when the structured output was last updated." - }, - "name": { - "type": "string", - "description": "This is the name of the structured output.", - "minLength": 1, - "maxLength": 40 - }, - "description": { - "type": "string", - "description": "This is the description of what the structured output extracts.\n\nUse this to provide context about what data will be extracted and how it will be used." - }, - "assistantIds": { - "description": "These are the assistant IDs that this structured output is linked to.\n\nWhen linked to assistants, this structured output will be available for extraction during those assistant's calls.", - "type": "array", - "items": { - "type": "string" - } + "description": "This is the ISO 8601 date-time string of when the test suite run was last updated." }, - "workflowIds": { - "description": "These are the workflow IDs that this structured output is linked to.\n\nWhen linked to workflows, this structured output will be available for extraction during those workflow's execution.", + "testResults": { + "description": "These are the results of the tests in this test suite run.", "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/TestSuiteRunTestResult" } }, - "schema": { - "description": "This is the JSON Schema definition for the structured output.\n\nDefines the structure and validation rules for the data that will be extracted. Supports all JSON Schema features including:\n- Objects and nested properties\n- Arrays and array validation\n- String, number, boolean, and null types\n- Enums and const values\n- Validation constraints (min/max, patterns, etc.)\n- Composition with allOf, anyOf, oneOf", - "allOf": [ - { - "$ref": "#/components/schemas/JsonSchema" - } - ] + "name": { + "type": "string", + "description": "This is the name of the test suite run.", + "maxLength": 80 } }, "required": [ + "status", "id", "orgId", + "testSuiteId", "createdAt", "updatedAt", - "name", - "schema" + "testResults" ] }, - "StructuredOutputPaginatedResponse": { + "TestSuiteRunsPaginatedResponse": { "type": "object", "properties": { "results": { "type": "array", "items": { - "$ref": "#/components/schemas/StructuredOutput" + "$ref": "#/components/schemas/TestSuiteRun" } }, "metadata": { @@ -39330,123 +37137,23 @@ "metadata" ] }, - "CreateStructuredOutputDTO": { + "CreateTestSuiteRunDto": { "type": "object", "properties": { - "model": { - "description": "This is the model that will be used to extract the structured output.\n\nTo provide your own custom system and user prompts for structured output extraction, populate the messages array with your system and user messages. You can specify liquid templating in your system and user messages.\nBetween the system or user messages, you must reference either 'transcript' or 'messages' with the '{{}}' syntax to access the conversation history.\nBetween the system or user messages, you must reference a variation of the structured output with the '{{}}' syntax to access the structured output definition.\ni.e.:\n{{structuredOutput}}\n{{structuredOutput.name}}\n{{structuredOutput.description}}\n{{structuredOutput.schema}}\n\nIf model is not specified, GPT-4.1 will be used by default for extraction, utilizing default system and user prompts.\nIf messages or required fields are not specified, the default system and user prompts will be used.", - "oneOf": [ - { - "$ref": "#/components/schemas/WorkflowOpenAIModel", - "title": "WorkflowOpenAIModel" - }, - { - "$ref": "#/components/schemas/WorkflowAnthropicModel", - "title": "WorkflowAnthropicModel" - }, - { - "$ref": "#/components/schemas/WorkflowGoogleModel", - "title": "WorkflowGoogleModel" - }, - { - "$ref": "#/components/schemas/WorkflowCustomModel", - "title": "WorkflowCustomModel" - } - ] - }, "name": { "type": "string", - "description": "This is the name of the structured output.", - "minLength": 1, - "maxLength": 40 - }, - "schema": { - "description": "This is the JSON Schema definition for the structured output.\n\nThis is required when creating a structured output. Defines the structure and validation rules for the data that will be extracted. Supports all JSON Schema features including:\n- Objects and nested properties\n- Arrays and array validation\n- String, number, boolean, and null types\n- Enums and const values\n- Validation constraints (min/max, patterns, etc.)\n- Composition with allOf, anyOf, oneOf", - "allOf": [ - { - "$ref": "#/components/schemas/JsonSchema" - } - ] - }, - "description": { - "type": "string", - "description": "This is the description of what the structured output extracts.\n\nUse this to provide context about what data will be extracted and how it will be used." - }, - "assistantIds": { - "description": "These are the assistant IDs that this structured output is linked to.\n\nWhen linked to assistants, this structured output will be available for extraction during those assistant's calls.", - "type": "array", - "items": { - "type": "string" - } - }, - "workflowIds": { - "description": "These are the workflow IDs that this structured output is linked to.\n\nWhen linked to workflows, this structured output will be available for extraction during those workflow's execution.", - "type": "array", - "items": { - "type": "string" - } + "description": "This is the name of the test suite run.", + "maxLength": 80 } - }, - "required": [ - "name", - "schema" - ] + } }, - "UpdateStructuredOutputDTO": { + "UpdateTestSuiteRunDto": { "type": "object", "properties": { - "model": { - "description": "This is the model that will be used to extract the structured output.\n\nTo provide your own custom system and user prompts for structured output extraction, populate the messages array with your system and user messages. You can specify liquid templating in your system and user messages.\nBetween the system or user messages, you must reference either 'transcript' or 'messages' with the '{{}}' syntax to access the conversation history.\nBetween the system or user messages, you must reference a variation of the structured output with the '{{}}' syntax to access the structured output definition.\ni.e.:\n{{structuredOutput}}\n{{structuredOutput.name}}\n{{structuredOutput.description}}\n{{structuredOutput.schema}}\n\nIf model is not specified, GPT-4.1 will be used by default for extraction, utilizing default system and user prompts.\nIf messages or required fields are not specified, the default system and user prompts will be used.", - "oneOf": [ - { - "$ref": "#/components/schemas/WorkflowOpenAIModel", - "title": "WorkflowOpenAIModel" - }, - { - "$ref": "#/components/schemas/WorkflowAnthropicModel", - "title": "WorkflowAnthropicModel" - }, - { - "$ref": "#/components/schemas/WorkflowGoogleModel", - "title": "WorkflowGoogleModel" - }, - { - "$ref": "#/components/schemas/WorkflowCustomModel", - "title": "WorkflowCustomModel" - } - ] - }, "name": { "type": "string", - "description": "This is the name of the structured output.", - "minLength": 1, - "maxLength": 40 - }, - "description": { - "type": "string", - "description": "This is the description of what the structured output extracts.\n\nUse this to provide context about what data will be extracted and how it will be used." - }, - "assistantIds": { - "description": "These are the assistant IDs that this structured output is linked to.\n\nWhen linked to assistants, this structured output will be available for extraction during those assistant's calls.", - "type": "array", - "items": { - "type": "string" - } - }, - "workflowIds": { - "description": "These are the workflow IDs that this structured output is linked to.\n\nWhen linked to workflows, this structured output will be available for extraction during those workflow's execution.", - "type": "array", - "items": { - "type": "string" - } - }, - "schema": { - "description": "This is the JSON Schema definition for the structured output.\n\nDefines the structure and validation rules for the data that will be extracted. Supports all JSON Schema features including:\n- Objects and nested properties\n- Arrays and array validation\n- String, number, boolean, and null types\n- Enums and const values\n- Validation constraints (min/max, patterns, etc.)\n- Composition with allOf, anyOf, oneOf", - "allOf": [ - { - "$ref": "#/components/schemas/JsonSchema" - } - ] + "description": "This is the name of the test suite run.", + "maxLength": 80 } } }, @@ -42421,20 +40128,98 @@ ] }, "authenticationPlan": { - "description": "This is the authentication plan. Supports OAuth2 RFC 6749 and HMAC signing.", + "description": "This is the authentication plan. Supports OAuth2 RFC 6749, HMAC signing, and Bearer authentication.", + "oneOf": [ + { + "$ref": "#/components/schemas/OAuth2AuthenticationPlan" + }, + { + "$ref": "#/components/schemas/HMACAuthenticationPlan" + }, + { + "$ref": "#/components/schemas/BearerAuthenticationPlan" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "oauth2": "#/components/schemas/OAuth2AuthenticationPlan", + "hmac": "#/components/schemas/HMACAuthenticationPlan", + "bearer": "#/components/schemas/BearerAuthenticationPlan" + } + } + }, + "id": { + "type": "string", + "description": "This is the unique identifier for the credential." + }, + "orgId": { + "type": "string", + "description": "This is the unique identifier for the org that this credential belongs to." + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the credential was created." + }, + "updatedAt": { + "format": "date-time", + "type": "string", + "description": "This is the ISO 8601 date-time string of when the assistant was last updated." + }, + "authenticationSession": { + "description": "This is the authentication session for the credential. Available for credentials that have an authentication plan.", + "allOf": [ + { + "$ref": "#/components/schemas/Oauth2AuthenticationSession" + } + ] + }, + "name": { + "type": "string", + "description": "This is the name of credential. This is just for your reference.", + "minLength": 1, + "maxLength": 40 + } + }, + "required": [ + "provider", + "authenticationPlan", + "id", + "orgId", + "createdAt", + "updatedAt", + "authenticationSession" + ] + }, + "CustomCredential": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "custom-credential" + ] + }, + "authenticationPlan": { + "description": "This is the authentication plan. Supports OAuth2 RFC 6749, HMAC signing, and Bearer authentication.", "oneOf": [ { "$ref": "#/components/schemas/OAuth2AuthenticationPlan" }, { "$ref": "#/components/schemas/HMACAuthenticationPlan" + }, + { + "$ref": "#/components/schemas/BearerAuthenticationPlan" } ], "discriminator": { "propertyName": "type", "mapping": { "oauth2": "#/components/schemas/OAuth2AuthenticationPlan", - "hmac": "#/components/schemas/HMACAuthenticationPlan" + "hmac": "#/components/schemas/HMACAuthenticationPlan", + "bearer": "#/components/schemas/BearerAuthenticationPlan" } } }, @@ -43019,6 +40804,49 @@ "apiKey" ] }, + "CreateCustomCredentialDTO": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": [ + "custom-credential" + ] + }, + "authenticationPlan": { + "description": "This is the authentication plan. Supports OAuth2 RFC 6749, HMAC signing, and Bearer authentication.", + "oneOf": [ + { + "$ref": "#/components/schemas/OAuth2AuthenticationPlan" + }, + { + "$ref": "#/components/schemas/HMACAuthenticationPlan" + }, + { + "$ref": "#/components/schemas/BearerAuthenticationPlan" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "oauth2": "#/components/schemas/OAuth2AuthenticationPlan", + "hmac": "#/components/schemas/HMACAuthenticationPlan", + "bearer": "#/components/schemas/BearerAuthenticationPlan" + } + } + }, + "name": { + "type": "string", + "description": "This is the name of credential. This is just for your reference.", + "minLength": 1, + "maxLength": 40 + } + }, + "required": [ + "provider", + "authenticationPlan" + ] + }, "CreateGoHighLevelMCPCredentialDTO": { "type": "object", "properties": { @@ -43968,20 +41796,57 @@ "type": "object", "properties": { "authenticationPlan": { - "description": "This is the authentication plan. Supports OAuth2 RFC 6749 and HMAC signing.", + "description": "This is the authentication plan. Supports OAuth2 RFC 6749, HMAC signing, and Bearer authentication.", + "oneOf": [ + { + "$ref": "#/components/schemas/OAuth2AuthenticationPlan" + }, + { + "$ref": "#/components/schemas/HMACAuthenticationPlan" + }, + { + "$ref": "#/components/schemas/BearerAuthenticationPlan" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "oauth2": "#/components/schemas/OAuth2AuthenticationPlan", + "hmac": "#/components/schemas/HMACAuthenticationPlan", + "bearer": "#/components/schemas/BearerAuthenticationPlan" + } + } + }, + "name": { + "type": "string", + "description": "This is the name of credential. This is just for your reference.", + "minLength": 1, + "maxLength": 40 + } + } + }, + "UpdateCustomCredentialDTO": { + "type": "object", + "properties": { + "authenticationPlan": { + "description": "This is the authentication plan. Supports OAuth2 RFC 6749, HMAC signing, and Bearer authentication.", "oneOf": [ { "$ref": "#/components/schemas/OAuth2AuthenticationPlan" }, { "$ref": "#/components/schemas/HMACAuthenticationPlan" + }, + { + "$ref": "#/components/schemas/BearerAuthenticationPlan" } ], "discriminator": { "propertyName": "type", "mapping": { "oauth2": "#/components/schemas/OAuth2AuthenticationPlan", - "hmac": "#/components/schemas/HMACAuthenticationPlan" + "hmac": "#/components/schemas/HMACAuthenticationPlan", + "bearer": "#/components/schemas/BearerAuthenticationPlan" } } }, @@ -44286,6 +42151,33 @@ "algorithm" ] }, + "BearerAuthenticationPlan": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "bearer" + ] + }, + "token": { + "type": "string", + "description": "This is the bearer token value." + }, + "headerName": { + "type": "string", + "description": "This is the header name where the bearer token will be sent. Defaults to 'Authorization'." + }, + "bearerPrefixEnabled": { + "type": "boolean", + "description": "Whether to include the 'Bearer ' prefix in the header value. Defaults to true." + } + }, + "required": [ + "type", + "token" + ] + }, "CredentialSessionDTO": { "type": "object", "properties": { @@ -45493,6 +43385,192 @@ "files" ] }, + "TimeRange": { + "type": "object", + "properties": { + "step": { + "type": "string", + "description": "This is the time step for aggregations.\n\nIf not provided, defaults to returning for the entire time range.", + "enum": [ + "second", + "minute", + "hour", + "day", + "week", + "month", + "quarter", + "year", + "decade", + "century", + "millennium" + ] + }, + "start": { + "format": "date-time", + "type": "string", + "description": "This is the start date for the time range.\n\nIf not provided, defaults to the 7 days ago." + }, + "end": { + "format": "date-time", + "type": "string", + "description": "This is the end date for the time range.\n\nIf not provided, defaults to now." + }, + "timezone": { + "type": "string", + "description": "This is the timezone you want to set for the query.\n\nIf not provided, defaults to UTC." + } + } + }, + "AnalyticsOperation": { + "type": "object", + "properties": { + "operation": { + "type": "string", + "description": "This is the aggregation operation you want to perform.", + "enum": [ + "sum", + "avg", + "count", + "min", + "max", + "history" + ] + }, + "column": { + "type": "string", + "description": "This is the columns you want to perform the aggregation operation on.", + "enum": [ + "id", + "cost", + "costBreakdown.llm", + "costBreakdown.stt", + "costBreakdown.tts", + "costBreakdown.vapi", + "costBreakdown.transport", + "costBreakdown.analysisBreakdown.summary", + "costBreakdown.transcriber", + "costBreakdown.ttsCharacters", + "costBreakdown.llmPromptTokens", + "costBreakdown.llmCompletionTokens", + "duration", + "concurrency", + "minutesUsed" + ] + }, + "alias": { + "type": "string", + "description": "This is the alias for column name returned. Defaults to `${operation}${column}`.", + "maxLength": 40 + } + }, + "required": [ + "operation", + "column" + ] + }, + "AnalyticsQuery": { + "type": "object", + "properties": { + "table": { + "type": "string", + "description": "This is the table you want to query.", + "enum": [ + "call", + "subscription" + ] + }, + "groupBy": { + "type": "array", + "description": "This is the list of columns you want to group by.", + "enum": [ + "type", + "assistantId", + "endedReason", + "analysis.successEvaluation", + "status" + ], + "items": { + "type": "string", + "enum": [ + "type", + "assistantId", + "endedReason", + "analysis.successEvaluation", + "status" + ] + } + }, + "name": { + "type": "string", + "description": "This is the name of the query. This will be used to identify the query in the response.", + "maxLength": 40 + }, + "timeRange": { + "description": "This is the time range for the query.", + "allOf": [ + { + "$ref": "#/components/schemas/TimeRange" + } + ] + }, + "operations": { + "description": "This is the list of operations you want to perform.", + "type": "array", + "items": { + "$ref": "#/components/schemas/AnalyticsOperation" + } + } + }, + "required": [ + "table", + "name", + "operations" + ] + }, + "AnalyticsQueryDTO": { + "type": "object", + "properties": { + "queries": { + "description": "This is the list of metric queries you want to perform.", + "type": "array", + "items": { + "$ref": "#/components/schemas/AnalyticsQuery" + } + } + }, + "required": [ + "queries" + ] + }, + "AnalyticsQueryResult": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This is the unique key for the query." + }, + "timeRange": { + "description": "This is the time range for the query.", + "allOf": [ + { + "$ref": "#/components/schemas/TimeRange" + } + ] + }, + "result": { + "description": "This is the result of the query, a list of unique groups with result of their aggregations.\n\nExample:\n\"result\": [\n { \"date\": \"2023-01-01\", \"assistantId\": \"123\", \"endedReason\": \"customer-ended-call\", \"sumDuration\": 120, \"avgCost\": 10.5 },\n { \"date\": \"2023-01-02\", \"assistantId\": \"123\", \"endedReason\": \"customer-did-not-give-microphone-permission\", \"sumDuration\": 0, \"avgCost\": 0 },\n // Additional results\n]", + "type": "array", + "items": { + "type": "object" + } + } + }, + "required": [ + "name", + "timeRange", + "result" + ] + }, "ClientMessageWorkflowNodeStarted": { "type": "object", "properties": { From 3a7429e40d4b5fd7c918b8a23005c2528fde4e0f Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Mon, 1 Sep 2025 10:43:44 +0530 Subject: [PATCH 011/171] Add MIT License to the project --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..4a728d29b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Vapi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 671e9a5f3bee5c892ef3aa7df87998f6aa168852 Mon Sep 17 00:00:00 2001 From: sahil suman Date: Mon, 1 Sep 2025 10:52:13 +0530 Subject: [PATCH 012/171] remove logs and kb endpoints from api-reference page. --- fern/apis/api/openapi-overrides.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fern/apis/api/openapi-overrides.yml b/fern/apis/api/openapi-overrides.yml index 598d91ed1..9873c7274 100644 --- a/fern/apis/api/openapi-overrides.yml +++ b/fern/apis/api/openapi-overrides.yml @@ -196,23 +196,28 @@ paths: get: x-fern-sdk-group-name: - knowledgeBases + x-fern-ignore: true x-fern-sdk-method-name: list post: x-fern-sdk-group-name: - knowledgeBases + x-fern-ignore: true x-fern-sdk-method-name: create /knowledge-base/{id}: get: x-fern-sdk-group-name: - knowledgeBases + x-fern-ignore: true x-fern-sdk-method-name: get delete: x-fern-sdk-group-name: - knowledgeBases + x-fern-ignore: true x-fern-sdk-method-name: delete patch: x-fern-sdk-group-name: - knowledgeBases + x-fern-ignore: true x-fern-sdk-method-name: update /analytics: post: @@ -224,6 +229,7 @@ paths: /logs: get: x-fern-pagination: true + x-fern-ignore: true x-fern-sdk-group-name: - logs x-fern-sdk-method-name: get From cd5ba7e9659b593d741d087a494d1f5212298cb1 Mon Sep 17 00:00:00 2001 From: Sri Date: Mon, 1 Sep 2025 13:20:28 -0700 Subject: [PATCH 013/171] Updated mcp tools doc --- fern/tools/mcp.mdx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/fern/tools/mcp.mdx b/fern/tools/mcp.mdx index ef2fe7e9b..9b34bd987 100644 --- a/fern/tools/mcp.mdx +++ b/fern/tools/mcp.mdx @@ -64,14 +64,17 @@ Now, add the MCP tool to your assistant: ## How MCP Works -The MCP integration follows these steps during a call: - -1. When a call starts, Vapi connects to your configured MCP server using **Streamable HTTP** protocol by default -2. The MCP server returns a list of available tools and their capabilities -3. These tools are dynamically added to your assistant's available tools -4. The assistant can then use these tools during the call -5. When a tool is invoked, Vapi sends the request to the MCP server -6. The MCP server executes the action and returns the result +The MCP integration follows these steps during a call or chat session: + +1. When a call or chat starts, Vapi connects to your configured MCP server using **Streamable HTTP** protocol by default, fetches the list of available tools, and dynamically adds them to your assistant's available tools +2. The assistant can then use these tools during the interaction +3. **Each time the model invokes a specific MCP tool**, Vapi creates a new connection to the MCP server and sends the request with the `X-Call-Id`/`X-Chat-Id` header to identify the call or chat +4. The MCP server executes the action and returns the result +5. This process repeats for every tool invocation, meaning **multiple MCP sessions are created per call or chat** + + + Vapi uses multiple MCP sessions throughout a single conversation to ensure consistent behavior across both calls and chat interactions. Each tool execution creates a separate connection to the MCP server, allowing for isolated and reliable tool execution. All tool invocations include the `X-Call-Id`/`X-Chat-Id` header to identify the specific call or chat. + The MCP tool itself is not meant to be invoked by the model. It serves as a configuration mechanism for Vapi to fetch and inject the specific tool definitions from the MCP server into the model's context. From 3d8b8346a06e52151c31660847740522c61cb4d0 Mon Sep 17 00:00:00 2001 From: Fern Support <126544928+fern-support@users.noreply.github.com> Date: Thu, 4 Sep 2025 14:22:22 -0400 Subject: [PATCH 014/171] bumped all fern versions (#664) Co-authored-by: Aditya Arolkar --- fern/apis/api/generators.yml | 16 ++++++++-------- fern/fern.config.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fern/apis/api/generators.yml b/fern/apis/api/generators.yml index 4a3b5c409..646709079 100644 --- a/fern/apis/api/generators.yml +++ b/fern/apis/api/generators.yml @@ -11,7 +11,7 @@ groups: python-sdk: generators: - name: fernapi/fern-python-sdk - version: 4.23.2 + version: 4.28.0 api: settings: unions: v1 @@ -28,7 +28,7 @@ groups: ts-sdk: generators: - name: fernapi/fern-typescript-node-sdk - version: 2.1.0 + version: 2.10.1 api: settings: unions: v1 @@ -49,7 +49,7 @@ groups: java-sdk: generators: - name: fernapi/fern-java-sdk - version: 2.38.6 + version: 2.43.3 disable-examples: true output: location: maven @@ -57,9 +57,9 @@ groups: username: ${MAVEN_USERNAME} password: ${MAVEN_PASSWORD} signature: - keyId: ${MAVEN_CENTRAL_SECRET_KEY_KEY_ID} - password: ${MAVEN_CENTRAL_SECRET_KEY_PASSWORD} - secretKey: ${MAVEN_CENTRAL_SECRET_KEY} + keyId: ${MAVEN_CENTRAL_SECRET_KEY_KEY_ID} + password: ${MAVEN_CENTRAL_SECRET_KEY_PASSWORD} + secretKey: ${MAVEN_CENTRAL_SECRET_KEY} github: repository: VapiAI/server-sdk-java config: @@ -67,7 +67,7 @@ groups: go-sdk: generators: - name: fernapi/fern-go-sdk - version: 1.4.0 + version: 1.7.0 disable-examples: true api: settings: @@ -92,7 +92,7 @@ groups: csharp-sdk: generators: - name: fernapi/fern-csharp-sdk - version: 2.0.2 + version: 2.1.15 disable-examples: true github: repository: VapiAI/server-sdk-csharp diff --git a/fern/fern.config.json b/fern/fern.config.json index a090da842..7e6a5183d 100644 --- a/fern/fern.config.json +++ b/fern/fern.config.json @@ -1,4 +1,4 @@ { "organization": "vapi", - "version": "0.64.36" + "version": "0.70.1" } \ No newline at end of file From f6bf55aa209935872bac1a3407c55f7c390fe2d7 Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Fri, 5 Sep 2025 19:29:49 +0530 Subject: [PATCH 015/171] Update websocket-transport.mdx --- fern/calls/websocket-transport.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/fern/calls/websocket-transport.mdx b/fern/calls/websocket-transport.mdx index c3accb0dc..d7927f68f 100644 --- a/fern/calls/websocket-transport.mdx +++ b/fern/calls/websocket-transport.mdx @@ -4,8 +4,6 @@ description: Stream audio directly via WebSockets for real-time, bidirectional c slug: calls/websocket-transport --- -# WebSocket Transport - Vapi's WebSocket transport enables real-time, bidirectional audio communication directly between your application and Vapi's AI assistants. Unlike traditional phone or web calls, this transport method lets you stream raw audio data instantly with minimal latency. ## Key Benefits From 0d37c64808d087b7a7fee148f3f3c8c4cc17af8a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 7 Sep 2025 03:14:27 -0700 Subject: [PATCH 016/171] Update API specifications with fern api update (#667) Co-authored-by: github-actions --- fern/apis/api/openapi.json | 2940 +++++++++++++++++++++++++++++++----- 1 file changed, 2535 insertions(+), 405 deletions(-) diff --git a/fern/apis/api/openapi.json b/fern/apis/api/openapi.json index 9044bc121..ecb32b45e 100644 --- a/fern/apis/api/openapi.json +++ b/fern/apis/api/openapi.json @@ -862,6 +862,15 @@ "type": "string" } }, + { + "name": "squadId", + "required": false, + "in": "query", + "description": "This is the unique identifier for the squad that will be used for the chat.", + "schema": { + "type": "string" + } + }, { "name": "workflowId", "required": false, @@ -1019,7 +1028,7 @@ "post": { "operationId": "ChatController_createChat", "summary": "Create Chat", - "description": "Creates a new chat. Requires at least one of: assistantId/assistant, sessionId, or previousChatId. Note: sessionId and previousChatId are mutually exclusive.", + "description": "Creates a new chat with optional SMS delivery via transport field. Requires at least one of: assistantId/assistant, sessionId, or previousChatId. Note: sessionId and previousChatId are mutually exclusive. Transport field enables SMS delivery with two modes: (1) New conversation - provide transport.phoneNumberId and transport.customer to create a new session, (2) Existing conversation - provide sessionId to use existing session data. Cannot specify both sessionId and transport fields together. The transport.useLLMGeneratedMessageForOutbound flag controls whether input is processed by LLM (true, default) or forwarded directly as SMS (false).", "parameters": [], "requestBody": { "required": true, @@ -1573,6 +1582,15 @@ "type": "string" } }, + { + "name": "squadId", + "required": false, + "in": "query", + "description": "This is the ID of the squad to filter sessions by.", + "schema": { + "type": "string" + } + }, { "name": "workflowId", "required": false, @@ -3858,58 +3876,252 @@ ] } }, - "/provider/{provider}/{resourceName}": { + "/eval": { "post": { - "operationId": "ProviderResourceController_createProviderResource", - "summary": "Create Provider Resource", + "operationId": "EvalController_create", + "summary": "Create Eval", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/CreateEvalDTO", + "title": "CreateEvalDTO" + } + ] + } + } + } + }, + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "Eval" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "get": { + "operationId": "EvalController_getPaginated", + "summary": "Get Evals with pagination", "parameters": [ { - "name": "content-type", - "required": true, - "in": "header", + "name": "id", + "required": false, + "in": "query", "schema": { "type": "string" } }, { - "name": "provider", - "required": true, - "in": "path", - "description": "The provider (e.g., 11labs)", + "name": "page", + "required": false, + "in": "query", + "description": "This is the page number to return. Defaults to 1.", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "sortOrder", + "required": false, + "in": "query", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", "schema": { "enum": [ - "11labs" + "ASC", + "DESC" ], "type": "string" } }, { - "name": "resourceName", - "required": true, - "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", + "name": "limit", + "required": false, + "in": "query", + "description": "This is the maximum number of items to return. Defaults to 100.", "schema": { - "enum": [ - "pronunciation-dictionary" - ], + "minimum": 0, + "maximum": 1000, + "type": "number" + } + }, + { + "name": "createdAtGt", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is greater than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtLt", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is less than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtGe", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is greater than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtLe", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is less than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtGt", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is greater than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtLt", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is less than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtGe", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is greater than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtLe", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is less than or equal to the specified value.", + "schema": { + "format": "date-time", "type": "string" } } ], "responses": { - "201": { - "description": "Successfully created provider resource", + "200": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ProviderResource" + "$ref": "#/components/schemas/EvalPaginatedResponse" } } } } }, "tags": [ - "Provider Resources" + "Eval" + ], + "security": [ + { + "bearer": [] + } + ] + } + }, + "/eval/{id}": { + "patch": { + "operationId": "EvalController_update", + "summary": "Update Eval", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/UpdateEvalDTO", + "title": "UpdateEvalDTO" + } + ] + } + } + } + }, + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Eval" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "delete": { + "operationId": "EvalController_remove", + "summary": "Delete Eval", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Eval" ], "security": [ { @@ -3918,43 +4130,381 @@ ] }, "get": { - "operationId": "ProviderResourceController_getProviderResourcesPaginated", - "summary": "List Provider Resources", + "operationId": "EvalController_get", + "summary": "Get Eval", "parameters": [ { - "name": "provider", + "name": "id", "required": true, "in": "path", - "description": "The provider (e.g., 11labs)", "schema": { - "enum": [ - "11labs" - ], "type": "string" } - }, + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Eval" + ], + "security": [ { - "name": "resourceName", + "bearer": [] + } + ] + } + }, + "/eval/run/{id}": { + "delete": { + "operationId": "EvalController_removeRun", + "summary": "Delete Eval Run", + "parameters": [ + { + "name": "id", "required": true, "in": "path", - "description": "The resource name (e.g., pronunciation-dictionary)", "schema": { - "enum": [ - "pronunciation-dictionary" - ], "type": "string" } - }, + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Eval" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "get": { + "operationId": "EvalController_getRun", + "summary": "Get Eval Run", + "parameters": [ { "name": "id", - "required": false, - "in": "query", + "required": true, + "in": "path", "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvalRun" + } + } + } + } + }, + "tags": [ + "Eval" + ], + "security": [ + { + "bearer": [] + } + ] + } + }, + "/eval/run": { + "post": { + "operationId": "EvalController_run", + "summary": "Run Eval", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateEvalRunDTO" + } + } + } + }, + "responses": { + "200": { + "description": "" }, + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Eval" + ], + "security": [ { - "name": "resourceId", + "bearer": [] + } + ] + }, + "get": { + "operationId": "EvalController_getRunsPaginated", + "summary": "Get Eval Runs with pagination", + "parameters": [ + { + "name": "id", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "description": "This is the page number to return. Defaults to 1.", + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "name": "sortOrder", + "required": false, + "in": "query", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "schema": { + "enum": [ + "ASC", + "DESC" + ], + "type": "string" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "description": "This is the maximum number of items to return. Defaults to 100.", + "schema": { + "minimum": 0, + "maximum": 1000, + "type": "number" + } + }, + { + "name": "createdAtGt", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is greater than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtLt", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is less than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtGe", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is greater than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "createdAtLe", + "required": false, + "in": "query", + "description": "This will return items where the createdAt is less than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtGt", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is greater than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtLt", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is less than the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtGe", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is greater than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "name": "updatedAtLe", + "required": false, + "in": "query", + "description": "This will return items where the updatedAt is less than or equal to the specified value.", + "schema": { + "format": "date-time", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvalRunPaginatedResponse" + } + } + } + } + }, + "tags": [ + "Eval" + ], + "security": [ + { + "bearer": [] + } + ] + } + }, + "/provider/{provider}/{resourceName}": { + "post": { + "operationId": "ProviderResourceController_createProviderResource", + "summary": "Create Provider Resource", + "parameters": [ + { + "name": "content-type", + "required": true, + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "provider", + "required": true, + "in": "path", + "description": "The provider (e.g., 11labs)", + "schema": { + "enum": [ + "11labs" + ], + "type": "string" + } + }, + { + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", + "schema": { + "enum": [ + "pronunciation-dictionary" + ], + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "Successfully created provider resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProviderResource" + } + } + } + } + }, + "tags": [ + "Provider Resources" + ], + "security": [ + { + "bearer": [] + } + ] + }, + "get": { + "operationId": "ProviderResourceController_getProviderResourcesPaginated", + "summary": "List Provider Resources", + "parameters": [ + { + "name": "provider", + "required": true, + "in": "path", + "description": "The provider (e.g., 11labs)", + "schema": { + "enum": [ + "11labs" + ], + "type": "string" + } + }, + { + "name": "resourceName", + "required": true, + "in": "path", + "description": "The resource name (e.g., pronunciation-dictionary)", + "schema": { + "enum": [ + "pronunciation-dictionary" + ], + "type": "string" + } + }, + { + "name": "id", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "resourceId", "required": false, "in": "query", "schema": { @@ -4442,26 +4992,26 @@ }, "endOfTurnConfidenceThreshold": { "type": "number", - "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\n\n@min 0\n@max 1\n@default 0.7", + "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@min 0\n@max 1\n@default 0.7", "minimum": 0, "maximum": 1, "example": 0.7 }, "minEndOfTurnSilenceWhenConfident": { "type": "number", - "description": "This is the minimum end of turn silence when confident in milliseconds.\n\n@default 160", + "description": "This is the minimum end of turn silence when confident in milliseconds.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@default 160", "minimum": 0, "example": 160 }, "wordFinalizationMaxWaitTime": { "type": "number", - "description": "This is the maximum wait time for word finalization in milliseconds.\n\n@default 160", + "description": "This is the maximum wait time for word finalization in milliseconds.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@default 160", "minimum": 0, "example": 160 }, "maxTurnSilence": { "type": "number", - "description": "This is the maximum turn silence time in milliseconds.\n\n@default 400", + "description": "This is the maximum turn silence time in milliseconds.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@default 400", "minimum": 0, "example": 400 }, @@ -5184,6 +5734,18 @@ "maximum": 1, "example": 0.4 }, + "preflightThreshold": { + "type": "number", + "example": 0.3 + }, + "eotThreshold": { + "type": "number", + "example": 0.7 + }, + "eotTimeoutMs": { + "type": "number", + "example": 3000 + }, "keywords": { "description": "These keywords are passed to the transcription model to help it pick up use-case specific words. Anything that may not be a common word, like your company name, should be added here.", "type": "array", @@ -5762,6 +6324,20 @@ } ] }, + "region": { + "type": "string", + "enum": [ + "us-west", + "eu-west" + ], + "description": "Region for processing audio (us-west or eu-west)", + "example": "us-west" + }, + "receivePartialTranscripts": { + "type": "boolean", + "example": false, + "description": "Enable partial transcripts for low-latency streaming transcription" + }, "fallbackPlan": { "description": "This is the plan for voice provider fallbacks in the event that the primary voice provider fails.", "allOf": [ @@ -6216,26 +6792,26 @@ }, "endOfTurnConfidenceThreshold": { "type": "number", - "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\n\n@min 0\n@max 1\n@default 0.7", + "description": "This is the end of turn confidence threshold. The minimum confidence that the end of turn is detected.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@min 0\n@max 1\n@default 0.7", "minimum": 0, "maximum": 1, "example": 0.7 }, "minEndOfTurnSilenceWhenConfident": { "type": "number", - "description": "This is the minimum end of turn silence when confident in milliseconds.\n\n@default 160", + "description": "This is the minimum end of turn silence when confident in milliseconds.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@default 160", "minimum": 0, "example": 160 }, "wordFinalizationMaxWaitTime": { "type": "number", - "description": "This is the maximum wait time for word finalization in milliseconds.\n\n@default 160", + "description": "This is the maximum wait time for word finalization in milliseconds.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@default 160", "minimum": 0, "example": 160 }, "maxTurnSilence": { "type": "number", - "description": "This is the maximum turn silence time in milliseconds.\n\n@default 400", + "description": "This is the maximum turn silence time in milliseconds.\nNote: Only used if startSpeakingPlan.smartEndpointingPlan is not set.\n@default 400", "minimum": 0, "example": 400 }, @@ -6847,6 +7423,18 @@ "maximum": 1, "example": 0.4 }, + "preflightThreshold": { + "type": "number", + "example": 0.3 + }, + "eotThreshold": { + "type": "number", + "example": 0.7 + }, + "eotTimeoutMs": { + "type": "number", + "example": 3000 + }, "keywords": { "description": "These keywords are passed to the transcription model to help it pick up use-case specific words. Anything that may not be a common word, like your company name, should be added here.", "type": "array", @@ -7408,6 +7996,20 @@ "$ref": "#/components/schemas/GladiaCustomVocabularyConfigDTO" } ] + }, + "region": { + "type": "string", + "enum": [ + "us-west", + "eu-west" + ], + "description": "Region for processing audio (us-west or eu-west)", + "example": "us-west" + }, + "receivePartialTranscripts": { + "type": "boolean", + "example": false, + "description": "Enable partial transcripts for low-latency streaming transcription" } }, "required": [ @@ -11630,6 +12232,7 @@ "llama3-8b-8192", "llama3-70b-8192", "gemma2-9b-it", + "moonshotai/kimi-k2-instruct-0905", "meta-llama/llama-4-maverick-17b-128e-instruct", "meta-llama/llama-4-scout-17b-16e-instruct", "mistral-saba-24b", @@ -13477,6 +14080,216 @@ "name" ] }, + "VoicemailDetectionBackoffPlan": { + "type": "object", + "properties": { + "startAtSeconds": { + "type": "number", + "description": "This is the number of seconds to wait before starting the first retry attempt.", + "minimum": 0, + "default": 5 + }, + "frequencySeconds": { + "type": "number", + "description": "This is the interval in seconds between retry attempts.", + "minimum": 2.5, + "default": 5 + }, + "maxRetries": { + "type": "number", + "description": "This is the maximum number of retry attempts before giving up.", + "minimum": 1, + "maximum": 10, + "default": 6 + } + } + }, + "GoogleVoicemailDetectionPlan": { + "type": "object", + "properties": { + "beepMaxAwaitSeconds": { + "type": "number", + "description": "This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message\n\n- If we detect a voicemail beep before this, we will speak the message at that point.\n\n- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.\n\n@default 30\n@min 0\n@max 60", + "minimum": 0, + "maximum": 30, + "default": 30 + }, + "provider": { + "type": "string", + "description": "This is the provider to use for voicemail detection.", + "enum": [ + "google" + ] + }, + "backoffPlan": { + "description": "This is the backoff plan for the voicemail detection.", + "allOf": [ + { + "$ref": "#/components/schemas/VoicemailDetectionBackoffPlan" + } + ] + }, + "type": { + "type": "string", + "description": "This is the detection type to use for voicemail detection.\n- 'audio': Uses native audio models (default)\n- 'transcript': Uses ASR/transcript-based detection\n@default 'audio' (audio detection)", + "enum": [ + "audio", + "transcript" + ] + } + }, + "required": [ + "provider" + ] + }, + "OpenAIVoicemailDetectionPlan": { + "type": "object", + "properties": { + "beepMaxAwaitSeconds": { + "type": "number", + "description": "This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message\n\n- If we detect a voicemail beep before this, we will speak the message at that point.\n\n- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.\n\n@default 30\n@min 0\n@max 60", + "minimum": 0, + "maximum": 30, + "default": 30 + }, + "provider": { + "type": "string", + "description": "This is the provider to use for voicemail detection.", + "enum": [ + "openai" + ] + }, + "backoffPlan": { + "description": "This is the backoff plan for the voicemail detection.", + "allOf": [ + { + "$ref": "#/components/schemas/VoicemailDetectionBackoffPlan" + } + ] + }, + "type": { + "type": "string", + "description": "This is the detection type to use for voicemail detection.\n- 'audio': Uses native audio models (default)\n- 'transcript': Uses ASR/transcript-based detection\n@default 'audio' (audio detection)", + "enum": [ + "audio", + "transcript" + ] + } + }, + "required": [ + "provider" + ] + }, + "TwilioVoicemailDetectionPlan": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider to use for voicemail detection.", + "enum": [ + "twilio" + ] + }, + "voicemailDetectionTypes": { + "type": "array", + "description": "These are the AMD messages from Twilio that are considered as voicemail. Default is ['machine_end_beep', 'machine_end_silence'].\n\n@default {Array} ['machine_end_beep', 'machine_end_silence']", + "enum": [ + "machine_start", + "human", + "fax", + "unknown", + "machine_end_beep", + "machine_end_silence", + "machine_end_other" + ], + "example": [ + "machine_end_beep", + "machine_end_silence" + ], + "items": { + "type": "string", + "enum": [ + "machine_start", + "human", + "fax", + "unknown", + "machine_end_beep", + "machine_end_silence", + "machine_end_other" + ] + } + }, + "enabled": { + "type": "boolean", + "description": "This sets whether the assistant should detect voicemail. Defaults to true.\n\n@default true" + }, + "machineDetectionTimeout": { + "type": "number", + "description": "The number of seconds that Twilio should attempt to perform answering machine detection before timing out and returning AnsweredBy as unknown. Default is 30 seconds.\n\nIncreasing this value will provide the engine more time to make a determination. This can be useful when DetectMessageEnd is provided in the MachineDetection parameter and there is an expectation of long answering machine greetings that can exceed 30 seconds.\n\nDecreasing this value will reduce the amount of time the engine has to make a determination. This can be particularly useful when the Enable option is provided in the MachineDetection parameter and you want to limit the time for initial detection.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 30", + "minimum": 3, + "maximum": 59 + }, + "machineDetectionSpeechThreshold": { + "type": "number", + "description": "The number of milliseconds that is used as the measuring stick for the length of the speech activity. Durations lower than this value will be interpreted as a human, longer as a machine. Default is 2400 milliseconds.\n\nIncreasing this value will reduce the chance of a False Machine (detected machine, actually human) for a long human greeting (e.g., a business greeting) but increase the time it takes to detect a machine.\n\nDecreasing this value will reduce the chances of a False Human (detected human, actually machine) for short voicemail greetings. The value of this parameter may need to be reduced by more than 1000ms to detect very short voicemail greetings. A reduction of that significance can result in increased False Machine detections. Adjusting the MachineDetectionSpeechEndThreshold is likely the better approach for short voicemails. Decreasing MachineDetectionSpeechThreshold will also reduce the time it takes to detect a machine.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 2400", + "minimum": 1000, + "maximum": 6000 + }, + "machineDetectionSpeechEndThreshold": { + "type": "number", + "description": "The number of milliseconds of silence after speech activity at which point the speech activity is considered complete. Default is 1200 milliseconds.\n\nIncreasing this value will typically be used to better address the short voicemail greeting scenarios. For short voicemails, there is typically 1000-2000ms of audio followed by 1200-2400ms of silence and then additional audio before the beep. Increasing the MachineDetectionSpeechEndThreshold to ~2500ms will treat the 1200-2400ms of silence as a gap in the greeting but not the end of the greeting and will result in a machine detection. The downsides of such a change include:\n- Increasing the delay for human detection by the amount you increase this parameter, e.g., a change of 1200ms to 2500ms increases human detection delay by 1300ms.\n- Cases where a human has two utterances separated by a period of silence (e.g. a \"Hello\", then 2000ms of silence, and another \"Hello\") may be interpreted as a machine.\n\nDecreasing this value will result in faster human detection. The consequence is that it can lead to increased False Human (detected human, actually machine) detections because a silence gap in a voicemail greeting (not necessarily just in short voicemail scenarios) can be incorrectly interpreted as the end of speech.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 1200", + "minimum": 500, + "maximum": 5000 + }, + "machineDetectionSilenceTimeout": { + "type": "number", + "description": "The number of milliseconds of initial silence after which an unknown AnsweredBy result will be returned. Default is 5000 milliseconds.\n\nIncreasing this value will result in waiting for a longer period of initial silence before returning an 'unknown' AMD result.\n\nDecreasing this value will result in waiting for a shorter period of initial silence before returning an 'unknown' AMD result.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 5000", + "minimum": 2000, + "maximum": 10000 + } + }, + "required": [ + "provider" + ] + }, + "VapiVoicemailDetectionPlan": { + "type": "object", + "properties": { + "beepMaxAwaitSeconds": { + "type": "number", + "description": "This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message\n\n- If we detect a voicemail beep before this, we will speak the message at that point.\n\n- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.\n\n@default 30\n@min 0\n@max 60", + "minimum": 0, + "maximum": 30, + "default": 30 + }, + "provider": { + "type": "string", + "description": "This is the provider to use for voicemail detection.", + "enum": [ + "vapi" + ] + }, + "backoffPlan": { + "description": "This is the backoff plan for the voicemail detection.", + "allOf": [ + { + "$ref": "#/components/schemas/VoicemailDetectionBackoffPlan" + } + ] + }, + "type": { + "type": "string", + "description": "This is the detection type to use for voicemail detection.\n- 'audio': Uses native audio models (default)\n- 'transcript': Uses ASR/transcript-based detection\n@default 'audio' (audio detection)", + "enum": [ + "audio", + "transcript" + ] + } + }, + "required": [ + "provider" + ] + }, "AIEdgeCondition": { "type": "object", "properties": { @@ -14077,7 +14890,7 @@ ] }, "smartEndpointingPlan": { - "description": "This is the plan for smart endpointing. Pick between Vapi smart endpointing or LiveKit smart endpointing (or nothing). We strongly recommend using livekit endpointing when working in English. LiveKit endpointing is not supported in other languages, yet.\n\nIf this is set, it will override and take precedence over `transcriptionEndpointingPlan`.\nThis plan will still be overridden by any matching `customEndpointingRules`.", + "description": "This is the plan for smart endpointing. Pick between Vapi smart endpointing, LiveKit, or custom endpointing model (or nothing). We strongly recommend using livekit endpointing when working in English. LiveKit endpointing is not supported in other languages, yet.\n\nIf this is set, it will override and take precedence over `transcriptionEndpointingPlan`.\nThis plan will still be overridden by any matching `customEndpointingRules`.\n\nIf this is not set, the system will automatically use the transcriber's built-in endpointing capabilities if available.", "oneOf": [ { "$ref": "#/components/schemas/VapiSmartEndpointingPlan", @@ -14114,7 +14927,7 @@ } }, "transcriptionEndpointingPlan": { - "description": "This determines how a customer speech is considered done (endpointing) using the transcription of customer's speech.\n\nOnce an endpoint is triggered, the request is sent to `assistant.model`.\n\nNote: This plan is only used if `smartEndpointingPlan` is not set. If both are provided, `smartEndpointingPlan` takes precedence.\nThis plan will also be overridden by any matching `customEndpointingRules`.", + "description": "This determines how a customer speech is considered done (endpointing) using the transcription of customer's speech.\n\nOnce an endpoint is triggered, the request is sent to `assistant.model`.\n\nNote: This plan is only used if `smartEndpointingPlan` is not set and transcriber does not have built-in endpointing capabilities. If both are provided, `smartEndpointingPlan` takes precedence.\nThis plan will also be overridden by any matching `customEndpointingRules`.", "allOf": [ { "$ref": "#/components/schemas/TranscriptionEndpointingPlan" @@ -14866,6 +15679,27 @@ } } }, + "voicemailDetection": { + "description": "This is the voicemail detection plan for the workflow.", + "oneOf": [ + { + "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", + "title": "Google" + }, + { + "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", + "title": "Twilio" + }, + { + "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", + "title": "Vapi" + } + ] + }, "name": { "type": "string", "maxLength": 80 @@ -21695,216 +22529,6 @@ "do" ] }, - "VoicemailDetectionBackoffPlan": { - "type": "object", - "properties": { - "startAtSeconds": { - "type": "number", - "description": "This is the number of seconds to wait before starting the first retry attempt.", - "minimum": 0, - "default": 5 - }, - "frequencySeconds": { - "type": "number", - "description": "This is the interval in seconds between retry attempts.", - "minimum": 2.5, - "default": 5 - }, - "maxRetries": { - "type": "number", - "description": "This is the maximum number of retry attempts before giving up.", - "minimum": 1, - "maximum": 10, - "default": 6 - } - } - }, - "GoogleVoicemailDetectionPlan": { - "type": "object", - "properties": { - "beepMaxAwaitSeconds": { - "type": "number", - "description": "This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message\n\n- If we detect a voicemail beep before this, we will speak the message at that point.\n\n- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.\n\n@default 30\n@min 0\n@max 60", - "minimum": 0, - "maximum": 30, - "default": 30 - }, - "provider": { - "type": "string", - "description": "This is the provider to use for voicemail detection.", - "enum": [ - "google" - ] - }, - "backoffPlan": { - "description": "This is the backoff plan for the voicemail detection.", - "allOf": [ - { - "$ref": "#/components/schemas/VoicemailDetectionBackoffPlan" - } - ] - }, - "type": { - "type": "string", - "description": "This is the detection type to use for voicemail detection.\n- 'audio': Uses native audio models (default)\n- 'transcript': Uses ASR/transcript-based detection\n@default 'audio' (audio detection)", - "enum": [ - "audio", - "transcript" - ] - } - }, - "required": [ - "provider" - ] - }, - "OpenAIVoicemailDetectionPlan": { - "type": "object", - "properties": { - "beepMaxAwaitSeconds": { - "type": "number", - "description": "This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message\n\n- If we detect a voicemail beep before this, we will speak the message at that point.\n\n- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.\n\n@default 30\n@min 0\n@max 60", - "minimum": 0, - "maximum": 30, - "default": 30 - }, - "provider": { - "type": "string", - "description": "This is the provider to use for voicemail detection.", - "enum": [ - "openai" - ] - }, - "backoffPlan": { - "description": "This is the backoff plan for the voicemail detection.", - "allOf": [ - { - "$ref": "#/components/schemas/VoicemailDetectionBackoffPlan" - } - ] - }, - "type": { - "type": "string", - "description": "This is the detection type to use for voicemail detection.\n- 'audio': Uses native audio models (default)\n- 'transcript': Uses ASR/transcript-based detection\n@default 'audio' (audio detection)", - "enum": [ - "audio", - "transcript" - ] - } - }, - "required": [ - "provider" - ] - }, - "TwilioVoicemailDetectionPlan": { - "type": "object", - "properties": { - "provider": { - "type": "string", - "description": "This is the provider to use for voicemail detection.", - "enum": [ - "twilio" - ] - }, - "voicemailDetectionTypes": { - "type": "array", - "description": "These are the AMD messages from Twilio that are considered as voicemail. Default is ['machine_end_beep', 'machine_end_silence'].\n\n@default {Array} ['machine_end_beep', 'machine_end_silence']", - "enum": [ - "machine_start", - "human", - "fax", - "unknown", - "machine_end_beep", - "machine_end_silence", - "machine_end_other" - ], - "example": [ - "machine_end_beep", - "machine_end_silence" - ], - "items": { - "type": "string", - "enum": [ - "machine_start", - "human", - "fax", - "unknown", - "machine_end_beep", - "machine_end_silence", - "machine_end_other" - ] - } - }, - "enabled": { - "type": "boolean", - "description": "This sets whether the assistant should detect voicemail. Defaults to true.\n\n@default true" - }, - "machineDetectionTimeout": { - "type": "number", - "description": "The number of seconds that Twilio should attempt to perform answering machine detection before timing out and returning AnsweredBy as unknown. Default is 30 seconds.\n\nIncreasing this value will provide the engine more time to make a determination. This can be useful when DetectMessageEnd is provided in the MachineDetection parameter and there is an expectation of long answering machine greetings that can exceed 30 seconds.\n\nDecreasing this value will reduce the amount of time the engine has to make a determination. This can be particularly useful when the Enable option is provided in the MachineDetection parameter and you want to limit the time for initial detection.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 30", - "minimum": 3, - "maximum": 59 - }, - "machineDetectionSpeechThreshold": { - "type": "number", - "description": "The number of milliseconds that is used as the measuring stick for the length of the speech activity. Durations lower than this value will be interpreted as a human, longer as a machine. Default is 2400 milliseconds.\n\nIncreasing this value will reduce the chance of a False Machine (detected machine, actually human) for a long human greeting (e.g., a business greeting) but increase the time it takes to detect a machine.\n\nDecreasing this value will reduce the chances of a False Human (detected human, actually machine) for short voicemail greetings. The value of this parameter may need to be reduced by more than 1000ms to detect very short voicemail greetings. A reduction of that significance can result in increased False Machine detections. Adjusting the MachineDetectionSpeechEndThreshold is likely the better approach for short voicemails. Decreasing MachineDetectionSpeechThreshold will also reduce the time it takes to detect a machine.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 2400", - "minimum": 1000, - "maximum": 6000 - }, - "machineDetectionSpeechEndThreshold": { - "type": "number", - "description": "The number of milliseconds of silence after speech activity at which point the speech activity is considered complete. Default is 1200 milliseconds.\n\nIncreasing this value will typically be used to better address the short voicemail greeting scenarios. For short voicemails, there is typically 1000-2000ms of audio followed by 1200-2400ms of silence and then additional audio before the beep. Increasing the MachineDetectionSpeechEndThreshold to ~2500ms will treat the 1200-2400ms of silence as a gap in the greeting but not the end of the greeting and will result in a machine detection. The downsides of such a change include:\n- Increasing the delay for human detection by the amount you increase this parameter, e.g., a change of 1200ms to 2500ms increases human detection delay by 1300ms.\n- Cases where a human has two utterances separated by a period of silence (e.g. a \"Hello\", then 2000ms of silence, and another \"Hello\") may be interpreted as a machine.\n\nDecreasing this value will result in faster human detection. The consequence is that it can lead to increased False Human (detected human, actually machine) detections because a silence gap in a voicemail greeting (not necessarily just in short voicemail scenarios) can be incorrectly interpreted as the end of speech.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 1200", - "minimum": 500, - "maximum": 5000 - }, - "machineDetectionSilenceTimeout": { - "type": "number", - "description": "The number of milliseconds of initial silence after which an unknown AnsweredBy result will be returned. Default is 5000 milliseconds.\n\nIncreasing this value will result in waiting for a longer period of initial silence before returning an 'unknown' AMD result.\n\nDecreasing this value will result in waiting for a shorter period of initial silence before returning an 'unknown' AMD result.\n\nCheck the [Twilio docs](https://www.twilio.com/docs/voice/answering-machine-detection#optional-api-tuning-parameters) for more info.\n\n@default 5000", - "minimum": 2000, - "maximum": 10000 - } - }, - "required": [ - "provider" - ] - }, - "VapiVoicemailDetectionPlan": { - "type": "object", - "properties": { - "beepMaxAwaitSeconds": { - "type": "number", - "description": "This is the maximum duration from the start of the call that we will wait for a voicemail beep, before speaking our message\n\n- If we detect a voicemail beep before this, we will speak the message at that point.\n\n- Setting too low a value means that the bot will start speaking its voicemail message too early. If it does so before the actual beep, it will get cut off. You should definitely tune this to your use case.\n\n@default 30\n@min 0\n@max 60", - "minimum": 0, - "maximum": 30, - "default": 30 - }, - "provider": { - "type": "string", - "description": "This is the provider to use for voicemail detection.", - "enum": [ - "vapi" - ] - }, - "backoffPlan": { - "description": "This is the backoff plan for the voicemail detection.", - "allOf": [ - { - "$ref": "#/components/schemas/VoicemailDetectionBackoffPlan" - } - ] - }, - "type": { - "type": "string", - "description": "This is the detection type to use for voicemail detection.\n- 'audio': Uses native audio models (default)\n- 'transcript': Uses ASR/transcript-based detection\n@default 'audio' (audio detection)", - "enum": [ - "audio", - "transcript" - ] - } - }, - "required": [ - "provider" - ] - }, "SQLInjectionSecurityFilter": { "type": "object", "properties": { @@ -25901,6 +26525,27 @@ } } }, + "voicemailDetection": { + "description": "This is the voicemail detection plan for the workflow.", + "oneOf": [ + { + "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", + "title": "Google" + }, + { + "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", + "title": "Twilio" + }, + { + "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", + "title": "Vapi" + } + ] + }, "id": { "type": "string" }, @@ -26500,6 +27145,27 @@ } } }, + "voicemailDetection": { + "description": "This is the voicemail detection plan for the workflow.", + "oneOf": [ + { + "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", + "title": "Google" + }, + { + "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", + "title": "Twilio" + }, + { + "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", + "title": "Vapi" + } + ] + }, "name": { "type": "string", "maxLength": 80 @@ -27081,6 +27747,27 @@ } } }, + "voicemailDetection": { + "description": "This is the voicemail detection plan for the workflow.", + "oneOf": [ + { + "$ref": "#/components/schemas/GoogleVoicemailDetectionPlan", + "title": "Google" + }, + { + "$ref": "#/components/schemas/OpenAIVoicemailDetectionPlan", + "title": "OpenAI" + }, + { + "$ref": "#/components/schemas/TwilioVoicemailDetectionPlan", + "title": "Twilio" + }, + { + "$ref": "#/components/schemas/VapiVoicemailDetectionPlan", + "title": "Vapi" + } + ] + }, "name": { "type": "string", "maxLength": 80 @@ -28079,6 +28766,7 @@ "call.in-progress.error-providerfault-vapi-500-server-error", "call.in-progress.error-providerfault-vapi-503-server-overloaded-error", "pipeline-error-deepgram-transcriber-failed", + "pipeline-error-deepgram-transcriber-api-key-missing", "call.in-progress.error-vapifault-deepgram-transcriber-failed", "pipeline-error-gladia-transcriber-failed", "call.in-progress.error-vapifault-gladia-transcriber-failed", @@ -29333,6 +30021,18 @@ } ] }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for the chat. To use a transient squad, use `squad` instead." + }, + "squad": { + "description": "This is the squad that will be used for the chat. To use an existing squad, use `squadId` instead.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] + }, "name": { "type": "string", "description": "This is the name of the chat. This is just for your own reference.", @@ -29499,6 +30199,38 @@ "updatedAt" ] }, + "TwilioSMSChatTransport": { + "type": "object", + "properties": { + "phoneNumberId": { + "type": "string", + "description": "This is the phone number that will be used to send the SMS.\nIf provided, will create a new session. If not provided, uses existing session's phoneNumberId.\nThe phone number must have SMS enabled and belong to your organization." + }, + "customer": { + "description": "This is the customer who will receive the SMS.\nIf provided, will create a new session. If not provided, uses existing session's customer.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateCustomerDTO" + } + ] + }, + "useLLMGeneratedMessageForOutbound": { + "type": "boolean", + "description": "Whether to use LLM-generated messages for outbound SMS.\nWhen true (default), input is processed by the assistant for a response.\nWhen false, the input text is forwarded directly as the SMS message without LLM processing.\nUseful for sending pre-defined messages or notifications.", + "default": true + }, + "type": { + "type": "string", + "description": "The type of transport to use for sending the chat response.\nCurrently supports 'twilio.sms' for SMS delivery via Twilio.", + "enum": [ + "twilio.sms" + ] + } + }, + "required": [ + "type" + ] + }, "CreateChatDTO": { "type": "object", "properties": { @@ -29522,6 +30254,18 @@ } ] }, + "squadId": { + "type": "string", + "description": "This is the squad that will be used for the chat. To use a transient squad, use `squad` instead." + }, + "squad": { + "description": "This is the squad that will be used for the chat. To use an existing squad, use `squadId` instead.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] + }, "name": { "type": "string", "description": "This is the name of the chat. This is just for your own reference.", @@ -29585,6 +30329,14 @@ "previousChatId": { "type": "string", "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." + }, + "transport": { + "description": "This is used to send the chat through a transport like SMS.\nIf transport.phoneNumberId and transport.customer are provided, creates a new session.\nIf sessionId is provided without transport fields, uses existing session data.\nCannot specify both sessionId and transport fields (phoneNumberId/customer) together.", + "allOf": [ + { + "$ref": "#/components/schemas/TwilioSMSChatTransport" + } + ] } }, "required": [ @@ -29598,6 +30350,10 @@ "type": "string", "description": "This is the unique identifier for the assistant that will be used for the chat." }, + "squadId": { + "type": "string", + "description": "This is the unique identifier for the squad that will be used for the chat." + }, "workflowId": { "type": "string", "description": "This is the unique identifier for the workflow that will be used for the chat." @@ -29735,166 +30491,186 @@ } ] }, - "name": { - "type": "string", - "description": "This is the name of the chat. This is just for your own reference.", - "maxLength": 40 - }, - "sessionId": { - "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." - }, - "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.\nThis field is REQUIRED for chat creation.", - "oneOf": [ - { - "type": "string", - "title": "String" - }, - { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/SystemMessage", - "title": "SystemMessage" - }, - { - "$ref": "#/components/schemas/UserMessage", - "title": "UserMessage" - }, - { - "$ref": "#/components/schemas/AssistantMessage", - "title": "AssistantMessage" - }, - { - "$ref": "#/components/schemas/ToolMessage", - "title": "ToolMessage" - }, - { - "$ref": "#/components/schemas/DeveloperMessage", - "title": "DeveloperMessage" - } - ] - }, - "title": "MessageArray" - } - ], - "examples": [ - "Hello, how can you help me?", - [ - { - "role": "user", - "content": "Hello, how can you help me?" - } - ] - ] - }, - "stream": { - "type": "boolean", - "description": "Whether to stream the response or not.", - "default": true - }, - "previousChatId": { - "type": "string", - "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." - } - }, - "required": [ - "input" - ] - }, - "ChatAssistantOverrides": { - "type": "object", - "properties": { - "variableValues": { - "type": "object", - "description": "Variable values for template substitution", - "example": { - "name": "John", - "company": "ACME Corp" - } - } - } - }, - "CreateWebCustomerDTO": { - "type": "object", - "properties": { - "numberE164CheckEnabled": { - "type": "boolean", - "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", - "default": true - }, - "extension": { + "squadId": { "type": "string", - "description": "This is the extension that will be dialed after the call is answered.", - "maxLength": 10, - "example": null + "description": "This is the squad that will be used for the chat. To use a transient squad, use `squad` instead." }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", + "squad": { + "description": "This is the squad that will be used for the chat. To use an existing squad, use `squadId` instead.", "allOf": [ { - "$ref": "#/components/schemas/ChatAssistantOverrides" + "$ref": "#/components/schemas/CreateSquadDTO" } ] }, - "number": { - "type": "string", - "description": "This is the number of the customer.", - "minLength": 3, - "maxLength": 40 - }, - "sipUri": { - "type": "string", - "description": "This is the SIP URI of the customer." - }, "name": { "type": "string", - "description": "This is the name of the customer. This is just for your own reference.\n\nFor SIP inbound calls, this is extracted from the `From` SIP header with format `\"Display Name\" `.", - "maxLength": 40 - }, - "email": { - "type": "string", - "description": "This is the email of the customer.", - "maxLength": 40 - }, - "externalId": { - "type": "string", - "description": "This is the external ID of the customer.", + "description": "This is the name of the chat. This is just for your own reference.", "maxLength": 40 - } - } - }, - "CreateWebChatDTO": { - "type": "object", - "properties": { - "assistantId": { - "type": "string", - "description": "The assistant ID to use for this chat" }, "sessionId": { "type": "string", - "description": "This is the ID of the session that will be used for the chat.\nIf provided, the conversation will continue from the previous state.\nIf not provided or expired, a new session will be created." - }, - "assistantOverrides": { - "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", - "allOf": [ - { - "$ref": "#/components/schemas/ChatAssistantOverrides" - } - ] - }, - "customer": { - "description": "This is the customer information for the chat.\nUsed to automatically manage sessions for repeat customers.", - "allOf": [ - { - "$ref": "#/components/schemas/CreateWebCustomerDTO" - } - ] + "description": "This is the ID of the session that will be used for the chat.\nMutually exclusive with previousChatId." }, "input": { - "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.\nThis field is REQUIRED for chat creation.", + "oneOf": [ + { + "type": "string", + "title": "String" + }, + { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/SystemMessage", + "title": "SystemMessage" + }, + { + "$ref": "#/components/schemas/UserMessage", + "title": "UserMessage" + }, + { + "$ref": "#/components/schemas/AssistantMessage", + "title": "AssistantMessage" + }, + { + "$ref": "#/components/schemas/ToolMessage", + "title": "ToolMessage" + }, + { + "$ref": "#/components/schemas/DeveloperMessage", + "title": "DeveloperMessage" + } + ] + }, + "title": "MessageArray" + } + ], + "examples": [ + "Hello, how can you help me?", + [ + { + "role": "user", + "content": "Hello, how can you help me?" + } + ] + ] + }, + "stream": { + "type": "boolean", + "description": "Whether to stream the response or not.", + "default": true + }, + "previousChatId": { + "type": "string", + "description": "This is the ID of the chat that will be used as context for the new chat.\nThe messages from the previous chat will be used as context.\nMutually exclusive with sessionId." + }, + "transport": { + "description": "This is used to send the chat through a transport like SMS.\nIf transport.phoneNumberId and transport.customer are provided, creates a new session.\nIf sessionId is provided without transport fields, uses existing session data.\nCannot specify both sessionId and transport fields (phoneNumberId/customer) together.", + "allOf": [ + { + "$ref": "#/components/schemas/TwilioSMSChatTransport" + } + ] + } + }, + "required": [ + "input" + ] + }, + "ChatAssistantOverrides": { + "type": "object", + "properties": { + "variableValues": { + "type": "object", + "description": "Variable values for template substitution", + "example": { + "name": "John", + "company": "ACME Corp" + } + } + } + }, + "CreateWebCustomerDTO": { + "type": "object", + "properties": { + "numberE164CheckEnabled": { + "type": "boolean", + "description": "This is the flag to toggle the E164 check for the `number` field. This is an advanced property which should be used if you know your use case requires it.\n\nUse cases:\n- `false`: To allow non-E164 numbers like `+001234567890`, `1234`, or `abc`. This is useful for dialing out to non-E164 numbers on your SIP trunks.\n- `true` (default): To allow only E164 numbers like `+14155551234`. This is standard for PSTN calls.\n\nIf `false`, the `number` is still required to only contain alphanumeric characters (regex: `/^\\+?[a-zA-Z0-9]+$/`).\n\n@default true (E164 check is enabled)", + "default": true + }, + "extension": { + "type": "string", + "description": "This is the extension that will be dialed after the call is answered.", + "maxLength": 10, + "example": null + }, + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", + "allOf": [ + { + "$ref": "#/components/schemas/ChatAssistantOverrides" + } + ] + }, + "number": { + "type": "string", + "description": "This is the number of the customer.", + "minLength": 3, + "maxLength": 40 + }, + "sipUri": { + "type": "string", + "description": "This is the SIP URI of the customer." + }, + "name": { + "type": "string", + "description": "This is the name of the customer. This is just for your own reference.\n\nFor SIP inbound calls, this is extracted from the `From` SIP header with format `\"Display Name\" `.", + "maxLength": 40 + }, + "email": { + "type": "string", + "description": "This is the email of the customer.", + "maxLength": 40 + }, + "externalId": { + "type": "string", + "description": "This is the external ID of the customer.", + "maxLength": 40 + } + } + }, + "CreateWebChatDTO": { + "type": "object", + "properties": { + "assistantId": { + "type": "string", + "description": "The assistant ID to use for this chat" + }, + "sessionId": { + "type": "string", + "description": "This is the ID of the session that will be used for the chat.\nIf provided, the conversation will continue from the previous state.\nIf not provided or expired, a new session will be created." + }, + "assistantOverrides": { + "description": "These are the variable values that will be used to replace template variables in the assistant messages.\nOnly variable substitution is supported in web chat - other assistant properties cannot be overridden.", + "allOf": [ + { + "$ref": "#/components/schemas/ChatAssistantOverrides" + } + ] + }, + "customer": { + "description": "This is the customer information for the chat.\nUsed to automatically manage sessions for repeat customers.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateWebCustomerDTO" + } + ] + }, + "input": { + "description": "This is the input text for the chat.\nCan be a string or an array of chat messages.", "oneOf": [ { "type": "string", @@ -30606,6 +31382,18 @@ } ] }, + "squadId": { + "type": "string", + "description": "This is the squad ID associated with this session. Use this when referencing an existing squad." + }, + "squad": { + "description": "This is the squad configuration for this session. Use this when creating a new squad configuration.\nIf squadId is provided, this will be ignored.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] + }, "messages": { "type": "array", "description": "This is an array of chat messages in the session.", @@ -30697,6 +31485,18 @@ } ] }, + "squadId": { + "type": "string", + "description": "This is the squad ID associated with this session. Use this when referencing an existing squad." + }, + "squad": { + "description": "This is the squad configuration for this session. Use this when creating a new squad configuration.\nIf squadId is provided, this will be ignored.", + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] + }, "messages": { "type": "array", "description": "This is an array of chat messages in the session.", @@ -30811,6 +31611,10 @@ "type": "string", "description": "This is the ID of the assistant to filter sessions by." }, + "squadId": { + "type": "string", + "description": "This is the ID of the squad to filter sessions by." + }, "workflowId": { "type": "string", "description": "This is the ID of the workflow to filter sessions by." @@ -37157,6 +37961,1330 @@ } } }, + "CreateEvalDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMock", + "title": "ChatEvalAssistantMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalSystemMessageMock", + "title": "ChatEvalSystemMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalToolResponseMessageMock", + "title": "ChatEvalToolResponseMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalUserMessageMock", + "title": "ChatEvalUserMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageEvaluation", + "title": "ChatEvalAssistantMessageEvaluation" + } + ] + } + }, + "name": { + "type": "string", + "description": "This is the name of the eval.\nIt helps identify what the eval is checking for.", + "example": "Verified User Flow Eval", + "minLength": 1, + "maxLength": 80 + }, + "description": { + "type": "string", + "description": "This is the description of the eval.\nThis helps describe the eval and its purpose in detail. It will not be used to evaluate the flow of the conversation.", + "example": "This eval checks if the user flow is verified.", + "minLength": 1, + "maxLength": 500 + }, + "type": { + "type": "string", + "description": "This is the type of the eval.\nCurrently it is fixed to `chat.mockConversation`.", + "example": "chat.mockConversation", + "enum": [ + "chat.mockConversation" + ] + } + }, + "required": [ + "messages", + "type" + ] + }, + "Eval": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMock", + "title": "ChatEvalAssistantMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalSystemMessageMock", + "title": "ChatEvalSystemMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalToolResponseMessageMock", + "title": "ChatEvalToolResponseMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalUserMessageMock", + "title": "ChatEvalUserMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageEvaluation", + "title": "ChatEvalAssistantMessageEvaluation" + } + ] + } + }, + "id": { + "type": "string" + }, + "orgId": { + "type": "string" + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "updatedAt": { + "format": "date-time", + "type": "string" + }, + "name": { + "type": "string", + "description": "This is the name of the eval.\nIt helps identify what the eval is checking for.", + "example": "Verified User Flow Eval", + "minLength": 1, + "maxLength": 80 + }, + "description": { + "type": "string", + "description": "This is the description of the eval.\nThis helps describe the eval and its purpose in detail. It will not be used to evaluate the flow of the conversation.", + "example": "This eval checks if the user flow is verified.", + "minLength": 1, + "maxLength": 500 + }, + "type": { + "type": "string", + "description": "This is the type of the eval.\nCurrently it is fixed to `chat.mockConversation`.", + "example": "chat.mockConversation", + "enum": [ + "chat.mockConversation" + ] + } + }, + "required": [ + "messages", + "id", + "orgId", + "createdAt", + "updatedAt", + "type" + ] + }, + "EvalModelListOptions": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider of the model.", + "enum": [ + "openai", + "anthropic", + "google", + "groq", + "custom-llm" + ] + } + }, + "required": [ + "provider" + ] + }, + "EvalUserEditable": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMock", + "title": "ChatEvalAssistantMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalSystemMessageMock", + "title": "ChatEvalSystemMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalToolResponseMessageMock", + "title": "ChatEvalToolResponseMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalUserMessageMock", + "title": "ChatEvalUserMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageEvaluation", + "title": "ChatEvalAssistantMessageEvaluation" + } + ] + } + }, + "name": { + "type": "string", + "description": "This is the name of the eval.\nIt helps identify what the eval is checking for.", + "example": "Verified User Flow Eval", + "minLength": 1, + "maxLength": 80 + }, + "description": { + "type": "string", + "description": "This is the description of the eval.\nThis helps describe the eval and its purpose in detail. It will not be used to evaluate the flow of the conversation.", + "example": "This eval checks if the user flow is verified.", + "minLength": 1, + "maxLength": 500 + }, + "type": { + "type": "string", + "description": "This is the type of the eval.\nCurrently it is fixed to `chat.mockConversation`.", + "example": "chat.mockConversation", + "enum": [ + "chat.mockConversation" + ] + } + }, + "required": [ + "messages", + "type" + ] + }, + "ChatEvalAssistantMessageMockToolCall": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This is the name of the tool that will be called.\nIt should be one of the tools created in the organization.", + "example": "get_weather", + "maxLength": 100 + }, + "arguments": { + "type": "object", + "description": "This is the arguments that will be passed to the tool call.", + "example": "\"{\"city\": \"San Francisco\"}\"" + } + }, + "required": [ + "name" + ] + }, + "ChatEvalAssistantMessageMock": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "assistant" + ], + "description": "This is the role of the message author.\nFor a mock assistant message, the role is always 'assistant'\n@default 'assistant'", + "default": "assistant" + }, + "content": { + "type": "string", + "description": "This is the content of the assistant message.\nThis is the message that the assistant would have sent.", + "example": "The weather in San Francisco is sunny.", + "maxLength": 1000 + }, + "toolCalls": { + "description": "This is the tool calls that will be made by the assistant.", + "example": "[{ name: \"get_weather\", arguments: { city: \"San Francisco\" } }]", + "type": "array", + "items": { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMockToolCall" + } + } + }, + "required": [ + "role" + ] + }, + "ChatEvalSystemMessageMock": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "system" + ], + "description": "This is the role of the message author.\nFor a mock system message, the role is always 'system'\n@default 'system'", + "default": "system" + }, + "content": { + "type": "string", + "description": "This is the content of the system message that would have been added in the middle of the conversation.\nDo not include the assistant prompt as a part of this message. It will automatically be fetched during runtime.", + "example": "You are a helpful assistant.", + "maxLength": 1000 + } + }, + "required": [ + "role", + "content" + ] + }, + "ChatEvalToolResponseMessageMock": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "tool" + ], + "description": "This is the role of the message author.\nFor a mock tool response message, the role is always 'tool'\n@default 'tool'", + "default": "tool" + }, + "content": { + "type": "string", + "description": "This is the content of the tool response message. JSON Objects should be stringified.", + "examples": [ + "The weather in San Francisco is sunny.", + "{weather: sunny}" + ], + "maxLength": 1000 + } + }, + "required": [ + "role", + "content" + ] + }, + "ChatEvalUserMessageMock": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "user" + ], + "description": "This is the role of the message author.\nFor a mock user message, the role is always 'user'\n@default 'user'", + "default": "user" + }, + "content": { + "type": "string", + "description": "This is the content of the user message.\nThis is the message that the user would have sent.", + "example": "Hello, how are you?", + "maxLength": 1000 + } + }, + "required": [ + "role", + "content" + ] + }, + "AssistantMessageEvaluationContinuePlan": { + "type": "object", + "properties": { + "exitOnFailureEnabled": { + "type": "boolean", + "description": "This is whether the evaluation should exit if the assistant message evaluates to false.\nBy default, it is false and the evaluation will continue.\n@default false", + "default": false + }, + "contentOverride": { + "type": "string", + "description": "This is the content that will be used in the conversation for this assistant turn if provided.\nIt will override the content received from the model.", + "example": "The weather in San Francisco is sunny.", + "maxLength": 1000 + }, + "toolCallsOverride": { + "description": "This is the tool calls that will be used in the conversation for this assistant turn if provided.\nIt will override the tool calls received from the model.", + "example": "[{ name: \"get_weather\", arguments: { city: \"San Francisco\" } }]", + "type": "array", + "items": { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMockToolCall" + } + } + }, + "required": [ + "exitOnFailureEnabled" + ] + }, + "ChatEvalAssistantMessageEvaluation": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "assistant" + ], + "description": "This is the role of the message author.\nFor an assistant message evaluation, the role is always 'assistant'\n@default 'assistant'", + "default": "assistant" + }, + "judgePlan": { + "description": "This is the judge plan that instructs how to evaluate the assistant message.\nThe assistant message can be evaluated against fixed content (exact match or RegEx) or with an LLM-as-judge by defining the evaluation criteria in a prompt.", + "oneOf": [ + { + "$ref": "#/components/schemas/AssistantMessageJudgePlanExact", + "title": "AssistantMessageJudgePlanExact" + }, + { + "$ref": "#/components/schemas/AssistantMessageJudgePlanRegex", + "title": "AssistantMessageJudgePlanRegex" + }, + { + "$ref": "#/components/schemas/AssistantMessageJudgePlanAI", + "title": "AssistantMessageJudgePlanAI" + } + ] + }, + "continuePlan": { + "description": "This is the plan for how the overall evaluation will proceed after the assistant message is evaluated.\nThis lets you configure whether to stop the evaluation if this message fails, and whether to override any content for future turns", + "allOf": [ + { + "$ref": "#/components/schemas/AssistantMessageEvaluationContinuePlan" + } + ] + } + }, + "required": [ + "role", + "judgePlan" + ] + }, + "AssistantMessageJudgePlanExact": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "exact" + ], + "description": "This is the type of the judge plan.\nUse 'exact' for an exact match on the content and tool calls - without using LLM-as-a-judge.\n@default 'exact'" + }, + "content": { + "type": "string", + "description": "This is what that will be used to evaluate the model's message content.\nIf you provide a string, the assistant message content will be evaluated against it as an exact match, case-insensitive.", + "example": "The weather in San Francisco is sunny.", + "maxLength": 1000 + }, + "toolCalls": { + "description": "This is the tool calls that will be used to evaluate the model's message content.\nThe tool name must be a valid tool that the assistant is allowed to call.\n\nFor the Query tool, the arguments for the tool call are in the format - {knowledgeBaseNames: ['kb_name', 'kb_name_2']}\n\nFor the DTMF tool, the arguments for the tool call are in the format - {dtmf: \"1234*\"}\n\nFor the Handoff tool, the arguments for the tool call are in the format - {destination: \"assistant_id\"}\n\nFor the Transfer Call tool, the arguments for the tool call are in the format - {destination: \"phone_number_or_assistant_id\"}\n\nFor all other tools, they are called without arguments or with user-defined arguments", + "example": "[{ name: \"get_weather\", arguments: { city: \"San Francisco\" } }]", + "type": "array", + "items": { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMockToolCall" + } + } + }, + "required": [ + "type", + "content" + ] + }, + "EvalOpenAIModel": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider of the model (`openai`).", + "enum": [ + "openai" + ] + }, + "model": { + "type": "string", + "description": "This is the OpenAI model that will be used.\n\nWhen using Vapi OpenAI or your own Azure Credentials, you have the option to specify the region for the selected model. This shouldn't be specified unless you have a specific reason to do so. Vapi will automatically find the fastest region that make sense.\nThis is helpful when you are required to comply with Data Residency rules. Learn more about Azure regions here https://azure.microsoft.com/en-us/explore/global-infrastructure/data-residency/.", + "maxLength": 100, + "enum": [ + "gpt-5", + "gpt-5-mini", + "gpt-5-nano", + "gpt-4.1-2025-04-14", + "gpt-4.1-mini-2025-04-14", + "gpt-4.1-nano-2025-04-14", + "gpt-4.1", + "gpt-4.1-mini", + "gpt-4.1-nano", + "chatgpt-4o-latest", + "o3", + "o3-mini", + "o4-mini", + "o1-mini", + "o1-mini-2024-09-12", + "gpt-4o-mini-2024-07-18", + "gpt-4o-mini", + "gpt-4o", + "gpt-4o-2024-05-13", + "gpt-4o-2024-08-06", + "gpt-4o-2024-11-20", + "gpt-4-turbo", + "gpt-4-turbo-2024-04-09", + "gpt-4-turbo-preview", + "gpt-4-0125-preview", + "gpt-4-1106-preview", + "gpt-4", + "gpt-4-0613", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125", + "gpt-3.5-turbo-1106", + "gpt-3.5-turbo-16k", + "gpt-3.5-turbo-0613", + "gpt-4.1-2025-04-14:westus", + "gpt-4.1-2025-04-14:eastus2", + "gpt-4.1-2025-04-14:eastus", + "gpt-4.1-2025-04-14:westus3", + "gpt-4.1-2025-04-14:northcentralus", + "gpt-4.1-2025-04-14:southcentralus", + "gpt-4.1-mini-2025-04-14:westus", + "gpt-4.1-mini-2025-04-14:eastus2", + "gpt-4.1-mini-2025-04-14:eastus", + "gpt-4.1-mini-2025-04-14:westus3", + "gpt-4.1-mini-2025-04-14:northcentralus", + "gpt-4.1-mini-2025-04-14:southcentralus", + "gpt-4.1-nano-2025-04-14:westus", + "gpt-4.1-nano-2025-04-14:eastus2", + "gpt-4.1-nano-2025-04-14:westus3", + "gpt-4.1-nano-2025-04-14:northcentralus", + "gpt-4.1-nano-2025-04-14:southcentralus", + "gpt-4o-2024-11-20:swedencentral", + "gpt-4o-2024-11-20:westus", + "gpt-4o-2024-11-20:eastus2", + "gpt-4o-2024-11-20:eastus", + "gpt-4o-2024-11-20:westus3", + "gpt-4o-2024-11-20:southcentralus", + "gpt-4o-2024-08-06:westus", + "gpt-4o-2024-08-06:westus3", + "gpt-4o-2024-08-06:eastus", + "gpt-4o-2024-08-06:eastus2", + "gpt-4o-2024-08-06:northcentralus", + "gpt-4o-2024-08-06:southcentralus", + "gpt-4o-mini-2024-07-18:westus", + "gpt-4o-mini-2024-07-18:westus3", + "gpt-4o-mini-2024-07-18:eastus", + "gpt-4o-mini-2024-07-18:eastus2", + "gpt-4o-mini-2024-07-18:northcentralus", + "gpt-4o-mini-2024-07-18:southcentralus", + "gpt-4o-2024-05-13:eastus2", + "gpt-4o-2024-05-13:eastus", + "gpt-4o-2024-05-13:northcentralus", + "gpt-4o-2024-05-13:southcentralus", + "gpt-4o-2024-05-13:westus3", + "gpt-4o-2024-05-13:westus", + "gpt-4-turbo-2024-04-09:eastus2", + "gpt-4-0125-preview:eastus", + "gpt-4-0125-preview:northcentralus", + "gpt-4-0125-preview:southcentralus", + "gpt-4-1106-preview:australia", + "gpt-4-1106-preview:canadaeast", + "gpt-4-1106-preview:france", + "gpt-4-1106-preview:india", + "gpt-4-1106-preview:norway", + "gpt-4-1106-preview:swedencentral", + "gpt-4-1106-preview:uk", + "gpt-4-1106-preview:westus", + "gpt-4-1106-preview:westus3", + "gpt-4-0613:canadaeast", + "gpt-3.5-turbo-0125:canadaeast", + "gpt-3.5-turbo-0125:northcentralus", + "gpt-3.5-turbo-0125:southcentralus", + "gpt-3.5-turbo-1106:canadaeast", + "gpt-3.5-turbo-1106:westus" + ] + }, + "temperature": { + "type": "number", + "description": "This is the temperature of the model. For LLM-as-a-judge, it's recommended to set it between 0 - 0.3 to avoid hallucinations and ensure the model judges the output correctly based on the instructions.", + "minimum": 0, + "maximum": 2 + }, + "maxTokens": { + "type": "number", + "description": "This is the max tokens of the model.\nIf your Judge instructions return `true` or `false` takes only 1 token (as per the OpenAI Tokenizer), and therefore is recommended to set it to a low number to force the model to return a short response.", + "minimum": 50, + "maximum": 10000 + } + }, + "required": [ + "provider", + "model" + ] + }, + "EvalAnthropicModel": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider of the model (`anthropic`).", + "enum": [ + "anthropic" + ] + }, + "model": { + "type": "string", + "description": "This is the specific model that will be used.", + "maxLength": 100, + "enum": [ + "claude-3-opus-20240229", + "claude-3-sonnet-20240229", + "claude-3-haiku-20240307", + "claude-3-5-sonnet-20240620", + "claude-3-5-sonnet-20241022", + "claude-3-5-haiku-20241022", + "claude-3-7-sonnet-20250219", + "claude-opus-4-20250514", + "claude-sonnet-4-20250514" + ] + }, + "thinking": { + "description": "This is the optional configuration for Anthropic's thinking feature.\n\n- Only applicable for `claude-3-7-sonnet-20250219` model.\n- If provided, `maxTokens` must be greater than `thinking.budgetTokens`.", + "allOf": [ + { + "$ref": "#/components/schemas/AnthropicThinkingConfig" + } + ] + }, + "temperature": { + "type": "number", + "description": "This is the temperature of the model. For LLM-as-a-judge, it's recommended to set it between 0 - 0.3 to avoid hallucinations and ensure the model judges the output correctly based on the instructions.", + "minimum": 0, + "maximum": 2 + }, + "maxTokens": { + "type": "number", + "description": "This is the max tokens of the model.\nIf your Judge instructions return `true` or `false` takes only 1 token (as per the OpenAI Tokenizer), and therefore is recommended to set it to a low number to force the model to return a short response.", + "minimum": 50, + "maximum": 10000 + } + }, + "required": [ + "provider", + "model" + ] + }, + "EvalGoogleModel": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider of the model (`google`).", + "enum": [ + "google" + ] + }, + "model": { + "type": "string", + "description": "This is the name of the model. Ex. gpt-4o", + "maxLength": 100, + "enum": [ + "gemini-2.5-pro", + "gemini-2.5-flash", + "gemini-2.5-flash-lite", + "gemini-2.0-flash-thinking-exp", + "gemini-2.0-pro-exp-02-05", + "gemini-2.0-flash", + "gemini-2.0-flash-lite", + "gemini-2.0-flash-exp", + "gemini-2.0-flash-realtime-exp", + "gemini-1.5-flash", + "gemini-1.5-flash-002", + "gemini-1.5-pro", + "gemini-1.5-pro-002", + "gemini-1.0-pro" + ] + }, + "temperature": { + "type": "number", + "description": "This is the temperature of the model. For LLM-as-a-judge, it's recommended to set it between 0 - 0.3 to avoid hallucinations and ensure the model judges the output correctly based on the instructions.", + "minimum": 0, + "maximum": 2 + }, + "maxTokens": { + "type": "number", + "description": "This is the max tokens of the model.\nIf your Judge instructions return `true` or `false` takes only 1 token (as per the OpenAI Tokenizer), and therefore is recommended to set it to a low number to force the model to return a short response.", + "minimum": 50, + "maximum": 10000 + } + }, + "required": [ + "provider", + "model" + ] + }, + "EvalGroqModel": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider of the model (`groq`).", + "enum": [ + "groq" + ] + }, + "model": { + "type": "string", + "description": "This is the name of the model. Ex. gpt-4o", + "maxLength": 100, + "enum": [ + "openai/gpt-oss-20b", + "openai/gpt-oss-120b", + "deepseek-r1-distill-llama-70b", + "llama-3.3-70b-versatile", + "llama-3.1-405b-reasoning", + "llama-3.1-8b-instant", + "llama3-8b-8192", + "llama3-70b-8192", + "gemma2-9b-it", + "moonshotai/kimi-k2-instruct-0905", + "meta-llama/llama-4-maverick-17b-128e-instruct", + "meta-llama/llama-4-scout-17b-16e-instruct", + "mistral-saba-24b", + "compound-beta", + "compound-beta-mini" + ] + }, + "temperature": { + "type": "number", + "description": "This is the temperature of the model. For LLM-as-a-judge, it's recommended to set it between 0 - 0.3 to avoid hallucinations and ensure the model judges the output correctly based on the instructions.", + "minimum": 0, + "maximum": 2 + }, + "maxTokens": { + "type": "number", + "description": "This is the max tokens of the model.\nIf your Judge instructions return `true` or `false` takes only 1 token (as per the OpenAI Tokenizer), and therefore is recommended to set it to a low number to force the model to return a short response.", + "minimum": 50, + "maximum": 10000 + } + }, + "required": [ + "provider", + "model" + ] + }, + "EvalCustomModel": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "description": "This is the provider of the model (`custom-llm`).", + "enum": [ + "custom-llm" + ] + }, + "url": { + "type": "string", + "description": "These is the URL we'll use for the OpenAI client's `baseURL`. Ex. https://openrouter.ai/api/v1" + }, + "headers": { + "type": "object", + "description": "These are the headers we'll use for the OpenAI client's `headers`." + }, + "timeoutSeconds": { + "type": "number", + "description": "This sets the timeout for the connection to the custom provider without needing to stream any tokens back. Default is 20 seconds.", + "minimum": 20, + "maximum": 600 + }, + "model": { + "type": "string", + "description": "This is the name of the model. Ex. gpt-4o", + "maxLength": 100 + }, + "temperature": { + "type": "number", + "description": "This is the temperature of the model. For LLM-as-a-judge, it's recommended to set it between 0 - 0.3 to avoid hallucinations and ensure the model judges the output correctly based on the instructions.", + "minimum": 0, + "maximum": 2 + }, + "maxTokens": { + "type": "number", + "description": "This is the max tokens of the model.\nIf your Judge instructions return `true` or `false` takes only 1 token (as per the OpenAI Tokenizer), and therefore is recommended to set it to a low number to force the model to return a short response.", + "minimum": 50, + "maximum": 10000 + } + }, + "required": [ + "provider", + "url", + "model" + ] + }, + "AssistantMessageJudgePlanAI": { + "type": "object", + "properties": { + "model": { + "description": "This is the model to use for the LLM-as-a-judge.\nIf not provided, will default to the assistant's model.\n\nThe instructions on how to evaluate the model output with this LLM-Judge must be passed as a system message in the messages array of the model.\n\nThe Mock conversation can be passed to the LLM-Judge to evaluate using the prompt {{messages}} and will be evaluated as a LiquidJS Variable. To access and judge only the last message, use {{messages[-1]}}\n\nThe LLM-Judge must respond with \"pass\" or \"fail\" and only those two responses are allowed.", + "example": "{", + "oneOf": [ + { + "$ref": "#/components/schemas/EvalOpenAIModel", + "title": "EvalOpenAIModel" + }, + { + "$ref": "#/components/schemas/EvalAnthropicModel", + "title": "EvalAnthropicModel" + }, + { + "$ref": "#/components/schemas/EvalGoogleModel", + "title": "EvalGoogleModel" + }, + { + "$ref": "#/components/schemas/EvalCustomModel", + "title": "EvalCustomModel" + } + ] + }, + "type": { + "type": "string", + "enum": [ + "ai" + ], + "description": "This is the type of the judge plan.\nUse 'ai' to evaluate the assistant message content using LLM-as-a-judge.\n@default 'ai'" + } + }, + "required": [ + "model", + "type" + ] + }, + "AssistantMessageJudgePlanRegex": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "regex" + ], + "description": "This is the type of the judge plan.\nUse 'regex' for a regex match on the content and tool calls - without using LLM-as-a-judge.\n@default 'regex'" + }, + "content": { + "type": "string", + "description": "This is what that will be used to evaluate the model's message content.\nThe content will be evaluated against the regex pattern provided in the Judge Plan content field.\nEvaluation is considered successful if the regex pattern matches any part of the assistant message content.", + "example": "/sunny/i", + "maxLength": 1000 + }, + "toolCalls": { + "description": "This is the tool calls that will be used to evaluate the model's message content.\nThe tool name must be a valid tool that the assistant is allowed to call.\nThe values to the arguments for the tool call should be a Regular Expression.\nEvaluation is considered successful if the regex pattern matches any part of each tool call argument.\n\nFor the Query tool, the arguments for the tool call are in the format - {knowledgeBaseNames: ['kb_name', 'kb_name_2']}\n\nFor the DTMF tool, the arguments for the tool call are in the format - {dtmf: \"1234*\"}\n\nFor the Handoff tool, the arguments for the tool call are in the format - {destination: \"assistant_id\"}\n\nFor the Transfer Call tool, the arguments for the tool call are in the format - {destination: \"phone_number_or_assistant_id\"}\n\nFor all other tools, they are called without arguments or with user-defined arguments", + "example": "[{ name: \"get_weather\", arguments: { city: \"/San Francisco/i\" } }]", + "type": "array", + "items": { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMockToolCall" + } + } + }, + "required": [ + "type", + "content" + ] + }, + "GetEvalPaginatedDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "page": { + "type": "number", + "description": "This is the page number to return. Defaults to 1.", + "minimum": 1 + }, + "sortOrder": { + "type": "string", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "enum": [ + "ASC", + "DESC" + ] + }, + "limit": { + "type": "number", + "description": "This is the maximum number of items to return. Defaults to 100.", + "minimum": 0, + "maximum": 1000 + }, + "createdAtGt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is greater than the specified value." + }, + "createdAtLt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is less than the specified value." + }, + "createdAtGe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is greater than or equal to the specified value." + }, + "createdAtLe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is less than or equal to the specified value." + }, + "updatedAtGt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is greater than the specified value." + }, + "updatedAtLt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is less than the specified value." + }, + "updatedAtGe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is greater than or equal to the specified value." + }, + "updatedAtLe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is less than or equal to the specified value." + } + } + }, + "EvalPaginatedResponse": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Eval" + } + }, + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" + } + }, + "required": [ + "results", + "metadata" + ] + }, + "UpdateEvalDTO": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMock", + "title": "ChatEvalAssistantMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalSystemMessageMock", + "title": "ChatEvalSystemMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalToolResponseMessageMock", + "title": "ChatEvalToolResponseMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalUserMessageMock", + "title": "ChatEvalUserMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageEvaluation", + "title": "ChatEvalAssistantMessageEvaluation" + } + ] + } + }, + "name": { + "type": "string", + "description": "This is the name of the eval.\nIt helps identify what the eval is checking for.", + "example": "Verified User Flow Eval", + "minLength": 1, + "maxLength": 80 + }, + "description": { + "type": "string", + "description": "This is the description of the eval.\nThis helps describe the eval and its purpose in detail. It will not be used to evaluate the flow of the conversation.", + "example": "This eval checks if the user flow is verified.", + "minLength": 1, + "maxLength": 500 + }, + "type": { + "type": "string", + "description": "This is the type of the eval.\nCurrently it is fixed to `chat.mockConversation`.", + "example": "chat.mockConversation", + "enum": [ + "chat.mockConversation" + ] + } + } + }, + "EvalRunTargetAssistant": { + "type": "object", + "properties": { + "assistant": { + "description": "This is the transient assistant that will be run against the eval", + "oneOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO", + "title": "CreateAssistantDTO" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } + ] + }, + "assistantOverrides": { + "description": "This is the overrides that will be applied to the assistant.", + "example": "{", + "oneOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides", + "title": "AssistantOverrides" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } + ] + }, + "type": { + "type": "string", + "description": "This is the type of the target.\nCurrently it is fixed to `assistant`.", + "example": "assistant", + "enum": [ + "assistant" + ] + }, + "assistantId": { + "type": "string", + "description": "This is the id of the assistant that will be run against the eval", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "required": [ + "type" + ] + }, + "CreateEvalRunDTO": { + "type": "object", + "properties": { + "eval": { + "description": "This is the transient eval that will be run", + "oneOf": [ + { + "$ref": "#/components/schemas/CreateEvalDTO", + "title": "CreateEvalDTO" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/Eval" + } + ] + }, + "target": { + "description": "This is the target that will be run against the eval", + "oneOf": [ + { + "$ref": "#/components/schemas/EvalRunTargetAssistant", + "title": "EvalRunTargetAssistant" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/EvalRunTargetAssistant" + } + ] + }, + "type": { + "type": "string", + "description": "This is the type of the run.\nCurrently it is fixed to `eval`.", + "example": "eval", + "enum": [ + "eval" + ] + }, + "evalId": { + "type": "string", + "description": "This is the id of the eval that will be run.", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "required": [ + "target", + "type" + ] + }, + "EvalRunResult": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "This is the status of the eval run result.\nThe status is only 'pass' or 'fail' for an eval run result.\nCurrently, An eval is considered `pass` only if all the Assistant Judge messages are evaluated to pass.", + "example": "pass", + "enum": [ + "pass", + "fail" + ] + }, + "messages": { + "type": "array", + "description": "This is the messages of the eval run result.\nIt contains the user/system messages", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/ChatEvalUserMessageMock", + "title": "ChatEvalUserMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalSystemMessageMock", + "title": "ChatEvalSystemMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalToolResponseMessageMock", + "title": "ChatEvalToolResponseMessageMock" + }, + { + "$ref": "#/components/schemas/ChatEvalAssistantMessageMock", + "title": "ChatEvalAssistantMessageMock" + } + ] + } + }, + "startedAt": { + "format": "date-time", + "type": "string", + "description": "This is the start time of the eval run result.", + "example": "2021-01-01T00:00:00.000Z" + }, + "endedAt": { + "format": "date-time", + "type": "string", + "description": "This is the end time of the eval run result.", + "example": "2021-01-01T00:00:00.000Z" + } + }, + "required": [ + "status", + "messages", + "startedAt", + "endedAt" + ] + }, + "EvalRun": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "This is the status of the eval run. When an eval run is created, the status is 'running'.\nWhen the eval run is completed, the status is 'ended'.", + "example": "running", + "enum": [ + "running", + "ended", + "queued" + ] + }, + "endedReason": { + "type": "string", + "description": "This is the reason for the eval run to end.\nWhen the eval run is completed normally i.e end of mock conversation, the status is 'mockConversation.done'.\nWhen the eval fails due to an error like Chat error or incorrect configuration, the status is 'error'.\nWhen the eval runs for too long, due to model issues or tool call issues, the status is 'timeout'.\nWhen the eval run is cancelled by the user, the status is 'cancelled'.\nWhen the eval run is cancelled by Vapi for any reason, the status is 'aborted'.", + "example": "mockConversation.done", + "enum": [ + "mockConversation.done", + "error", + "timeout", + "cancelled", + "aborted" + ] + }, + "eval": { + "description": "This is the transient eval that will be run", + "oneOf": [ + { + "$ref": "#/components/schemas/CreateEvalDTO", + "title": "CreateEvalDTO" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/Eval" + } + ] + }, + "target": { + "description": "This is the target that will be run against the eval", + "oneOf": [ + { + "$ref": "#/components/schemas/EvalRunTargetAssistant", + "title": "EvalRunTargetAssistant" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/EvalRunTargetAssistant" + } + ] + }, + "id": { + "type": "string" + }, + "orgId": { + "type": "string" + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "startedAt": { + "format": "date-time", + "type": "string" + }, + "endedAt": { + "format": "date-time", + "type": "string" + }, + "endedMessage": { + "type": "string", + "description": "This is the ended message when the eval run ended for any reason apart from mockConversation.done", + "example": "The Assistant returned an error" + }, + "results": { + "description": "This is the results of the eval or suite run.\nThe array will have a single item for an eval run, and multiple items each corresponding to the an eval in a suite run in the same order as the evals in the suite.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EvalRunResult" + } + }, + "type": { + "type": "string", + "description": "This is the type of the run.\nCurrently it is fixed to `eval`.", + "example": "eval", + "enum": [ + "eval" + ] + }, + "evalId": { + "type": "string", + "description": "This is the id of the eval that will be run.", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "required": [ + "status", + "endedReason", + "target", + "id", + "orgId", + "createdAt", + "startedAt", + "endedAt", + "results", + "type" + ] + }, + "EvalRunPaginatedResponse": { + "type": "object", + "properties": { + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EvalRun" + } + }, + "metadata": { + "$ref": "#/components/schemas/PaginationMeta" + } + }, + "required": [ + "results", + "metadata" + ] + }, + "GetEvalRunPaginatedDTO": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "page": { + "type": "number", + "description": "This is the page number to return. Defaults to 1.", + "minimum": 1 + }, + "sortOrder": { + "type": "string", + "description": "This is the sort order for pagination. Defaults to 'DESC'.", + "enum": [ + "ASC", + "DESC" + ] + }, + "limit": { + "type": "number", + "description": "This is the maximum number of items to return. Defaults to 100.", + "minimum": 0, + "maximum": 1000 + }, + "createdAtGt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is greater than the specified value." + }, + "createdAtLt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is less than the specified value." + }, + "createdAtGe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is greater than or equal to the specified value." + }, + "createdAtLe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the createdAt is less than or equal to the specified value." + }, + "updatedAtGt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is greater than the specified value." + }, + "updatedAtLt": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is less than the specified value." + }, + "updatedAtGe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is greater than or equal to the specified value." + }, + "updatedAtLe": { + "format": "date-time", + "type": "string", + "description": "This will return items where the updatedAt is less than or equal to the specified value." + } + } + }, "CreateOrgDTO": { "type": "object", "properties": { @@ -45450,6 +47578,7 @@ "call.in-progress.error-providerfault-vapi-500-server-error", "call.in-progress.error-providerfault-vapi-503-server-overloaded-error", "pipeline-error-deepgram-transcriber-failed", + "pipeline-error-deepgram-transcriber-api-key-missing", "call.in-progress.error-vapifault-deepgram-transcriber-failed", "pipeline-error-gladia-transcriber-failed", "call.in-progress.error-vapifault-gladia-transcriber-failed", @@ -46644,6 +48773,7 @@ "call.in-progress.error-providerfault-vapi-500-server-error", "call.in-progress.error-providerfault-vapi-503-server-overloaded-error", "pipeline-error-deepgram-transcriber-failed", + "pipeline-error-deepgram-transcriber-api-key-missing", "call.in-progress.error-vapifault-deepgram-transcriber-failed", "pipeline-error-gladia-transcriber-failed", "call.in-progress.error-vapifault-gladia-transcriber-failed", From 03617d23c782d070348e37981a0896292d205025 Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:54:46 +0530 Subject: [PATCH 017/171] Add Gladia as a multilingual transcriber option (#668) Co-authored-by: Cursor Agent Co-authored-by: sahil --- fern/customization/multilingual.mdx | 16 ++++++++-------- fern/providers/transcriber/gladia.mdx | 7 ++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/fern/customization/multilingual.mdx b/fern/customization/multilingual.mdx index 07dc4c289..403428831 100644 --- a/fern/customization/multilingual.mdx +++ b/fern/customization/multilingual.mdx @@ -16,7 +16,7 @@ Configure your voice assistant to communicate in multiple languages with automat - Test and optimize multilingual performance -**Multilingual Support:** Multiple providers support automatic language detection. **Deepgram** (Nova 2, Nova 3 with "Multi" setting) and **Google STT** (with "Multilingual" setting) both offer automatic language detection for seamless multilingual conversations. +**Multilingual Support:** Multiple providers support automatic language detection. **Deepgram** (Nova 2, Nova 3 with "Multi" setting), **Google STT** (with "Multilingual" setting), and **Gladia** (automatic language detection) all offer seamless multilingual conversations. ## Configure automatic language detection @@ -28,10 +28,10 @@ Set up your transcriber to automatically detect and process multiple languages. 1. Navigate to **Assistants** in your [Vapi Dashboard](https://dashboard.vapi.ai/) 2. Create a new assistant or edit an existing one 3. In the **Transcriber** section: - - **Provider**: Select `Deepgram` (recommended) or `Google` - - **Model**: For Deepgram, choose `Nova 2` or `Nova 3`; for Google, choose `Latest` - - **Language**: Set to `Multi` (Deepgram) or `Multilingual` (Google) - 4. **Other providers**: Single language only, no automatic detection + - **Provider**: Select `Deepgram` (recommended), `Google`, or `Gladia` + - **Model**: For Deepgram, choose `Nova 2` or `Nova 3`; for Google, choose `Latest`; for Gladia, choose your preferred Gladia model + - **Language / Mode**: Set `Multi` (Deepgram), `Multilingual` (Google), or enable automatic language detection (Gladia) + 4. **Other providers**: May require a single language and not auto-detect 5. Click **Save** to apply the configuration @@ -114,7 +114,7 @@ Set up your transcriber to automatically detect and process multiple languages. -**Provider Performance:** **Deepgram** offers the best balance of speed and multilingual accuracy. **Google** provides broader language support but may be slower. Both providers support automatic language detection within conversations. +**Provider Performance:** **Deepgram** offers the best balance of speed and multilingual accuracy. **Google** provides broader language support but may be slower. **Gladia** offers excellent automatic language recognition and code-switching with strong accuracy reported by customers. All three support automatic language detection within conversations. ## Set up multilingual voices @@ -463,7 +463,7 @@ Validate your configuration with different languages and scenarios. | **Assembly AI** | ❌ English only | English | No multilingual support | | **Azure STT** | ❌ Single language | 100+ | Many languages, but no auto-detection | | **OpenAI Whisper** | ❌ Single language | 90+ | Many languages, but no auto-detection | -| **Gladia** | ❌ Single language | 80+ | Many languages, but no auto-detection | +| **Gladia** | ✅ Full auto-detection | 90+ | Supports automatic language detection and code-switching | | **Speechmatics** | ❌ Single language | 50+ | Many languages, but no auto-detection | | **Talkscriber** | ❌ Single language | 40+ | Many languages, but no auto-detection | @@ -481,7 +481,7 @@ Validate your configuration with different languages and scenarios. **Solutions:** - - Use Deepgram (Nova 2/Nova 3 with "Multi") or Google STT (with "Multilingual") + - Use Deepgram (Nova 2/Nova 3 with "Multi"), Google STT (with "Multilingual"), or Gladia (automatic language detection) - Ensure high-quality audio input for better detection accuracy - Test with native speakers of target languages - Consider provider-specific language combinations for optimal results diff --git a/fern/providers/transcriber/gladia.mdx b/fern/providers/transcriber/gladia.mdx index d3797e787..12780e10f 100644 --- a/fern/providers/transcriber/gladia.mdx +++ b/fern/providers/transcriber/gladia.mdx @@ -21,7 +21,7 @@ Gladia provides a comprehensive suite of AI-driven tools: **Speech-to-Text:** -Gladia’s core offering is its AI-powered speech-to-text technology, delivering highly accurate and real-time transcription. This service supports 99 languages and includes speaker diarization and code-switching. +Gladia’s core offering is its AI-powered speech-to-text technology, delivering highly accurate and real-time transcription. This service supports automatic language detection (including code‑switching within a conversation) and 90+ languages, and includes speaker diarization. **Audio Intelligence:** @@ -54,8 +54,9 @@ Gladia excels in providing real-time transcription and translation: **Multilingual Support:** -- 99 Languages: Supports a wide range of languages and dialects. -- Real-time Translation: Near-instantaneous translation for diverse applications. +- Automatic language recognition: Detects the spoken language automatically and handles code‑switching +- 90+ languages: Supports a wide range of languages and dialects +- Real-time Translation: Near-instantaneous translation for diverse applications **Use Cases:** From f537f75cda8c7617eb93efea92822f9bb3d84927 Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:53:34 +0530 Subject: [PATCH 018/171] Update multilingual.mdx --- fern/customization/multilingual.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fern/customization/multilingual.mdx b/fern/customization/multilingual.mdx index 403428831..cfef4bb88 100644 --- a/fern/customization/multilingual.mdx +++ b/fern/customization/multilingual.mdx @@ -463,7 +463,7 @@ Validate your configuration with different languages and scenarios. | **Assembly AI** | ❌ English only | English | No multilingual support | | **Azure STT** | ❌ Single language | 100+ | Many languages, but no auto-detection | | **OpenAI Whisper** | ❌ Single language | 90+ | Many languages, but no auto-detection | -| **Gladia** | ✅ Full auto-detection | 90+ | Supports automatic language detection and code-switching | +| **Gladia** | ✅ Full auto-detection | 110+ | Supports automatic language detection and code-switching | | **Speechmatics** | ❌ Single language | 50+ | Many languages, but no auto-detection | | **Talkscriber** | ❌ Single language | 40+ | Many languages, but no auto-detection | From 2b1a094f8eeec120a001333854d6ec0bee542331 Mon Sep 17 00:00:00 2001 From: Sri Date: Mon, 8 Sep 2025 15:22:57 -0700 Subject: [PATCH 019/171] added warm transfer props --- fern/calls/assistant-based-warm-transfer.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fern/calls/assistant-based-warm-transfer.mdx b/fern/calls/assistant-based-warm-transfer.mdx index 1e7d3ce33..aec4bbdbc 100644 --- a/fern/calls/assistant-based-warm-transfer.mdx +++ b/fern/calls/assistant-based-warm-transfer.mdx @@ -53,6 +53,7 @@ The `function.name` property identifies your transfer tool. Use this name when i "transferAssistant": { "firstMessage": "Hello, I have a customer on the line. Are you available to take this call?", "maxDurationSeconds": 120, + "silenceTimeoutSeconds": 30, "model": { "provider": "openai", "model": "gpt-4o", @@ -91,6 +92,10 @@ The `function.name` property identifies your transfer tool. Use this name when i Maximum duration in seconds for the operator call. The transfer is automatically cancelled if this limit is reached. + + Number of seconds to wait during silence before automatically cancelling the transfer. Must be between 10 and 3600 seconds. + + Assistant configuration including provider, model, and system messages that control the transfer assistant's behavior From dd03e01f2f9f632498eb293615553d76e2d68794 Mon Sep 17 00:00:00 2001 From: Adi Sai Date: Mon, 8 Sep 2025 17:47:46 -0700 Subject: [PATCH 020/171] Add server credentialId docs (#669) * custom credential authentication * remove mdc: from non-cursor rule files --- fern/calls/assistant-based-warm-transfer.mdx | 6 +- fern/customization/custom-transcriber.mdx | 10 +- fern/customization/custom-tts.mdx | 18 +- fern/server-url/server-authentication.mdx | 568 +++++++++++++++--- fern/server-url/setting-server-urls.mdx | 32 +- .../bearer-token-credential.png | Bin 0 -> 90737 bytes .../credential-selection-assistant-server.png | Bin 0 -> 195388 bytes ...edential-selection-phone-number-server.png | Bin 0 -> 153888 bytes .../authentication/credential-selection.png | Bin 0 -> 102634 bytes .../custom-credentials-dashboard.png | Bin 0 -> 214197 bytes .../authentication/hmac-credential.png | Bin 0 -> 158226 bytes .../authentication/oauth2-credential.png | Bin 0 -> 101217 bytes .../x-vapi-secret-credential.png | Bin 0 -> 92428 bytes 13 files changed, 540 insertions(+), 94 deletions(-) create mode 100644 fern/static/images/server-url/authentication/bearer-token-credential.png create mode 100644 fern/static/images/server-url/authentication/credential-selection-assistant-server.png create mode 100644 fern/static/images/server-url/authentication/credential-selection-phone-number-server.png create mode 100644 fern/static/images/server-url/authentication/credential-selection.png create mode 100644 fern/static/images/server-url/authentication/custom-credentials-dashboard.png create mode 100644 fern/static/images/server-url/authentication/hmac-credential.png create mode 100644 fern/static/images/server-url/authentication/oauth2-credential.png create mode 100644 fern/static/images/server-url/authentication/x-vapi-secret-credential.png diff --git a/fern/calls/assistant-based-warm-transfer.mdx b/fern/calls/assistant-based-warm-transfer.mdx index aec4bbdbc..cdb39ba1c 100644 --- a/fern/calls/assistant-based-warm-transfer.mdx +++ b/fern/calls/assistant-based-warm-transfer.mdx @@ -323,6 +323,6 @@ Configure your transfer assistant to: ## Next steps Now that you've configured assistant-based warm transfers: -- **[Call forwarding](mdc:docs/call-forwarding):** Learn about other transfer modes and options -- **[Assistant configuration](mdc:docs/assistants):** Configure assistant models and prompts -- **[Custom tools](mdc:docs/tools/custom-tools):** Add custom tools to your assistants +- **[Call forwarding](../call-forwarding):** Learn about other transfer modes and options +- **[Assistant configuration](../assistants):** Configure assistant models and prompts +- **[Custom tools](../tools/custom-tools):** Add custom tools to your assistants diff --git a/fern/customization/custom-transcriber.mdx b/fern/customization/custom-transcriber.mdx index 6157c8e82..741c6c511 100644 --- a/fern/customization/custom-transcriber.mdx +++ b/fern/customization/custom-transcriber.mdx @@ -408,9 +408,9 @@ You'll learn how to: "transcriber": { "provider": "custom-transcriber", "server": { - "url": "wss://your-server.ngrok.io/api/custom-transcriber" - }, - "secret": "your_optional_secret_value" + "url": "wss://your-server.ngrok.io/api/custom-transcriber", + "credentialId": "cred_transcriber_auth_123" + } }, "firstMessage": "Hello! I am using a custom transcriber with Deepgram." }, @@ -438,8 +438,8 @@ You'll learn how to: - **Streaming support requirement:** The custom transcriber must support streaming. Vapi sends continuous audio data over the WebSocket, and your server must handle this stream in real time. -- **Secret header:** - The custom transcriber configuration accepts an optional field called **`secret`**. When set, Vapi will send this value with every request as an HTTP header named `x-vapi-secret`. This can also be configured via a headers field. +- **Authentication:** + For secure transcriber endpoints, use **Custom Credentials** with `credentialId`. Create [Custom Credentials](../server-url/server-authentication) in the dashboard to manage Bearer Token, OAuth 2.0, or HMAC authentication. For backward compatibility, the legacy `secret` field is still supported and sends the value as an `x-vapi-secret` HTTP header. - **Buffering:** The solution buffers PCM audio and performs simple validation (e.g. ensuring stereo PCM data length is a multiple of 4). If the audio data is malformed, it is trimmed to a valid length. - **Channel detection:** diff --git a/fern/customization/custom-tts.mdx b/fern/customization/custom-tts.mdx index b12264f6c..d08d2e8e8 100644 --- a/fern/customization/custom-tts.mdx +++ b/fern/customization/custom-tts.mdx @@ -53,20 +53,20 @@ VAPI's custom TTS system operates through a webhook pattern: ## Authentication setup -VAPI needs secure communication with your TTS endpoint. Choose from these authentication options: +VAPI needs secure communication with your TTS endpoint. Use **Custom Credentials** for authentication: -### Secret header authentication +### Using Custom Credentials (Recommended) -The most common approach uses a secret token in the `X-VAPI-SECRET` header: +Create authentication credentials in the dashboard and reference them by ID: -```json title="Assistant Configuration" +```json title="Assistant Configuration with Custom Credentials" { "voice": { "provider": "custom-voice", "server": { "url": "https://your-tts-api.com/synthesize", - "secret": "your-secret-token-here", + "credentialId": "cred_tts_auth_123", "timeoutSeconds": 30 } } @@ -74,9 +74,13 @@ The most common approach uses a secret token in the `X-VAPI-SECRET` header: ``` -### Enhanced authentication with custom headers + +Create [Custom Credentials](../server-url/server-authentication) in the Vapi dashboard for better security and credential management. + + +### Legacy Authentication Methods -Add extra headers for API versioning or enhanced security: +For backward compatibility, you can still use inline authentication: ```json title="Assistant Configuration with Custom Headers" diff --git a/fern/server-url/server-authentication.mdx b/fern/server-url/server-authentication.mdx index 16aa9e994..03df2eb89 100644 --- a/fern/server-url/server-authentication.mdx +++ b/fern/server-url/server-authentication.mdx @@ -3,131 +3,553 @@ title: Server authentication slug: server-url/server-authentication --- -When configuring webhooks for your assistant, you can authenticate your server endpoints using either a secret token, custom headers, or OAuth2. This ensures that only authorized requests from Vapi are processed by your server. +When configuring webhooks for your assistant, you can authenticate your server endpoints by creating **Custom Credentials** and referencing them using a `credentialId`. This approach provides better security, reusability, and centralized management of your authentication credentials. -## Credential Configuration +## Overview -Credentials can be configured at multiple levels: +Vapi now uses a **credential-based authentication system** where you: -1. **Tool Call Level**: Create individual credentials for each tool call -2. **Assistant Level**: Set credentials directly in the assistant configuration -3. **Phone Number Level**: Configure credentials for specific phone numbers -4. **Organization Level**: Manage credentials in the [API Keys page](https://dashboard.vapi.ai/keys) +1. **Create Custom Credentials** through the dashboard +2. **Reference credentials by ID** in your server configurations +3. **Reuse credentials** across multiple assistants, phone numbers, and tools -The order of precedence is: -1. Tool call-level credentials -2. Assistant-level credentials -3. Phone number-level credentials -4. Organization-level credentials from the API Keys page +This replaces the previous inline authentication approach and provides better security and management capabilities. -## Authentication Methods +## Quick start -### Secret Token Authentication + + + In the Vapi dashboard, navigate to Custom Credentials and create a new credential: + + - Choose **Bearer Token** for simple API key authentication + - Enter a descriptive name like "Production API Auth" + - Add your API token + - Save the credential and note the generated ID (e.g., `cred_abc123`) + + + + Reference the credential when configuring server webhooks: + + ```json + { + "name": "Support Assistant", + "server": { + "url": "https://api.yourcompany.com/webhook", + "credentialId": "cred_abc123" + }, + "model": { + "provider": "openai", + "model": "gpt-4" + } + } + ``` + + + + Make a test call - Vapi will now authenticate requests to your webhook using the configured credential. + + + +## Creating Custom Credentials + +### Dashboard Management + +Custom Credentials are managed through the Vapi dashboard. Navigate to your organization settings to create and manage authentication credentials. + + + + + +You can create different types of authentication credentials: + +- **Bearer Token**: Simple token-based authentication +- **OAuth 2.0**: OAuth 2.0 client credentials flow +- **HMAC**: HMAC signature-based authentication + +## Authentication Types + +### Bearer Token Authentication + +The most common authentication method using a bearer token in the Authorization header. + + + + In the dashboard, select "Bearer Token" as the authentication type and configure: + + - **Credential Name**: A descriptive name for the credential + - **Token**: Your API token or secret + - **Header Name**: The header to send the token in (default: `Authorization`) + - **Include Bearer Prefix**: Whether to prefix the token with "Bearer " + + + + Reference the credential by its ID in your server configuration: + + ```json + { + "server": { + "url": "https://your-server.com/webhook", + "credentialId": "cred_abc123" + } + } + ``` + + + + + + + +#### Standard Authorization Header + +The most common Bearer Token configuration uses the standard `Authorization` header with the Bearer prefix: + + + + Configure a Bearer Token credential with: + + - **Header Name**: `Authorization` (default) + - **Include Bearer Prefix**: Enabled (toggle on) + - **Token**: Your API token or secret key + + + + Reference this credential in your server setup - Vapi will send your token as `Authorization: Bearer your-token`. + + ```json + { + "server": { + "url": "https://api.example.com/webhook", + "credentialId": "cred_bearer_standard_123" + } + } + ``` + + + + Your server will receive the standard Authorization header: + + ```http + POST /webhook HTTP/1.1 + Host: api.example.com + Authorization: Bearer your-api-token-here + Content-Type: application/json + ``` + + + +This is the recommended approach for modern API authentication and works with most authentication frameworks and libraries. + +#### Legacy X-Vapi-Secret Support + +For backward compatibility with existing implementations, you can configure a Bearer Token credential to use the `X-Vapi-Secret` header (matching the previous inline `secret` field behavior): + + + + Configure a Bearer Token credential with: + + - **Header Name**: `X-Vapi-Secret` (instead of `Authorization`) + - **Include Bearer Prefix**: Disabled (toggle off) + - **Token**: Your secret token value + + + + Reference this credential in your server setup - Vapi will send your token in the `X-Vapi-Secret` header exactly like the previous inline behavior. + + + + + + + +### OAuth 2.0 Authentication + +For OAuth 2.0 protected endpoints, configure client credentials flow with automatic token refresh. + + + + Select "OAuth 2.0" as the authentication type and configure: + + - **Credential Name**: A descriptive name for the credential + - **Token URL**: Your OAuth token endpoint + - **Client ID**: OAuth client identifier + - **Client Secret**: OAuth client secret + - **Scope**: Optional scopes to request + + + + Use the credential ID in your server setup: + + ```json + { + "server": { + "url": "https://your-server.com/webhook", + "credentialId": "cred_oauth_xyz789" + } + } + ``` + + + + + + + +#### OAuth 2.0 Flow + +1. Vapi makes a token request to your OAuth endpoint with client credentials +2. Your server validates the credentials and returns an access token +3. Vapi includes the access token in the Authorization header for webhook requests +4. When tokens expire, Vapi automatically requests new ones -The simplest way to authenticate webhook requests is using a secret token. Vapi will include this token in the `X-Vapi-Signature` header of each request. +#### Token Response Format -#### Configuration +Your OAuth server should return: ```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +### HMAC Authentication + +For maximum security, use HMAC signature-based authentication to verify request integrity. + + + + Select "HMAC" as the authentication type and configure: + + - **Credential Name**: A descriptive name for the credential + - **Secret Key**: Your HMAC secret key + - **Algorithm**: Hash algorithm (SHA256, SHA1, etc.) + - **Signature Header**: Header name for the signature (e.g., `x-signature`) + - **Timestamp Header**: Optional timestamp header for replay protection + - **Payload Format**: How to format the payload for signing + + + + Reference the HMAC credential: + + ```json + { + "server": { + "url": "https://your-server.com/webhook", + "credentialId": "cred_hmac_456" + } + } + ``` + + + + + + + +## Using Credentials + +### In Assistant Configuration + +Reference credentials in your assistant's server configuration: + + +```json title="API Request" { "server": { - "url": "https://your-server.com/webhook", - "secret": "your-secret-token" + "url": "https://api.example.com/webhook", + "credentialId": "cred_bearer_auth_123" } } ``` -### Custom Headers Authentication +```typescript title="TypeScript SDK" +import { VapiClient } from "@vapi-ai/server-sdk"; -For more complex authentication scenarios, you can configure custom headers that Vapi will include with each webhook request. +const client = new VapiClient({ token: process.env.VAPI_API_KEY }); -This could include short lived JWTs/API Keys passed along via the Authorization header, or any other header that your server checks for. +const assistant = await client.assistants.create({ + server: { + url: "https://api.example.com/webhook", + credentialId: "cred_bearer_auth_123" + }, + // ... other assistant config +}); +``` -#### Configuration +```python title="Python SDK" +from vapi import Vapi -```json +client = Vapi(token=os.getenv("VAPI_API_KEY")) + +assistant = client.assistants.create( + server={ + "url": "https://api.example.com/webhook", + "credentialId": "cred_bearer_auth_123" + } + # ... other assistant config +) +``` + + + + + + +### In Phone Number Configuration + +Assign credentials to phone numbers for incoming call authentication: + + +```json title="API Request" { + "phoneNumber": "+1234567890", "server": { - "url": "https://your-server.com/webhook", - "headers": { - "Authorization": "Bearer your-api-key", - "Custom-Header": "custom-value" - } + "url": "https://api.example.com/calls", + "credentialId": "cred_oauth_456" } } ``` -### OAuth2 Authentication +```typescript title="TypeScript SDK" +const phoneNumber = await client.phoneNumbers.create({ + phoneNumber: "+1234567890", + server: { + url: "https://api.example.com/calls", + credentialId: "cred_oauth_456" + } +}); +``` + + + + + -For OAuth2-protected webhook endpoints, you can configure OAuth2 credentials that Vapi will use to obtain and refresh access tokens. +### In Tool Configuration -#### Configuration (at the assistant-level) +Secure your function tool endpoints with credentials: -```json + +```json title="API Request" { - "server": { - "url": "https://your-server.com/webhook" - }, - "credentials": [ - { - "provider": "webhook", - "authenticationPlan": { - "type": "oauth2", - "url": "https://your-server.com/oauth/token", - "clientId": "your-client-id", - "clientSecret": "your-client-secret", - "scope": "optional, only needed to specify which scopes to request access for" + "type": "function", + "function": { + "name": "get_weather", + "description": "Get current weather", + "parameters": { + "type": "object", + "properties": { + "location": { "type": "string" } } } - ] + }, + "server": { + "url": "https://api.example.com/weather", + "credentialId": "cred_hmac_789" + } } ``` -#### Configuration (via our Dashboard) +```typescript title="TypeScript SDK" +const tool = await client.tools.create({ + type: "function", + function: { + name: "get_weather", + description: "Get current weather", + parameters: { + type: "object", + properties: { + location: { type: "string" } + } + } + }, + server: { + url: "https://api.example.com/weather", + credentialId: "cred_hmac_789" + } +}); +``` + + +## Credential Management + +### Dashboard Features + +The Custom Credentials dashboard provides: + +- **Credential Creation**: Create new authentication credentials +- **Credential Editing**: Modify existing credential configurations +- **Credential Deletion**: Remove unused credentials +- **Usage Tracking**: See where credentials are being used + + + + + +### Best Practices + + +**Credential Naming**: Use descriptive names like "Production API Key" or "Staging OAuth" to easily identify credentials. + + + +**Credential Rotation**: Regularly rotate credentials for enhanced security. Update the credential in the dashboard without changing your configurations. + + + +**Credential Security**: Store credential secrets securely. Once created, secrets are encrypted and cannot be viewed in the dashboard. + + +### Migration from Inline Authentication + +If you're currently using inline authentication, migrate to the credential system: - - Go to [https://dashboard.vapi.ai/keys](https://dashboard.vapi.ai/keys) to manage your OAuth2 credentials. + + For each inline authentication configuration, create a matching Custom Credential in the dashboard: + + - **For `secret` field**: Create a Bearer Token credential with header `X-Vapi-Secret` and no Bearer prefix (see [Legacy X-Vapi-Secret Support](#legacy-x-vapi-secret-support)) + - **For `headers` field**: Create a Bearer Token credential with the appropriate header name + - **For OAuth configurations**: Create an OAuth 2.0 credential + + + + Replace inline authentication with `credentialId` references: + + **Before (inline secret):** + ```json + { + "server": { + "url": "https://api.example.com/webhook", + "secret": "your-secret-token" + } + } + ``` + + **After (credential reference):** + ```json + { + "server": { + "url": "https://api.example.com/webhook", + "credentialId": "cred_x_vapi_secret_123" + } + } + ``` + + Your server will continue receiving the same `X-Vapi-Secret` header with identical behavior. + + + + Verify that your webhooks continue working with the new credential system. The authentication behavior should be identical to your previous inline configuration. - - - +## Common Use Cases -#### OAuth2 Flow +### Single Credential for Multiple Resources -1. Vapi makes a request to your token endpoint with client credentials (Content-Type `application/x-www-form-urlencoded`) -2. Your server validates the credentials and returns an access token -3. Vapi includes the access token in the Authorization header for webhook requests -4. Your server validates the access token before processing the webhook -5. When the token expires, Vapi automatically requests a new one +Reuse the same credential across different components: + + +```json title="Shared Credential Usage" +{ + "assistant": { + "server": { + "url": "https://api.yourcompany.com/assistant-webhook", + "credentialId": "cred_production_api_123" + } + }, + "phoneNumber": { + "server": { + "url": "https://api.yourcompany.com/call-webhook", + "credentialId": "cred_production_api_123" + } + }, + "tools": [ + { + "type": "function", + "function": { + "name": "get_user_info" + }, + "server": { + "url": "https://api.yourcompany.com/user-info", + "credentialId": "cred_production_api_123" + } + } + ] +} +``` + -#### OAuth2 Token Response Format +### Environment-Specific Credentials -Your server should return a JSON response with the following format: +Use different credentials for staging and production: -```json + +```json title="Staging Environment" { - "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", - "token_type": "Bearer", - "expires_in": 3600 + "server": { + "url": "https://staging-api.yourcompany.com/webhook", + "credentialId": "cred_staging_api_456" + } } ``` -Example error response: +```json title="Production Environment" +{ + "server": { + "url": "https://api.yourcompany.com/webhook", + "credentialId": "cred_production_api_123" + } +} +``` + -```json +### Service-Specific Credentials + +Use different credentials for different services: + + +```json title="Multiple Service Credentials" { - "error": "invalid_client", - "error_description": "Invalid client credentials" + "assistant": { + "server": { + "url": "https://auth.yourcompany.com/webhook", + "credentialId": "cred_auth_service_789" + } + }, + "tools": [ + { + "type": "function", + "function": { + "name": "payment_processing" + }, + "server": { + "url": "https://payments.yourcompany.com/process", + "credentialId": "cred_payment_service_321" + } + }, + { + "type": "function", + "function": { + "name": "user_management" + }, + "server": { + "url": "https://users.yourcompany.com/manage", + "credentialId": "cred_user_service_654" + } + } + ] } ``` + + +## Next steps -Common error types: -- `invalid_client`: Invalid client credentials -- `invalid_grant`: Invalid or expired refresh token -- `invalid_scope`: Invalid scope requested -- `unauthorized_client`: Client not authorized for this grant type +Now that you have authentication configured: - If using the OAuth2 flow for authenticating tool calls, make sure the server for the tool is the URL that should be hit *after* we have completed the token exchange. \ No newline at end of file +- **[Setting server URLs](./setting-server-urls):** Learn where server URLs can be configured +- **[Server events](./events):** Understand what webhook events Vapi sends +- **[Local development](./developing-locally):** Set up local webhook testing \ No newline at end of file diff --git a/fern/server-url/setting-server-urls.mdx b/fern/server-url/setting-server-urls.mdx index d450d062b..80f96b08c 100644 --- a/fern/server-url/setting-server-urls.mdx +++ b/fern/server-url/setting-server-urls.mdx @@ -43,7 +43,13 @@ Here's a breakdown of where you can set server URLs in Vapi: - **At Import:** when you [import from Twilio](/api-reference/phone-numbers/import-twilio-number) or [Vonage](/api-reference/phone-numbers/import-vonage-number) - **Via Update:** you can [update a number](/api-reference/phone-numbers/update-phone-number) already in your account - The field `phoneNumber.serverUrl` will contain the server URL for the phone number. + The phone number's server configuration includes both the URL and optional authentication: + - `phoneNumber.server.url`: The webhook endpoint URL + - `phoneNumber.server.credentialId`: Authentication credential ID (optional) + + + For secured webhooks, create [Custom Credentials](./server-authentication) and reference them using `credentialId`. + @@ -60,9 +66,15 @@ Here's a breakdown of where you can set server URLs in Vapi: - At [assistant creation](/api-reference/assistants/create-assistant) (or via an [update](/api-reference/assistants/update-assistant)) you can set the assistant's server URL. - - The server URL for an assistant is stored in the `assistant.serverUrl` field. + At [assistant creation](/api-reference/assistants/create-assistant) (or via an [update](/api-reference/assistants/update-assistant)) you can set the assistant's server configuration. + + The assistant's server configuration includes: + - `assistant.server.url`: The webhook endpoint URL + - `assistant.server.credentialId`: Authentication credential ID (optional) + + + For secured webhooks, use [Custom Credentials](./server-authentication) with `credentialId` instead of inline authentication. + @@ -79,9 +91,17 @@ Here's a breakdown of where you can set server URLs in Vapi: - The server URL for a function call can be found on an assistant at `assistant.model.functions[].serverUrl`. + Function tools can be configured with server endpoints via the [tools API](/api-reference/tools) or within assistant configurations. + + The server configuration for function tools includes: + - `tool.server.url`: The function endpoint URL + - `tool.server.credentialId`: Authentication credential ID (optional) - You can either set the URL for a function call at [assistant creation](/api-reference/assistants/create-assistant), or in an [assistant update](/api-reference/assistants/update-assistant). + You can configure function tool servers at [tool creation](/api-reference/tools/create), [assistant creation](/api-reference/assistants/create-assistant), or in updates. + + + Use [Custom Credentials](./server-authentication) to secure your function endpoints with `credentialId`. + diff --git a/fern/static/images/server-url/authentication/bearer-token-credential.png b/fern/static/images/server-url/authentication/bearer-token-credential.png new file mode 100644 index 0000000000000000000000000000000000000000..3cbcc39fabf9124fbdbff31dac7c05ce99cfe08f GIT binary patch literal 90737 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%0Ad%vq*jCWg+ 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

A(XY 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

    0OD~FOKP#gJG{GZ&2de~6 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 Cr*zZ+ literal 0 HcmV?d00001 diff --git a/fern/static/images/server-url/authentication/custom-credentials-dashboard.png b/fern/static/images/server-url/authentication/custom-credentials-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..df6e1d532da4de54162682d013a723175b72e6ea GIT binary patch literal 214197 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 *x~%)u)n*VV#wQwTNxUf*~vP}<9|HF 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 literal 0 HcmV?d00001 diff --git a/fern/static/images/server-url/authentication/hmac-credential.png b/fern/static/images/server-url/authentication/hmac-credential.png new file mode 100644 index 0000000000000000000000000000000000000000..7baf82e1e7c3a9aa12adff722adbc8255fc7fa4e GIT binary patch literal 158226 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�^ofC$WP;U0=rg{Q?sZUy^2`t)iNZ< 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

    rh(;^hvg~bvb*#b69S& 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 bw)aW4oQ;m>F+aWs_;=@q_Vw&*W_^( literal 0 HcmV?d00001 diff --git a/fern/static/images/server-url/authentication/x-vapi-secret-credential.png b/fern/static/images/server-url/authentication/x-vapi-secret-credential.png new file mode 100644 index 0000000000000000000000000000000000000000..3d754d39a8d12a70002927f40e12aa7f5ed45f42 GIT binary patch literal 92428 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 Date: Tue, 9 Sep 2025 02:01:37 -0700 Subject: [PATCH 021/171] enhancement: support for mulaw encoding within websocket transport (#670) --- fern/calls/websocket-transport.mdx | 50 +++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/fern/calls/websocket-transport.mdx b/fern/calls/websocket-transport.mdx index d7927f68f..115849fd1 100644 --- a/fern/calls/websocket-transport.mdx +++ b/fern/calls/websocket-transport.mdx @@ -18,6 +18,8 @@ Vapi's WebSocket transport enables real-time, bidirectional audio communication To initiate a call using WebSocket transport: +### PCM Format (16-bit, default) + ```bash curl 'https://api.vapi.ai/call' \ -H 'authorization: Bearer YOUR_API_KEY' \ @@ -35,6 +37,25 @@ curl 'https://api.vapi.ai/call' \ }' ``` +### Mu-Law Format + +```bash +curl 'https://api.vapi.ai/call' \ + -H 'authorization: Bearer YOUR_API_KEY' \ + -H 'content-type: application/json' \ + --data-raw '{ + "assistantId": "YOUR_ASSISTANT_ID", + "transport": { + "provider": "vapi.websocket", + "audioFormat": { + "format": "mulaw", + "container": "raw", + "sampleRate": 8000 + } + } + }' +``` + ### Sample API Response ```json @@ -61,13 +82,25 @@ When creating a WebSocket call, the audio format can be customized: | Parameter | Description | Default | |-------------|-------------------------|---------------------| | `format` | Audio encoding format | `pcm_s16le` (16-bit PCM) | -| `container` | Audio container format | `raw` (Raw PCM) | -| `sampleRate`| Sample rate in Hz | `16000` (16kHz) | +| `container` | Audio container format | `raw` (Raw audio) | +| `sampleRate`| Sample rate in Hz | `16000` for PCM, `8000` for Mu-Law | + +### Supported Audio Formats + +Vapi supports the following audio formats: -Currently, Vapi supports only raw PCM (`pcm_s16le` with `raw` container). Additional formats may be supported in future updates. +- **`pcm_s16le`**: 16-bit PCM, signed little-endian (default) +- **`mulaw`**: Mu-Law encoded audio (ITU-T G.711 standard) + +Both formats use the `raw` container format for direct audio streaming. + +### Format Selection Guidelines + +- **PCM (`pcm_s16le`)**: Higher quality audio, larger bandwidth usage. Ideal for high-quality applications. +- **Mu-Law (`mulaw`)**: Lower bandwidth, telephony-standard encoding. Ideal for telephony integrations and bandwidth-constrained environments. -Vapi automatically converts sample rates as needed. You can stream audio at 8kHz, 44.1kHz, etc., and Vapi will handle conversions seamlessly. +Vapi automatically converts sample rates as needed. You can stream audio at 8kHz, 44.1kHz, etc., and Vapi will handle conversions seamlessly. The system also handles format conversions internally when needed. ## Connecting to the WebSocket @@ -86,9 +119,16 @@ socket.onerror = (error) => console.error("WebSocket error:", error); The WebSocket supports two types of messages: -- **Binary audio data** (PCM, 16-bit signed little-endian) +- **Binary audio data** (format depends on your configuration: PCM or Mu-Law) - **Text-based JSON control messages** +### Audio Data Format + +The binary audio data format depends on your `audioFormat` configuration: + +- **PCM (`pcm_s16le`)**: 16-bit signed little-endian samples +- **Mu-Law (`mulaw`)**: 8-bit Mu-Law encoded samples (ITU-T G.711) + ### Sending Audio Data ```javascript From f22404f60898d0314eced3c5f91f0790d74e1b9c Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Fri, 12 Sep 2025 03:46:40 +0530 Subject: [PATCH 022/171] Optimize webhook response time (#678) * Docs: Add assistant-request webhook timeout warning Co-authored-by: sahil * Fix webhook timeout description Co-authored-by: sahil * Fix: Clarify webhook timeout reasons Co-authored-by: sahil --------- Co-authored-by: Cursor Agent Co-authored-by: sahil --- fern/server-url/events.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fern/server-url/events.mdx b/fern/server-url/events.mdx index 98761bdfb..4f4fa615c 100644 --- a/fern/server-url/events.mdx +++ b/fern/server-url/events.mdx @@ -113,6 +113,14 @@ For inbound phone calls, you can specify the assistant dynamically. If a PhoneNu } ``` + + You must respond to the `assistant-request` webhook within 7.5 seconds end-to-end. This limit is fixed and not configurable: the telephony provider enforces a 15-second cap, and Vapi reserves ~7.5 seconds for call setup. The timeout value shown elsewhere in the dashboard does not apply to this webhook. + + To avoid timeouts: + - Return quickly with an existing assistantId or a minimal assistant, then enrich context asynchronously after the call starts using Live Call Control. + - Host your webhook close to us-west-2 to reduce latency, and target < ~6s to allow for network jitter. + + Respond with either an existing assistant ID, a transient assistant, or transfer destination: ```json From 16c03768dd63a7c3021d11fd5c874ed38c439022 Mon Sep 17 00:00:00 2001 From: roshan Date: Fri, 12 Sep 2025 11:25:15 -0700 Subject: [PATCH 023/171] Removed Typo from Docs (#681) Removed section for conditional structured outputs (not currently live) --- .../structured-outputs-quickstart.mdx | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/fern/assistants/structured-outputs-quickstart.mdx b/fern/assistants/structured-outputs-quickstart.mdx index 30ae147d1..f5d0e1886 100644 --- a/fern/assistants/structured-outputs-quickstart.mdx +++ b/fern/assistants/structured-outputs-quickstart.mdx @@ -737,23 +737,6 @@ You can attach multiple structured outputs to extract different types of data: The `structuredOutputIds` are UUIDs returned when you create each structured output configuration. -### Conditional extraction - -Use conditional logic in your schema to handle different scenarios: - -```json -{ - "if": { - "properties": { - "requestType": {"const": "appointment"} - } - }, - "then": { - "required": ["preferredDate", "preferredTime"] - } -} -``` - ### Validation patterns Common validation patterns for reliable extraction: @@ -801,4 +784,4 @@ Common validation patterns for reliable extraction: Need assistance? We're here to help: - [API Documentation](/api-reference) - [Discord Community](https://discord.gg/pUFNcf2WmH) -- [Support](mailto:support@vapi.ai) \ No newline at end of file +- [Support](mailto:support@vapi.ai) From 1c10ea5d2262ffeaea6d8f1310c71c71b5ce6285 Mon Sep 17 00:00:00 2001 From: Sri Date: Fri, 12 Sep 2025 14:54:50 -0700 Subject: [PATCH 024/171] Added custom kb docs and trieve migration docs (#682) * Added custom kb docs and trieve migration docs * updated gemini-1.5 note * updated the query tool docs * updated the docs --- fern/docs.yml | 9 +- fern/knowledge-base/custom-knowledge-base.mdx | 537 ++++++++++++++++++ fern/knowledge-base/knowledge-base.mdx | 2 +- fern/knowledge-base/migrating-from-trieve.mdx | 413 ++++++++++++++ fern/knowledge-base/using-query-tool.mdx | 50 +- 5 files changed, 994 insertions(+), 17 deletions(-) create mode 100644 fern/knowledge-base/custom-knowledge-base.mdx create mode 100644 fern/knowledge-base/migrating-from-trieve.mdx diff --git a/fern/docs.yml b/fern/docs.yml index 12fb055b9..add14f79c 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -214,9 +214,12 @@ navigation: - page: Query tool path: knowledge-base/using-query-tool.mdx icon: fa-light fa-magnifying-glass - - page: Trieve integration - path: knowledge-base/integrating-with-trieve.mdx - icon: fa-light fa-brain + - page: Custom knowledge base + path: knowledge-base/custom-knowledge-base.mdx + icon: fa-light fa-server + - page: Migrating from Trieve + path: knowledge-base/migrating-from-trieve.mdx + icon: fa-light fa-triangle-exclamation - section: Structured outputs icon: fa-light fa-database path: assistants/structured-outputs.mdx diff --git a/fern/knowledge-base/custom-knowledge-base.mdx b/fern/knowledge-base/custom-knowledge-base.mdx new file mode 100644 index 000000000..af7bbeefc --- /dev/null +++ b/fern/knowledge-base/custom-knowledge-base.mdx @@ -0,0 +1,537 @@ +--- +title: Custom Knowledge Base +subtitle: Create and implement your own knowledge base server for full control over document retrieval +slug: knowledge-base/custom-knowledge-base +--- + +## Overview + +Custom Knowledge Bases allow you to implement your own document retrieval server, giving you complete control over how your assistant searches and retrieves information. Instead of relying on Vapi's built-in knowledge base providers, you can integrate your own search infrastructure, vector databases, or custom retrieval logic. + +**With Custom Knowledge Bases, you can:** +- Use your own vector database or search infrastructure +- Implement custom retrieval algorithms and scoring +- Integrate with existing document management systems +- Apply custom business logic to document filtering +- Maintain full control over data security and privacy + +## How Custom Knowledge Bases Work + +Custom Knowledge Bases operate through a webhook-style integration where Vapi forwards search requests to your server and expects structured responses containing relevant documents. + + + + User asks assistant a question during conversation + + + Vapi sends search request to your custom endpoint + + + Your server returns relevant documents or direct response + + + +## Creating a Custom Knowledge Base + +### Step 1: Create the Knowledge Base + +Use the Vapi API to create a custom knowledge base configuration: + + +```bash title="cURL" +curl --location 'https://api.vapi.ai/knowledge-base' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer YOUR_VAPI_API_KEY' \ +--data '{ + "provider": "custom-knowledge-base", + "server": { + "url": "https://your-domain.com/kb/search", + "secret": "your-webhook-secret" + } +}' +``` + +```typescript title="TypeScript SDK" +import { VapiClient } from "@vapi-ai/server-sdk"; + +const vapi = new VapiClient({ + token: process.env.VAPI_API_KEY +}); + +try { + const knowledgeBase = await vapi.knowledgeBases.create({ + provider: "custom-knowledge-base", + server: { + url: "https://your-domain.com/kb/search", + secret: "your-webhook-secret" + } + }); + + console.log(`Custom Knowledge Base created: ${knowledgeBase.id}`); +} catch (error) { + console.error("Failed to create knowledge base:", error); +} +``` + +```python title="Python SDK" +import os +from vapi import Vapi + +client = Vapi(token=os.getenv("VAPI_API_KEY")) + +try: + knowledge_base = client.knowledge_bases.create( + provider="custom-knowledge-base", + server={ + "url": "https://your-domain.com/kb/search", + "secret": "your-webhook-secret" + } + ) + + print(f"Custom Knowledge Base created: {knowledge_base.id}") +except Exception as error: + print(f"Failed to create knowledge base: {error}") +``` + + +### Step 2: Attach to Your Assistant + + + Custom knowledge bases can **only** be attached to assistants via the API. This functionality is not available through the dashboard interface. + + +To attach a custom knowledge base to your assistant, update the assistant's model configuration. You must provide the **complete** model configuration including all existing messages, as partial patches are not supported for nested objects: + + +```bash title="cURL" +curl --location --request PATCH 'https://api.vapi.ai/assistant/YOUR_ASSISTANT_ID' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer YOUR_VAPI_API_KEY' \ +--data '{ + "model": { + "model": "gpt-4o", + "provider": "openai", + "messages": [ + { + "role": "system", + "content": "Your existing system prompt and instructions..." + } + ], + "knowledgeBaseId": "YOUR_KNOWLEDGE_BASE_ID" + } +}' +``` + +```typescript title="TypeScript SDK" +// First, get the existing assistant to preserve current configuration +const existingAssistant = await vapi.assistants.get("YOUR_ASSISTANT_ID"); + +const updatedAssistant = await vapi.assistants.update("YOUR_ASSISTANT_ID", { + model: { + ...existingAssistant.model, // Preserve existing model configuration + knowledgeBaseId: "YOUR_KNOWLEDGE_BASE_ID" // Add knowledge base + } +}); +``` + +```python title="Python SDK" +# First, get the existing assistant to preserve current configuration +existing_assistant = client.assistants.get(id="YOUR_ASSISTANT_ID") + +updated_assistant = client.assistants.update( + id="YOUR_ASSISTANT_ID", + model={ + **existing_assistant.model, # Preserve existing model configuration + "knowledgeBaseId": "YOUR_KNOWLEDGE_BASE_ID" # Add knowledge base + } +) +``` + + + + When updating an assistant's model, you must include the **complete model object** including all existing messages and configuration. The API replaces the entire model object and doesn't support partial updates for nested objects. + + +## Implementing the Custom Endpoint + +Your custom knowledge base server must handle POST requests at the configured URL and return structured responses. + +### Request Structure + +Vapi will send requests to your endpoint with the following structure: + +```json title="Request Format" +{ + "message": { + "type": "knowledge-base-request", + "messages": [ + { + "role": "user", + "content": "What is your return policy?" + }, + { + "role": "assistant", + "content": "I'll help you with information about our return policy." + }, + { + "role": "user", + "content": "How long do I have to return items?" + } + ] + // Additional metadata fields about the call or chat will be included here + } +} +``` + +### Response Options + +Your endpoint can respond in two ways: + +#### Option 1: Return Documents for AI Processing + +Return an array of relevant documents that the AI will use to formulate a response: + +```json title="Document Response" +{ + "documents": [ + { + "content": "Our return policy allows customers to return items within 30 days of purchase for a full refund. Items must be in original condition with tags attached.", + "similarity": 0.92, + "uuid": "doc-return-policy-1" // optional + }, + { + "content": "Extended return periods apply during holiday seasons - customers have up to 60 days to return items purchased between November 1st and December 31st.", + "similarity": 0.78, + "uuid": "doc-return-policy-holiday" // optional + } + ] +} +``` + +#### Option 2: Return Direct Response + +Return a complete response that the assistant will speak directly: + +```json title="Direct Response" +{ + "message": { + "role": "assistant", + "content": "You have 30 days to return items for a full refund. Items must be in original condition with tags attached. During the holiday season (November 1st to December 31st), you get an extended 60-day return period." + } +} +``` + +### Implementation Examples + +Here are complete server implementations in different languages: + + +```typescript title="Node.js/Express" +import express from 'express'; +import crypto from 'crypto'; + +const app = express(); +app.use(express.json()); + +// Your knowledge base data (replace with actual database/vector store) +const documents = [ + { + id: "return-policy-1", + content: "Our return policy allows customers to return items within 30 days of purchase for a full refund. Items must be in original condition with tags attached.", + category: "returns" + }, + { + id: "shipping-info-1", + content: "We offer free shipping on orders over $50. Standard shipping takes 3-5 business days.", + category: "shipping" + } +]; + +app.post('/kb/search', (req, res) => { + try { + // Verify webhook secret (recommended) + const signature = req.headers['x-vapi-signature']; + const secret = process.env.VAPI_WEBHOOK_SECRET; + + if (signature && secret) { + const expectedSignature = crypto + .createHmac('sha256', secret) + .update(JSON.stringify(req.body)) + .digest('hex'); + + if (signature !== `sha256=${expectedSignature}`) { + return res.status(401).json({ error: 'Invalid signature' }); + } + } + + const { message } = req.body; + + if (message.type !== 'knowledge-base-request') { + return res.status(400).json({ error: 'Invalid request type' }); + } + + // Get the latest user message + const userMessages = message.messages.filter(msg => msg.role === 'user'); + const latestQuery = userMessages[userMessages.length - 1]?.content || ''; + + // Simple keyword-based search (replace with vector search) + const relevantDocs = documents + .map(doc => ({ + ...doc, + similarity: calculateSimilarity(latestQuery, doc.content) + })) + .filter(doc => doc.similarity > 0.1) + .sort((a, b) => b.similarity - a.similarity) + .slice(0, 3); + + // Return documents for AI processing + res.json({ + documents: relevantDocs.map(doc => ({ + content: doc.content, + similarity: doc.similarity, + uuid: doc.id + })) + }); + + } catch (error) { + console.error('Knowledge base search error:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +function calculateSimilarity(query: string, content: string): number { + // Simple similarity calculation (replace with proper vector similarity) + const queryWords = query.toLowerCase().split(' '); + const contentWords = content.toLowerCase().split(' '); + const matches = queryWords.filter(word => + contentWords.some(cWord => cWord.includes(word)) + ).length; + + return matches / queryWords.length; +} + +app.listen(3000, () => { + console.log('Custom Knowledge Base server running on port 3000'); +}); +``` + +```python title="Python/FastAPI" +from fastapi import FastAPI, HTTPException, Request +import hashlib +import hmac +import os +from typing import List, Dict, Any +import uvicorn + +app = FastAPI() + +# Your knowledge base data (replace with actual database/vector store) +documents = [ + { + "id": "return-policy-1", + "content": "Our return policy allows customers to return items within 30 days of purchase for a full refund. Items must be in original condition with tags attached.", + "category": "returns" + }, + { + "id": "shipping-info-1", + "content": "We offer free shipping on orders over $50. Standard shipping takes 3-5 business days.", + "category": "shipping" + } +] + +@app.post("/kb/search") +async def knowledge_base_search(request: Request): + try: + body = await request.json() + + # Verify webhook secret (recommended) + signature = request.headers.get('x-vapi-signature') + secret = os.getenv('VAPI_WEBHOOK_SECRET') + + if signature and secret: + body_bytes = await request.body() + expected_signature = f"sha256={hmac.new(secret.encode(), body_bytes, hashlib.sha256).hexdigest()}" + + if signature != expected_signature: + raise HTTPException(status_code=401, detail="Invalid signature") + + message = body.get('message', {}) + + if message.get('type') != 'knowledge-base-request': + raise HTTPException(status_code=400, detail="Invalid request type") + + # Get the latest user message + user_messages = [msg for msg in message.get('messages', []) if msg.get('role') == 'user'] + latest_query = user_messages[-1].get('content', '') if user_messages else '' + + # Simple keyword-based search (replace with vector search) + relevant_docs = [] + for doc in documents: + similarity = calculate_similarity(latest_query, doc['content']) + if similarity > 0.1: + relevant_docs.append({ + **doc, + 'similarity': similarity + }) + + # Sort by similarity and take top 3 + relevant_docs.sort(key=lambda x: x['similarity'], reverse=True) + relevant_docs = relevant_docs[:3] + + # Return documents for AI processing + return { + "documents": [ + { + "content": doc['content'], + "similarity": doc['similarity'], + "uuid": doc['id'] + } + for doc in relevant_docs + ] + } + + except Exception as error: + print(f"Knowledge base search error: {error}") + raise HTTPException(status_code=500, detail="Internal server error") + +def calculate_similarity(query: str, content: str) -> float: + """Simple similarity calculation (replace with proper vector similarity)""" + query_words = query.lower().split() + content_words = content.lower().split() + + matches = sum(1 for word in query_words + if any(word in cword for cword in content_words)) + + return matches / len(query_words) if query_words else 0 + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + + +## Advanced Implementation Patterns + +### Vector Database Integration + +For production use, integrate with a proper vector database: + + +```typescript title="Pinecone Integration" +import { PineconeClient } from '@pinecone-database/pinecone'; +import OpenAI from 'openai'; + +const pinecone = new PineconeClient(); +const openai = new OpenAI(); + +app.post('/kb/search', async (req, res) => { + try { + const { message } = req.body; + const latestQuery = getLatestUserMessage(message); + + // Generate embedding for the query + const embedding = await openai.embeddings.create({ + model: 'text-embedding-ada-002', + input: latestQuery + }); + + // Search vector database + const index = pinecone.Index('knowledge-base'); + const searchResults = await index.query({ + vector: embedding.data[0].embedding, + topK: 5, + includeMetadata: true + }); + + // Format response + const documents = searchResults.matches.map(match => ({ + content: match.metadata.content, + similarity: match.score, + uuid: match.id + })); + + res.json({ documents }); + } catch (error) { + console.error('Vector search error:', error); + res.status(500).json({ error: 'Search failed' }); + } +}); +``` + +```python title="Weaviate Integration" +import weaviate +from sentence_transformers import SentenceTransformer + +client = weaviate.Client("http://localhost:8080") +model = SentenceTransformer('all-MiniLM-L6-v2') + +@app.post("/kb/search") +async def search_with_weaviate(request: Request): + try: + body = await request.json() + message = body.get('message', {}) + latest_query = get_latest_user_message(message) + + # Search using Weaviate + result = client.query.get("Document", ["content", "title"]) \ + .with_near_text({"concepts": [latest_query]}) \ + .with_limit(5) \ + .with_additional(["certainty"]) \ + .do() + + documents = [] + for doc in result['data']['Get']['Document']: + documents.append({ + "content": doc['content'], + "similarity": doc['_additional']['certainty'], + "uuid": doc.get('title', 'unknown') + }) + + return {"documents": documents} + except Exception as error: + raise HTTPException(status_code=500, detail=str(error)) +``` + + +## Security and Best Practices + +### Performance Optimization + + + **Response time is critical**: Your endpoint should respond in **milliseconds** (ideally under ~50ms) for optimal user experience. While Vapi allows up to 10 seconds timeout, slower responses will significantly affect your assistant's conversational flow and response quality. + + + + **Cache frequently requested documents** and implement request timeouts to ensure fast response times. Consider using in-memory caches, CDNs, or pre-computed embeddings for faster retrieval. + + +### Error Handling + +Always handle errors gracefully and return appropriate HTTP status codes: + +```typescript +app.post('/kb/search', async (req, res) => { + try { + // Your search logic here + } catch (error) { + console.error('Search error:', error); + + // Return empty documents rather than failing + res.json({ + documents: [], + error: "Search temporarily unavailable" + }); + } +}); +``` + +## Next Steps + +Now that you have a custom knowledge base implementation: + +- **[Query Tool Configuration](/knowledge-base/using-query-tool):** Learn advanced query tool configurations +- **[Vector Databases](/knowledge-base/integrating-with-trieve):** Explore vector database integrations +- **[Assistant Configuration](/assistants):** Optimize your assistant's use of knowledge bases + + + Custom Knowledge Bases require a webhook endpoint that's publicly accessible. For production deployments, ensure your server can handle concurrent requests and has appropriate error handling and monitoring in place. + diff --git a/fern/knowledge-base/knowledge-base.mdx b/fern/knowledge-base/knowledge-base.mdx index 9d167d8dd..ca9cd4225 100644 --- a/fern/knowledge-base/knowledge-base.mdx +++ b/fern/knowledge-base/knowledge-base.mdx @@ -139,7 +139,7 @@ By following these guidelines, you can create a comprehensive Knowledge Base tha Currently, Vapi's Knowledge Base functionality supports Google as a provider - with the gemini-1.5-flash model for knowledge retrieval. For the most + with Gemini models for knowledge retrieval. For the most up-to-date information on supported providers and models, please refer to our [API documentation](api-reference/tools/create#request.body.query.knowledgeBases). diff --git a/fern/knowledge-base/migrating-from-trieve.mdx b/fern/knowledge-base/migrating-from-trieve.mdx new file mode 100644 index 000000000..520921ac1 --- /dev/null +++ b/fern/knowledge-base/migrating-from-trieve.mdx @@ -0,0 +1,413 @@ +--- +title: Migrating from Trieve +subtitle: Essential migration guide for Trieve users - service ending November 1st, 2025 +slug: knowledge-base/migrating-from-trieve +--- + + + **URGENT: Trieve is shutting down on November 1st, 2025.** All Trieve-based knowledge bases must be migrated before this date to avoid service disruption. + + +## Overview + +Trieve [is shutting down their cloud service](https://www.trieve.ai/blog/trieve-is-being-acquired-by-mintlify) on November 1st, 2025. If you're currently using Trieve for your Vapi knowledge bases, you need to migrate before this date to avoid service disruption. + +This guide provides two migration paths to ensure your assistant continues working seamlessly. + +**Available migration options:** +- **Custom Knowledge Base**: Full control with your own search infrastructure +- **Google Knowledge Base**: Managed solution using Google's Gemini models + + + **Important Behavioral Difference**: Google knowledge bases work as tools that the assistant calls when needed based on your prompt instructions. Custom knowledge bases are queried on every user request automatically. Choose based on whether you want selective or automatic knowledge retrieval. + + + + **Recommendation**: To maintain the same assistant behavior as your previous Trieve setup, we recommend migrating to a **Custom Knowledge Base**. This ensures your assistant continues to automatically query your knowledge on every user message, just like it did with Trieve. + + +## Migration Options Comparison + +Choose the migration path that best fits your needs: + + + + **Best for:** Advanced users wanting automatic knowledge retrieval + + - Queried on every user message + - Full control over search logic + - Use any vector database or search system + - Requires server development + + + **Best for:** Quick migration with selective knowledge use + + - Works as a tool called when needed + - Simple file upload process + - No server maintenance required + - Assistant decides when to use knowledge + + + +### Decision Matrix + +| Factor | Custom Knowledge Base | Google Knowledge Base | +|--------|----------------------|----------------------| +| **Retrieval Behavior** | Queried on every user message | Called as tool when needed by assistant | +| **Latency** | Lower (direct database query) | Higher (Google Gemini model processing) | +| **Technical Complexity** | High | Low | +| **Ongoing Maintenance** | Server management required | None | +| **Customization** | Complete flexibility | Limited | +| **Cost** | Server hosting costs | Included in Vapi | +| **Search Quality** | Depends on implementation | Google Gemini quality | + +## Migrating to Custom Knowledge Base + +### Step 1: Export Your Data + +Your export process depends on how your Trieve knowledge base was originally created: + +#### Option A: User-Managed Trieve Dataset (Import Plan) +If you created your knowledge base with your own Trieve dataset: + +1. Access your Trieve dashboard directly +2. Export your datasets in your preferred format +3. Download all document chunks and metadata +4. Save any custom embeddings if applicable + +#### Option B: Vapi-Managed Trieve Dataset (Create Plan) +If Vapi created and managed your Trieve dataset: + +1. Navigate to the **Files** page in your Vapi dashboard +2. Download the individual files that were uploaded to create the knowledge base +3. These files are stored in Vapi and are not affected by the Trieve shutdown + + + **Files uploaded to Vapi are safe**: If your knowledge base was created using files uploaded to Vapi, those files remain available in your Vapi account and are not affected by the Trieve shutdown. + + +### Step 2: Set Up Your Custom Server + +Choose your infrastructure and implement the knowledge base endpoint: + + +```typescript title="Node.js Example" +import express from 'express'; +import { PineconeClient } from '@pinecone-database/pinecone'; + +const app = express(); +const pinecone = new PineconeClient(); + +app.post('/kb/search', async (req, res) => { + try { + const { message } = req.body; + const userMessages = message.messages.filter(msg => msg.role === 'user'); + const latestQuery = userMessages[userMessages.length - 1]?.content || ''; + + // Search your vector database + const index = pinecone.Index('your-knowledge-base'); + const searchResults = await index.query({ + vector: await getEmbedding(latestQuery), + topK: 5, + includeMetadata: true + }); + + // Format response + const documents = searchResults.matches.map(match => ({ + content: match.metadata.content, + similarity: match.score, + uuid: match.id + })); + + res.json({ documents }); + } catch (error) { + res.status(500).json({ error: 'Search failed' }); + } +}); + +app.listen(3000); +``` + +```python title="Python Example" +from fastapi import FastAPI +import weaviate +from sentence_transformers import SentenceTransformer + +app = FastAPI() +client = weaviate.Client("http://localhost:8080") + +@app.post("/kb/search") +async def search_knowledge_base(request: dict): + try: + message = request.get('message', {}) + user_messages = [msg for msg in message.get('messages', []) if msg.get('role') == 'user'] + latest_query = user_messages[-1].get('content', '') if user_messages else '' + + # Search your vector database + result = client.query.get("Document", ["content", "title"]) \ + .with_near_text({"concepts": [latest_query]}) \ + .with_limit(5) \ + .with_additional(["certainty"]) \ + .do() + + documents = [] + for doc in result['data']['Get']['Document']: + documents.append({ + "content": doc['content'], + "similarity": doc['_additional']['certainty'], + "uuid": doc.get('title', 'unknown') + }) + + return {"documents": documents} + except Exception as error: + return {"error": str(error)} +``` + + +### Step 3: Create Custom Knowledge Base in Vapi + + +```bash title="cURL" +curl --location 'https://api.vapi.ai/knowledge-base' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer YOUR_VAPI_API_KEY' \ +--data '{ + "provider": "custom-knowledge-base", + "server": { + "url": "https://your-domain.com/kb/search", + "secret": "your-webhook-secret" + } +}' +``` + +```typescript title="TypeScript SDK" +const knowledgeBase = await vapi.knowledgeBases.create({ + provider: "custom-knowledge-base", + server: { + url: "https://your-domain.com/kb/search", + secret: "your-webhook-secret" + } +}); +``` + + +### Step 4: Update Your Assistant + +Replace your Trieve knowledge base with the custom one: + + +```bash title="cURL" +curl --location --request PATCH 'https://api.vapi.ai/assistant/YOUR_ASSISTANT_ID' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer YOUR_VAPI_API_KEY' \ +--data '{ + "model": { + "model": "gpt-4o", + "provider": "openai", + "messages": [ + { + "role": "system", + "content": "Your existing system prompt..." + } + ], + "knowledgeBaseId": "YOUR_NEW_KNOWLEDGE_BASE_ID" + } +}' +``` + +```typescript title="TypeScript SDK" +// Get existing configuration +const existingAssistant = await vapi.assistants.get("YOUR_ASSISTANT_ID"); + +// Update with new knowledge base +const updatedAssistant = await vapi.assistants.update("YOUR_ASSISTANT_ID", { + model: { + ...existingAssistant.model, + knowledgeBaseId: knowledgeBase.id + } +}); +``` + + +## Migrating to Google Knowledge Base + +### Step 1: Prepare Your Files + +Your file preparation depends on how your Trieve knowledge base was originally created: + +#### Option A: User-Managed Trieve Dataset (Import Plan) +If you created your knowledge base with your own Trieve dataset: + +1. Export your Trieve datasets as individual files +2. Organize files by topic or domain +3. Ensure files are in supported formats (`.txt`, `.pdf`, `.docx`, `.md`, etc.) +4. Keep individual files under 300KB for optimal processing +5. **Upload these files to Vapi** (you'll need them in Vapi to create the query tool) + +#### Option B: Vapi-Managed Trieve Dataset (Create Plan) +If Vapi created and managed your Trieve dataset: + +1. Navigate to the **Files** page in your Vapi dashboard +2. Locate the files that were used to create your Trieve knowledge base +3. Note the **file IDs** - you'll use these directly to create your query tool +4. **No need to download or re-upload** - the files are already in Vapi + + + **Files uploaded to Vapi are safe**: If your knowledge base was created using files uploaded to Vapi, those files remain available and are not affected by the Trieve shutdown. + + +### Step 2: Upload Files to Vapi (Option A Only) + + + **This step is only required for Option A (User-Managed Trieve)**. If you're using Option B (Vapi-Managed), skip to Step 3 as your files are already in Vapi. + + +If you exported files from your own Trieve dataset (Option A): + +1. Navigate to **Build > Files** in your Vapi dashboard +2. Click **Upload** and select your exported files +3. Wait for processing and note the generated file IDs + +### Step 3: Create Query Tool + +Create a query tool using your file IDs: + +- **Option A**: Use the file IDs from the files you just uploaded in Step 2 +- **Option B**: Use the existing file IDs you noted from your Vapi Files page + +For detailed instructions, see our [Query Tool documentation](/knowledge-base/using-query-tool). + + + **Don't forget**: You must update your assistant's system prompt to explicitly name the tool to use. Add instructions like: "When users ask about products or support topics, use the 'knowledge-search' tool to search the knowledge base." Replace 'knowledge-search' with your actual tool function name. + + + +```bash title="cURL" +curl --location 'https://api.vapi.ai/tool' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer YOUR_VAPI_API_KEY' \ +--data '{ + "type": "query", + "function": { + "name": "knowledge-search" + }, + "knowledgeBases": [ + { + "provider": "google", + "name": "product-support-documentation", + "description": "Contains comprehensive information about our products, services, features, pricing, and technical support documentation. Includes troubleshooting guides and company information.", + "fileIds": [ + "FILE_ID_1", + "FILE_ID_2", + "FILE_ID_3" + ] + } + ] +}' +``` + +```typescript title="TypeScript SDK" +const queryTool = await vapi.tools.create({ + type: "query", + function: { + name: "knowledge-search" + }, + knowledgeBases: [ + { + provider: "google", + name: "product-support-documentation", + description: "Contains comprehensive information about our products, services, features, pricing, and technical support documentation. Includes troubleshooting guides and company information.", + fileIds: [ + "FILE_ID_1", + "FILE_ID_2", + "FILE_ID_3" + ] + } + ] +}); +``` + + +### Step 4: Update Your Assistant + +Remove Trieve tools and add your new query tool: + + +```bash title="cURL" +curl --location --request PATCH 'https://api.vapi.ai/assistant/YOUR_ASSISTANT_ID' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Bearer YOUR_VAPI_API_KEY' \ +--data '{ + "model": { + "model": "gpt-4o", + "provider": "openai", + "messages": [ + { + "role": "system", + "content": "Your existing system prompt..." + } + ], + "toolIds": ["YOUR_NEW_QUERY_TOOL_ID"] + } +}' +``` + +```typescript title="TypeScript SDK" +// Get existing assistant +const existingAssistant = await vapi.assistants.get("YOUR_ASSISTANT_ID"); + +// Update with new tool +const updatedAssistant = await vapi.assistants.update("YOUR_ASSISTANT_ID", { + model: { + ...existingAssistant.model, + toolIds: [queryTool.id] + } +}); +``` + + +## Post-Migration Checklist + +After completing your migration: + +- [ ] **Test all assistants** to ensure knowledge retrieval is working +- [ ] **Monitor response quality** and adjust configurations if needed +- [ ] **Remove the old Trieve knowledge base** from Vapi using API. +- [ ] **Remove Trieve credentials** from Vapi dashboard + +## Troubleshooting Common Issues + +### Poor Search Quality After Migration + +**Custom Knowledge Base:** +- Verify your embedding model matches or exceeds Trieve's quality +- Adjust similarity thresholds based on your model +- Test different chunking strategies +- Consider implementing hybrid search (semantic + keyword) + +**Google Knowledge Base:** +- Review file formatting and structure +- Optimize knowledge base descriptions +- Test with different query phrasings +- Consider splitting large files into smaller, focused documents + +### Performance Issues + +**Custom Knowledge Base:** +- Implement caching for frequently searched content +- Optimize your vector database configuration +- Consider using faster embedding models for latency-critical applications +- Monitor and optimize server response times + +**Google Knowledge Base:** +- Ensure files are under 300KB each +- Use clear, well-structured file formats +- Minimize the number of files per knowledge base where possible + +## Next Steps + +Once you've completed your migration: + +- **[Custom Knowledge Base](/knowledge-base/custom-knowledge-base):** Learn advanced customization options +- **[Query Tool Configuration](/knowledge-base/using-query-tool):** Optimize your Google knowledge base setup +- **[Assistant Configuration](/assistants):** Fine-tune your assistant's knowledge base usage diff --git a/fern/knowledge-base/using-query-tool.mdx b/fern/knowledge-base/using-query-tool.mdx index 22747a331..b1806e51a 100644 --- a/fern/knowledge-base/using-query-tool.mdx +++ b/fern/knowledge-base/using-query-tool.mdx @@ -15,11 +15,6 @@ The Query Tool is a powerful feature that allows your voice AI assistant to acce - **Improved response accuracy**: Responses are based on your verified information rather than general knowledge. - **Customizable knowledge retrieval**: Configure multiple knowledge bases for different topics or domains. - - Currently, the Query Tool only supports Google as a provider with the - gemini-1.5-flash model for knowledge base retrieval. - - ## **How to Configure a Query Tool for Knowledge Bases** ### **Step 1: Upload Your Files** @@ -58,7 +53,7 @@ Create a query tool that references your knowledge base files: - **Tool Name**: "Product Query" - **Knowledge Bases**: Add your knowledge base with: - **Name**: `product-kb` - - **Description**: "Use this knowledge base when the user asks or queries about the product or services" + - **Description**: "Contains comprehensive product information, service details, and company offerings" - **File IDs**: Select the files you uploaded in Step 1 #### Option 2: Using the API @@ -78,7 +73,7 @@ curl --location 'https://api.vapi.ai/tool/' \ { "provider": "google", "name": "product-kb", - "description": "Use this knowledge base when the user asks or queries about the product or services", + "description": "Contains comprehensive product information, service details, and company offerings", "fileIds": [ "41a2bd44-d13c-4914-bbf7-b19807dd2cf4", "ef82ae15-21b2-47bd-bde4-dea3922c1e49" @@ -104,7 +99,8 @@ After creating the query tool, you need to attach it to your assistant: 2. Select the assistant you want to configure 3. Go to the **Tools** section 4. Click **Add Tool** and select your query tool from the dropdown -5. Save and publish your assistant +5. **Update the system prompt** to instruct when to use the tool (see examples below) +6. Save and publish your assistant #### Option 2: Using the API @@ -130,6 +126,10 @@ curl --location --request PATCH 'https://api.vapi.ai/assistant/ASSISTANT_ID' \ just the toolIds field. This will overwrite any existing model configuration. + + **Don't forget**: After attaching the tool via API, you must also update your assistant's system prompt (in the `messages` array) to instruct when to use the tool by name. See the system prompt examples below. + + + **Important**: You must explicitly instruct your assistant in its system prompt about when to use the query tool. The knowledge base description alone is not sufficient for the assistant to know when to search. + + +Add clear instructions to your assistant's system messages, **explicitly naming the tool**: ```json -"description": "Use this knowledge base when the user asks about pricing, subscription plans, or billing information" +{ + "role": "system", + "content": "You are a helpful customer support assistant. When users ask about products, pricing, features, or need troubleshooting help, use the 'knowledge-search' tool to search our knowledge base for accurate information. Always call the knowledge-search tool before providing answers to ensure accuracy." +} ``` + + **Be specific**: Replace `'knowledge-search'` with your actual tool's function name from the query tool configuration. + + +**Example system prompt instructions with specific tool names:** +- **Product Support**: "When users ask about product features, specifications, or troubleshooting, use the 'product-support-search' tool to find relevant information." +- **Billing Questions**: "For any questions about pricing, billing, or subscription plans, use the 'billing-query' tool to find the most current information." +- **Technical Documentation**: "When users need API documentation, code examples, or integration help, use the 'api-docs-search' tool to search the technical knowledge base." + ## **Best Practices for Query Tool Configuration** - **Organize by topic**: Create separate knowledge bases for distinct topics to improve retrieval accuracy. - **Use descriptive names**: Name your knowledge bases clearly to help your assistant understand their purpose. -- **Keep descriptions specific**: Write clear descriptions that tell the assistant exactly when to use each knowledge base. +- **Include system prompt instructions**: Always add explicit instructions to your assistant's system prompt about when to use the query tool. - **Update regularly**: Refresh your knowledge bases as information changes to ensure accuracy. - **Test thoroughly**: After configuration, test your assistant with various queries to ensure it retrieves information correctly. From f7a143d5cc4df9d42e7d6271b30050e6c804ced4 Mon Sep 17 00:00:00 2001 From: Arvind Ram Singh Kishore Date: Fri, 12 Sep 2025 17:37:56 -0700 Subject: [PATCH 025/171] Update OpenAI Realtime model (#683) * updates * updates --- fern/openai-realtime.mdx | 386 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 379 insertions(+), 7 deletions(-) diff --git a/fern/openai-realtime.mdx b/fern/openai-realtime.mdx index 4cd0cf952..619a24a04 100644 --- a/fern/openai-realtime.mdx +++ b/fern/openai-realtime.mdx @@ -1,16 +1,388 @@ --- title: OpenAI Realtime -subtitle: You can use OpenAI's newest speech-to-speech model with your Vapi assistants. +subtitle: Build voice assistants with OpenAI's native speech-to-speech models for ultra-low latency conversations slug: openai-realtime --- +## Overview + +OpenAI’s Realtime API enables developers to use a native speech-to-speech model. Unlike other Vapi configurations which orchestrate a transcriber, model and voice API to simulate speech-to-speech, OpenAI’s Realtime API natively processes audio in and audio out. + +**In this guide, you'll learn to:** +- Choose the right realtime model for your use case +- Configure voice assistants with realtime capabilities +- Implement best practices for production deployments +- Optimize prompts specifically for realtime models + +## Available models + + + The `gpt-realtime-2025-08-28` model is production-ready. + + +OpenAI offers three realtime models, each with different capabilities and cost/performance trade-offs: + +| Model | Status | Best For | Key Features | +|-------|---------|----------|--------------| +| `gpt-realtime-2025-08-28` | **Production** | Production workloads | Production Ready | +| `gpt-4o-realtime-preview-2024-12-17` | Preview | Development & testing | Balanced performance/cost | +| `gpt-4o-mini-realtime-preview-2024-12-17` | Preview | Cost-sensitive apps | Lower latency, reduced cost | + +## Voice options + +Realtime models support a specific set of OpenAI voices optimized for speech-to-speech: + + + + Available across all realtime models: + - `alloy` - Neutral and balanced + - `echo` - Warm and engaging + - `shimmer` - Energetic and expressive + + + Only available with realtime models: + - `marin` - Professional and clear + - `cedar` - Natural and conversational + + + + + The following voices are **NOT** supported by realtime models: ash, ballad, coral, fable, onyx, and nova. + + +## Configuration + +### Basic setup + +Configure a realtime assistant with function calling: + + +```json title="Assistant Configuration" +{ + "model": { + "provider": "openai", + "model": "gpt-realtime-2025-08-28", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant. Be concise and friendly." + } + ], + "temperature": 0.7, + "maxTokens": 250, + "tools": [ + { + "type": "function", + "function": { + "name": "getWeather", + "description": "Get the current weather", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city name" + } + }, + "required": ["location"] + } + } + } + ] + }, + "voice": { + "provider": "openai", + "voiceId": "alloy" + } +} +``` +```typescript title="TypeScript SDK" +import { Vapi } from '@vapi-ai/server-sdk'; + +const vapi = new Vapi({ token: process.env.VAPI_API_KEY }); + +const assistant = await vapi.assistants.create({ + model: { + provider: "openai", + model: "gpt-realtime-2025-08-28", + messages: [{ + role: "system", + content: "You are a helpful assistant. Be concise and friendly." + }], + temperature: 0.7, + maxTokens: 250, + tools: [{ + type: "function", + function: { + name: "getWeather", + description: "Get the current weather", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "The city name" + } + }, + required: ["location"] + } + } + }] + }, + voice: { + provider: "openai", + voiceId: "alloy" + } +}); +``` +```python title="Python SDK" +from vapi import Vapi + +vapi = Vapi(token=os.getenv("VAPI_API_KEY")) + +assistant = vapi.assistants.create( + model={ + "provider": "openai", + "model": "gpt-realtime-2025-08-28", + "messages": [{ + "role": "system", + "content": "You are a helpful assistant. Be concise and friendly." + }], + "temperature": 0.7, + "maxTokens": 250, + "tools": [{ + "type": "function", + "function": { + "name": "getWeather", + "description": "Get the current weather", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city name" + } + }, + "required": ["location"] + } + } + }] + }, + voice={ + "provider": "openai", + "voiceId": "alloy" + } +) +``` + + +### Using realtime-exclusive voices + +To use the enhanced voices only available with realtime models: + +```json +{ + "voice": { + "provider": "openai", + "voiceId": "marin" // or "cedar" + } +} +``` + +### Handling instructions + + + Unlike traditional OpenAI models, realtime models receive instructions through the session configuration. Vapi automatically converts your system messages to session instructions during WebSocket initialization. + + +The system message in your model configuration is automatically optimized for realtime processing: + +1. System messages are converted to session instructions +2. Instructions are sent during WebSocket session initialization +3. The instructions field supports the same prompting strategies as system messages + +## Prompting best practices + - The Realtime API is currently in beta, and not recommended for production use by OpenAI. We're excited to have you try this new feature and welcome your [feedback](https://discord.com/invite/pUFNcf2WmH) as we continue to refine and improve the experience. + Realtime models benefit from different prompting techniques than text-based models. These guidelines are based on [OpenAI's official prompting guide](https://cookbook.openai.com/examples/realtime_prompting_guide). -OpenAI’s Realtime API enables developers to use a native speech-to-speech model. Unlike other Vapi configurations which orchestrate a transcriber, model and voice API to simulate speech-to-speech, OpenAI’s Realtime API natively processes audio in and audio out. +### General tips + +- **Iterate relentlessly**: Small wording changes can significantly impact behavior +- **Use bullet points over paragraphs**: Clear, short bullets outperform long text blocks +- **Guide with examples**: The model closely follows sample phrases you provide +- **Be precise**: Ambiguity or conflicting instructions degrade performance +- **Control language**: Pin output to a target language to prevent unwanted switching +- **Reduce repetition**: Add variety rules to avoid robotic phrasing +- **Capitalize for emphasis**: Use CAPS for key rules to make them stand out + +### Prompt structure + +Organize your prompts with clear sections for better model comprehension: + +``` +# Role & Objective +You are a customer service agent for Acme Corp. Your goal is to resolve issues quickly. + +# Personality & Tone +- Friendly, professional, and empathetic +- Speak naturally at a moderate pace +- Keep responses to 2-3 sentences + +# Instructions +- Greet callers warmly +- Ask clarifying questions before offering solutions +- Always confirm understanding before proceeding + +# Tools +Use the available tools to look up account information and process requests. + +# Safety +If a caller becomes aggressive or requests something outside your scope, +politely offer to transfer them to a specialist. +``` + +### Realtime-specific techniques + + + + Control the model's speaking pace with explicit instructions: + + ``` + ## Pacing + - Deliver responses at a natural, conversational speed + - Do not rush through information + - Pause briefly between key points + ``` + + + Realtime models excel at maintaining consistent personality: + + ``` + ## Personality + - Warm and approachable like a trusted advisor + - Professional but not robotic + - Show genuine interest in helping + ``` + + + Guide natural conversation progression: + + ``` + ## Conversation Flow + 1. Greeting: Welcome caller and ask how you can help + 2. Discovery: Understand their specific needs + 3. Solution: Offer the best available option + 4. Confirmation: Ensure they're satisfied before ending + ``` + + + +## Migration guide + +Transitioning from standard STT/TTS to realtime models: + + + + Change your model to one of the realtime options: + ```json + { + "model": { + "provider": "openai", + "model": "gpt-realtime-2025-08-28" // Changed from gpt-4 + } + } + ``` + + + + Ensure your selected voice is supported (alloy, echo, shimmer, marin, or cedar) + + + + Realtime models handle speech-to-speech natively, so transcriber settings are not needed + + + + Your existing function configurations work unchanged with realtime models + + + + Apply realtime-specific prompting techniques for best results + + + +## Best practices + +### Model selection strategy + + + + **Best for production workloads requiring:** + - Structured outputs for form filling or data collection + - Complex function orchestration + - Highest quality voice interactions + - Responses API integration + + + + **Best for development and testing:** + - Prototyping voice applications + - Balanced cost/performance during development + - Testing conversation flows before production + + + + **Best for cost-sensitive applications:** + - High-volume voice interactions + - Simple Q&A or routing scenarios + - Applications where latency is critical + + + +### Performance optimization + +- **Temperature settings**: Use 0.5-0.7 for consistent yet natural responses +- **Max tokens**: Set appropriate limits (200-300) for conversational responses +- **Voice selection**: Test different voices to match your brand personality +- **Function design**: Keep function schemas simple for faster execution + +### Error handling + +Handle edge cases gracefully: + +```json +{ + "messages": [{ + "role": "system", + "content": "If you don't understand the user, politely ask them to repeat. Never make assumptions about unclear requests." + }] +} +``` + +## Current limitations + + + Be aware of these limitations when implementing realtime models: + + +- **Knowledge Bases** are not currently supported with the Realtime API +- **Endpointing and Interruption** models are managed by Vapi's orchestration layer +- **Custom voice cloning** is not available for realtime models +- **Some OpenAI voices** (ash, ballad, coral, fable, onyx, nova) are incompatible +- **Transcripts** may have slight differences from traditional STT output + +## Additional resources + +- [OpenAI Realtime Documentation](https://platform.openai.com/docs/guides/realtime) +- [Realtime Prompting Guide](https://platform.openai.com/docs/guides/realtime-models-prompting) +- [Prompting Cookbook](https://cookbook.openai.com/examples/realtime_prompting_guide) +- [Vapi Discord Community](https://discord.com/invite/pUFNcf2WmH) + +## Next steps -To start using it with your Vapi assistants, select `gpt-4o-realtime-preview-2024-12-17` as your model. -- Please note that only OpenAI voices may be selected while using this model. The voice selection will not act as a TTS (text-to-speech) model, but rather as the voice used within the speech-to-speech model. -- Also note that we don’t currently support Knowledge Bases with the Realtime API. -- Lastly, note that our Realtime integration still retains the rest of Vapi's orchestration layer such as Endpointing and Interruption models to enable a reliable conversational flow. \ No newline at end of file +Now that you understand OpenAI Realtime models: +- **[Phone Calling Guide](/phone-calling):** Set up inbound and outbound calling +- **[Assistant Hooks](/assistants/assistant-hooks):** Add custom logic to your conversations +- **[Voice Providers](/providers/voice/openai):** Explore other voice options \ No newline at end of file From f3dbab640631e352dff4a6ba0199638b7a7440c6 Mon Sep 17 00:00:00 2001 From: Adi Sai Date: Sat, 13 Sep 2025 17:01:52 -0700 Subject: [PATCH 026/171] fix paths for linking (#685) * fix paths for linking * fix more broken links --- fern/customization/custom-transcriber.mdx | 2 +- fern/customization/custom-tts.mdx | 2 +- fern/phone-numbers/inbound-sms.mdx | 2 +- fern/tools/default-tools.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fern/customization/custom-transcriber.mdx b/fern/customization/custom-transcriber.mdx index 741c6c511..771b4dfc7 100644 --- a/fern/customization/custom-transcriber.mdx +++ b/fern/customization/custom-transcriber.mdx @@ -439,7 +439,7 @@ You'll learn how to: - **Streaming support requirement:** The custom transcriber must support streaming. Vapi sends continuous audio data over the WebSocket, and your server must handle this stream in real time. - **Authentication:** - For secure transcriber endpoints, use **Custom Credentials** with `credentialId`. Create [Custom Credentials](../server-url/server-authentication) in the dashboard to manage Bearer Token, OAuth 2.0, or HMAC authentication. For backward compatibility, the legacy `secret` field is still supported and sends the value as an `x-vapi-secret` HTTP header. + For secure transcriber endpoints, use **Custom Credentials** with `credentialId`. Create [Custom Credentials](../../server-url/server-authentication) in the dashboard to manage Bearer Token, OAuth 2.0, or HMAC authentication. For backward compatibility, the legacy `secret` field is still supported and sends the value as an `x-vapi-secret` HTTP header. - **Buffering:** The solution buffers PCM audio and performs simple validation (e.g. ensuring stereo PCM data length is a multiple of 4). If the audio data is malformed, it is trimmed to a valid length. - **Channel detection:** diff --git a/fern/customization/custom-tts.mdx b/fern/customization/custom-tts.mdx index d08d2e8e8..fc7903ad0 100644 --- a/fern/customization/custom-tts.mdx +++ b/fern/customization/custom-tts.mdx @@ -75,7 +75,7 @@ Create authentication credentials in the dashboard and reference them by ID: -Create [Custom Credentials](../server-url/server-authentication) in the Vapi dashboard for better security and credential management. +Create [Custom Credentials](../../server-url/server-authentication) in the Vapi dashboard for better security and credential management. ### Legacy Authentication Methods diff --git a/fern/phone-numbers/inbound-sms.mdx b/fern/phone-numbers/inbound-sms.mdx index a1a75e05a..c08ff607e 100644 --- a/fern/phone-numbers/inbound-sms.mdx +++ b/fern/phone-numbers/inbound-sms.mdx @@ -69,7 +69,7 @@ Update your number to set `smsEnabled: true` if it was previously disabled. - **Twilio only**: Other telephony providers are not supported for inbound SMS at this time. - **Webhooks**: With `smsEnabled: true`, Vapi manages the Twilio Messaging webhook for you. -For full endpoint details, see the [OpenAPI reference](/api-reference/openapi). +For full endpoint details, see the [OpenAPI reference](https://api.vapi.ai/api-json). ## Next steps diff --git a/fern/tools/default-tools.mdx b/fern/tools/default-tools.mdx index a3741a768..9f6372cc4 100644 --- a/fern/tools/default-tools.mdx +++ b/fern/tools/default-tools.mdx @@ -124,7 +124,7 @@ There are three methods for sending DTMF in a phone call: Vapi's DTMF tool integrates with telephony provider APIs to send DTMF tones using the out-of-band RFC 2833 method. This approach is widely supported and more reliable for transmitting the signals, especially in VoIP environments. -Note, the tool's effectiveness depends on the IVR system's configuration and their capturing method. See our [IVR navigation guide](https://docs.vapi.ai/tools/ivr-navigation) for best practices. +Note, the tool's effectiveness depends on the IVR system's configuration and their capturing method. See our [IVR navigation guide](https://docs.vapi.ai/ivr-navigation) for best practices. #### API Request From 27c70a319ba18c49cb1f4b3901513f0fab2ff1c0 Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:51:16 +0530 Subject: [PATCH 027/171] Update vapi docs with deepgram keyword info (#689) * Refactor: Clarify keyword and keyterm boosting in docs Co-authored-by: sahil * Refactor: Update custom keywords to keyterm prompting Co-authored-by: sahil --------- Co-authored-by: Cursor Agent Co-authored-by: sahil --- fern/customization/custom-keywords.mdx | 84 +++++++++++++++++--------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/fern/customization/custom-keywords.mdx b/fern/customization/custom-keywords.mdx index 6c88d4691..0327cb3b7 100644 --- a/fern/customization/custom-keywords.mdx +++ b/fern/customization/custom-keywords.mdx @@ -1,6 +1,6 @@ --- -title: Custom Keywords -subtitle: Enhanced transcription accuracy guide +title: Deepgram Keywords and Keyterm Prompting +subtitle: Boost STT accuracy for domain words and phrases slug: customization/custom-keywords --- @@ -18,21 +18,25 @@ Keyword boosting is beneficial for: ### Important Notes - Keywords should be uncommon words or proper nouns not frequently recognized by the model. -- Custom model training is the most effective way to ensure accurate keyword recognition. -- For more than 50 keywords, consider custom model training by contacting Deepgram. +- Use single words for `keywords` (no spaces or punctuation). For multi-word phrases, use `keyterm` instead. +- Custom model training is the most effective way to ensure accurate keyword recognition when you need extensive vocabulary coverage. + +### Model support + +- Keywords is available on Deepgram Nova-2, Nova-1, Enhanced, and Base speech-to-text models. +- For Nova-3 models, use Keyterm Prompting instead of Keywords. ## Enabling Keyword Boosting in Vapi ### API Call Integration -To enable keyword boosting, you need to add a `keywords` parameter to your Vapi assistant's transcriber section. This parameter should include the keywords and their respective intensifiers. +To enable keyword boosting, add the `keywords` parameter to your assistant's `transcriber` configuration when using the Deepgram provider. You can also supply `keyterm` to boost recall for phrases. ### Example of POST Request To create an assistant with keyword boosting enabled, you can make the following POST request to Vapi: ```bash -bashCopy code curl \ --request POST \ --header 'Authorization: Bearer ' \ @@ -40,27 +44,33 @@ curl \ --data '{ "name": "Emma", "model": { - "model": "gpt-4o", - "provider": "openai" + "model": "gpt-4o", + "provider": "openai" }, "voice": { - "voiceId": "emma", - "provider": "azure" + "voiceId": "emma", + "provider": "azure" }, "transcriber": { - "provider": "deepgram", - "model": "nova-2", - "language": "bg", - "smartFormat": true, - "keywords": [ - "snuffleupagus:1" - ] + "provider": "deepgram", + "model": "nova-2", + "language": "en", + "smartFormat": true, + "keywords": [ + "snuffleupagus:5", + "systrom", + "krieger" + ], + "keyterm": [ + "order number", + "account ID", + "PCI compliance" + ] }, "firstMessage": "Hi, I am Emma, what is your name?", "firstMessageMode": "assistant-speaks-first" }' \ https://api.vapi.ai/assistant - ``` In this configuration: @@ -68,28 +78,44 @@ In this configuration: - **name**: The name of the assistant. - **model**: Specifies the model and provider for the assistant's conversational capabilities. - **voice**: Specifies the voice and provider for the assistant's speech. -- **transcriber**: Specifies Deepgram as the transcription provider, along with the model, language, smart formatting, and keywords for boosting. +- **transcriber**: Specifies Deepgram as the transcription provider, along with the model, language, smart formatting, and both `keywords` (single words) and `keyterm` (phrases) for boosting. - **firstMessage**: The initial message the assistant will speak. - **firstMessageMode**: Specifies that the assistant speaks first. -### Intensifiers +### Format and intensifiers + +The `keywords` array accepts single-word tokens consisting of letters and digits, with an optional integer intensifier after a colon: + +- Accepted forms: `apple`, `apple:3`, `apple:-2` +- Not accepted: `order number` (use `keyterm`), `hello-world`, `foo_bar`, `rate:1.5` (decimals are not supported by this schema) -Intensifiers are exponential factors that boost or suppress the likelihood of the specified keyword being recognized. The default intensifier is `1`. Higher values increase the likelihood, while `0` is equivalent to not specifying a keyword. +Intensifiers are exponential factors that boost or suppress the likelihood of the specified keyword being recognized. The default intensifier is `1`. Higher values increase the likelihood, while `0` is equivalent to not specifying a keyword. Negative values suppress recognition. - **Boosting Example:** `keywords=snuffleupagus:5` - **Suppressing Example:** `keywords=kansas:-10` -### Best Practices for Keyword Boosting +### Keyterm prompting (phrases) -1. **Send Uncommon Keywords:** Focus on keywords not successfully transcribed by the model. -2. **Send Keywords Once:** Avoid repeating keywords. -3. **Use Individual Keywords:** Prefer individual terms over phrases. -4. **Use Proper Spelling:** Spell proper nouns as you want them to appear in transcripts. -5. **Moderate Intensifiers:** Start with small increments to avoid false positives. -6. **Custom Model Training:** For extensive vocabulary needs, consider custom model training. +Deepgram's Keyterm Prompting improves Keyword Recall Rate (KRR) for important keyterms or phrases. Use `keyterm` for multi‑word phrases you want the model to detect more reliably. Unlike `keywords`, keyterms are specified as plain strings without intensifiers. + +Example: `"keyterm": ["account number", "confirmation code", "HIPAA compliance"]` + +### Best Practices for Keyword and Keyterm Boosting + +1. **Start small:** Begin without any boosting; add keywords/keyterms only where needed. +2. **Send uncommon words:** Focus on proper nouns or domain terms the model often misses. +3. **Use `keywords` for single words; `keyterm` for phrases:** Avoid spaces in `keywords`. +4. **Avoid duplicates:** Send each keyword once; duplicates don't improve results. +5. **Moderate intensifiers:** Use minimal integer boosts to reduce false positives; increase cautiously. +6. **Correct spelling/casing:** Provide the spelling and capitalization you want in transcripts. +7. **Consider custom models:** For extensive vocabularies, consider custom model training with Deepgram. ### Additional Resources -For more detailed information on Deepgram's keyword boosting feature, refer to the Deepgram Keyword Boosting Documentation. +For more details, see: + +- Deepgram Keywords: [developers.deepgram.com/docs/keywords](https://developers.deepgram.com/docs/keywords) +- Deepgram Keyterm Prompting: [developers.deepgram.com/docs/keyterm](https://developers.deepgram.com/docs/keyterm) +- API reference: Deepgram transcriber `keywords` and `keyterm` in the [API reference](https://api.vapi.ai/api#:~:text=DeepgramTranscriber) By following these guidelines, you can effectively utilize Deepgram's keyword boosting feature within your Vapi assistant, ensuring enhanced transcription accuracy for specialized terminology and uncommon proper nouns. \ No newline at end of file From 914a1181e8cf4d8030b1de5292ff4e985f41981e Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:51:40 +0530 Subject: [PATCH 028/171] Update docs: redirect expert directory to library (#688) Co-authored-by: Cursor Agent Co-authored-by: sahil --- fern/docs.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fern/docs.yml b/fern/docs.yml index add14f79c..ec5d1bb3b 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -612,7 +612,7 @@ navigation: href: https://content.vapi.ai/ - link: Expert Directory icon: fa-light fa-book-user - href: https://vapi.ai/creators + href: https://vapi.ai/library - link: Discord href: https://discord.com/invite/pUFNcf2WmH icon: fa-brands fa-discord @@ -848,6 +848,8 @@ redirects: destination: /api-reference/webhooks/client-message - source: "/api-reference/phone-numbers/import-twilio-number" destination: "/api-reference/phone-numbers/create-phone-number" + - source: /community/expert-directory + destination: https://vapi.ai/library - source: "api-reference/calls/create-call" destination: "https://api.vapi.ai/api#/Calls/CallController_create" - source: "/getting_started" From 524ba3d3a81ad0d2077d99efac6edc398e284ebe Mon Sep 17 00:00:00 2001 From: Sahil Suman <34382211+sahilsuman933@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:02:41 +0530 Subject: [PATCH 029/171] feat: Add empty string option for keypadInputPlan delimiters (#690) Co-authored-by: Cursor Agent Co-authored-by: sahil --- fern/apis/api/openapi-overrides.yml | 8 ++++++++ fern/apis/webhooks/openapi-overrides.yml | 8 ++++++++ fern/changelog/2025-02-27.mdx | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/fern/apis/api/openapi-overrides.yml b/fern/apis/api/openapi-overrides.yml index 9873c7274..fb413081a 100644 --- a/fern/apis/api/openapi-overrides.yml +++ b/fern/apis/api/openapi-overrides.yml @@ -432,6 +432,14 @@ components: name: Asterisk "#": name: Hash + items: + x-fern-enum: + "": + name: Empty + "*": + name: Asterisk + "#": + name: Hash NeuphonicVoice: title: NeuphonicVoice properties: diff --git a/fern/apis/webhooks/openapi-overrides.yml b/fern/apis/webhooks/openapi-overrides.yml index 8f9aca57c..047e8aed6 100644 --- a/fern/apis/webhooks/openapi-overrides.yml +++ b/fern/apis/webhooks/openapi-overrides.yml @@ -246,6 +246,14 @@ components: name: Asterisk "#": name: Hash + items: + x-fern-enum: + "": + name: Empty + "*": + name: Asterisk + "#": + name: Hash TransferDestinationAssistant: properties: transferMode: diff --git a/fern/changelog/2025-02-27.mdx b/fern/changelog/2025-02-27.mdx index d8cf366b1..27a6b6c50 100644 --- a/fern/changelog/2025-02-27.mdx +++ b/fern/changelog/2025-02-27.mdx @@ -7,7 +7,7 @@ Configuration options: { "keypadInputPlan": { "enabled": true, // Default: false - "delimiters": "#", // Options: "#", "*", or "" (empty string) + "delimiters": ["#"], // Options: ["#"], ["*"], [""] "timeoutSeconds": 2 // Range: 0.5-10 seconds, Default: 2 } } From be77cb35589d8e6d139ace4707a7ea8823dc670c Mon Sep 17 00:00:00 2001 From: arthurchi93 <152110249+arthurchi93@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:47:14 -0700 Subject: [PATCH 030/171] unhide handoff docs (#692) --- fern/docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/fern/docs.yml b/fern/docs.yml index ec5d1bb3b..8fdc43093 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -191,7 +191,6 @@ navigation: - page: Handoff tool path: tools/handoff.mdx icon: fa-light fa-hand-holding-hand - hidden: true - section: External tools icon: fa-light fa-cubes contents: From 12915f75bc710b3e7088d7d82f9961b041e57729 Mon Sep 17 00:00:00 2001 From: smeltserMake Date: Tue, 16 Sep 2025 02:47:49 -0500 Subject: [PATCH 031/171] docs: Add Make MCP server setup instructions (#694) - Add Make MCP configuration steps in setup notes - Include Make MCP provider documentation with detailed steps - Add links to Make MCP documentation resources Co-authored-by: jd-smeltser <94378935+jd-smeltser@users.noreply.github.com> --- fern/tools/mcp.mdx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/fern/tools/mcp.mdx b/fern/tools/mcp.mdx index 9b34bd987..24606272a 100644 --- a/fern/tools/mcp.mdx +++ b/fern/tools/mcp.mdx @@ -21,7 +21,7 @@ This powerful integration allows your assistant to leverage a wide range of tool Before you can use the MCP integration, you need to: 1. Have access to the Vapi Dashboard 2. Have an assistant created in Vapi -3. Have access to an MCP server URL (e.g., from Zapier, Composio, or other MCP providers) +3. Have access to an MCP server URL (e.g., from Make, Zapier, Composio, or other MCP providers) ## Setup Steps @@ -29,12 +29,14 @@ Before you can use the MCP integration, you need to: First, you need to obtain an MCP server URL from your chosen provider: -1. Sign up for an MCP-compatible service (e.g., Zapier, Composio) +1. Sign up for an MCP-compatible service (e.g., Make, Zapier, Composio) 2. Navigate to the MCP configuration section of your provider 3. Generate or copy your MCP server URL For Zapier MCP, visit https://mcp.zapier.com/mcp/?client=vapi? to generate your MCP server URL. This URL should be treated as a credential and kept secure. + + To generate your Make MCP Server URL (also known as MCP Token), navigate to your Make profile > API Access tab > Tokens > Add token. See [Obtaining MCP Token documentation](https://developers.make.com/mcp-server/make-cloud-mcp-server/obtaining-mcp-token) for detailed instructions. This URL should be treated as a credential and kept secure. ### 2. Create and Configure MCP Tool @@ -192,6 +194,20 @@ If you need to use Server-Sent Events protocol instead: ## Example MCP Providers +### Make MCP + +The Make MCP Server provides access to the Make scenarios you select, allowing you to provision them as Custom Tools through MCP. + +1. Define your Make scenarios, configuring scenario [inputs and outputs](https://help.make.com/scenario-inputs-and-outputs) and setting them to be [scheduled on demand](https://help.make.com/schedule-a-scenario#30pY_) +2. Get your [Make MCP Token](https://developers.make.com/mcp-server/make-cloud-mcp-server/obtaining-mcp-token) +3. Choose your MCP [Tool Access Control](https://developers.make.com/mcp-server/make-cloud-mcp-server/tool-access-control) mechanism and define your MCP URL +4. Add the URL to your Vapi MCP tool configuration +5. Your assistant will now have access to your chosen Make scenarios + + + Make Cloud MCP allows you to build simple or complex Custom Tools using business logic to access the most important apps in your business tech stack. Check the full list in the Make app gallery. + + ### Zapier MCP Zapier offers an MCP server that provides access to thousands of app integrations: @@ -230,6 +246,7 @@ Composio also offers an MCP server for integration: - [Model Context Protocol Introduction](https://modelcontextprotocol.io/introduction) - [Zapier MCP](https://zapier.com/mcp) +- [Make MCP](https://developers.make.com/mcp-server) Date: Wed, 17 Sep 2025 01:18:19 -0700 Subject: [PATCH 032/171] Update API specifications with fern api update (#697) Co-authored-by: github-actions --- fern/apis/api/openapi.json | 754 ++++++++++++++++++++++++++++++++----- 1 file changed, 650 insertions(+), 104 deletions(-) diff --git a/fern/apis/api/openapi.json b/fern/apis/api/openapi.json index ecb32b45e..59bd996e5 100644 --- a/fern/apis/api/openapi.json +++ b/fern/apis/api/openapi.json @@ -3886,19 +3886,21 @@ "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/CreateEvalDTO", - "title": "CreateEvalDTO" - } - ] + "$ref": "#/components/schemas/CreateEvalDTO" } } } }, "responses": { "201": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Eval" + } + } + } } }, "tags": [ @@ -3912,7 +3914,7 @@ }, "get": { "operationId": "EvalController_getPaginated", - "summary": "Get Evals with pagination", + "summary": "List Evals", "parameters": [ { "name": "id", @@ -4078,19 +4080,21 @@ "content": { "application/json": { "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/UpdateEvalDTO", - "title": "UpdateEvalDTO" - } - ] + "$ref": "#/components/schemas/UpdateEvalDTO" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Eval" + } + } + } } }, "tags": [ @@ -4117,7 +4121,14 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Eval" + } + } + } } }, "tags": [ @@ -4144,7 +4155,14 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Eval" + } + } + } } }, "tags": [ @@ -4173,7 +4191,14 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvalRun" + } + } + } } }, "tags": [ @@ -4223,7 +4248,7 @@ "/eval/run": { "post": { "operationId": "EvalController_run", - "summary": "Run Eval", + "summary": "Create Eval Run", "parameters": [], "requestBody": { "required": true, @@ -4261,7 +4286,7 @@ }, "get": { "operationId": "EvalController_getRunsPaginated", - "summary": "Get Eval Runs with pagination", + "summary": "List Eval Runs", "parameters": [ { "name": "id", @@ -5683,6 +5708,7 @@ "pl", "pt", "pt-BR", + "pt-PT", "ro", "ru", "sk", @@ -7372,6 +7398,7 @@ "pl", "pt", "pt-BR", + "pt-PT", "ro", "ru", "sk", @@ -14339,6 +14366,217 @@ "to" ] }, + "RecordingConsentHangUpToDeclinePlan": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "This is the message asking for consent to record the call.", + "maxLength": 1000, + "examples": [ + "For quality purposes, this call may be recorded. Please stay on the line if you agree or end the call if you do not consent.", + "This call may be recorded for quality and training purposes. Do you consent to being recorded?" + ] + }, + "voice": { + "description": "This is the voice to use for the consent message. If not specified, inherits from the assistant's voice.\nUse a different voice for the consent message for a better user experience.", + "oneOf": [ + { + "$ref": "#/components/schemas/AzureVoice", + "title": "AzureVoice" + }, + { + "$ref": "#/components/schemas/CartesiaVoice", + "title": "CartesiaVoice" + }, + { + "$ref": "#/components/schemas/CustomVoice", + "title": "CustomVoice" + }, + { + "$ref": "#/components/schemas/DeepgramVoice", + "title": "DeepgramVoice" + }, + { + "$ref": "#/components/schemas/ElevenLabsVoice", + "title": "ElevenLabsVoice" + }, + { + "$ref": "#/components/schemas/HumeVoice", + "title": "HumeVoice" + }, + { + "$ref": "#/components/schemas/LMNTVoice", + "title": "LMNTVoice" + }, + { + "$ref": "#/components/schemas/NeuphonicVoice", + "title": "NeuphonicVoice" + }, + { + "$ref": "#/components/schemas/OpenAIVoice", + "title": "OpenAIVoice" + }, + { + "$ref": "#/components/schemas/PlayHTVoice", + "title": "PlayHTVoice" + }, + { + "$ref": "#/components/schemas/RimeAIVoice", + "title": "RimeAIVoice" + }, + { + "$ref": "#/components/schemas/SmallestAIVoice", + "title": "SmallestAIVoice" + }, + { + "$ref": "#/components/schemas/TavusVoice", + "title": "TavusVoice" + }, + { + "$ref": "#/components/schemas/VapiVoice", + "title": "VapiVoice" + }, + { + "$ref": "#/components/schemas/SesameVoice", + "title": "SesameVoice" + }, + { + "$ref": "#/components/schemas/InworldVoice", + "title": "InworldVoice" + }, + { + "$ref": "#/components/schemas/MinimaxVoice", + "title": "MinimaxVoice" + } + ] + }, + "type": { + "type": "string", + "description": "This is the type of recording consent plan.", + "enum": [ + "hang-up-to-decline" + ], + "example": "hang-up-to-decline" + }, + "waitSeconds": { + "type": "number", + "description": "Number of seconds to wait before transferring to the assistant if user stays on the call", + "minimum": 1, + "maximum": 5, + "default": 2, + "example": 2 + } + }, + "required": [ + "message", + "type" + ] + }, + "RecordingConsentVerbalPlan": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "This is the message asking for consent to record the call.", + "maxLength": 1000, + "examples": [ + "For quality purposes, this call may be recorded. Please stay on the line if you agree or end the call if you do not consent.", + "This call may be recorded for quality and training purposes. Do you consent to being recorded?" + ] + }, + "voice": { + "description": "This is the voice to use for the consent message. If not specified, inherits from the assistant's voice.\nUse a different voice for the consent message for a better user experience.", + "oneOf": [ + { + "$ref": "#/components/schemas/AzureVoice", + "title": "AzureVoice" + }, + { + "$ref": "#/components/schemas/CartesiaVoice", + "title": "CartesiaVoice" + }, + { + "$ref": "#/components/schemas/CustomVoice", + "title": "CustomVoice" + }, + { + "$ref": "#/components/schemas/DeepgramVoice", + "title": "DeepgramVoice" + }, + { + "$ref": "#/components/schemas/ElevenLabsVoice", + "title": "ElevenLabsVoice" + }, + { + "$ref": "#/components/schemas/HumeVoice", + "title": "HumeVoice" + }, + { + "$ref": "#/components/schemas/LMNTVoice", + "title": "LMNTVoice" + }, + { + "$ref": "#/components/schemas/NeuphonicVoice", + "title": "NeuphonicVoice" + }, + { + "$ref": "#/components/schemas/OpenAIVoice", + "title": "OpenAIVoice" + }, + { + "$ref": "#/components/schemas/PlayHTVoice", + "title": "PlayHTVoice" + }, + { + "$ref": "#/components/schemas/RimeAIVoice", + "title": "RimeAIVoice" + }, + { + "$ref": "#/components/schemas/SmallestAIVoice", + "title": "SmallestAIVoice" + }, + { + "$ref": "#/components/schemas/TavusVoice", + "title": "TavusVoice" + }, + { + "$ref": "#/components/schemas/VapiVoice", + "title": "VapiVoice" + }, + { + "$ref": "#/components/schemas/SesameVoice", + "title": "SesameVoice" + }, + { + "$ref": "#/components/schemas/InworldVoice", + "title": "InworldVoice" + }, + { + "$ref": "#/components/schemas/MinimaxVoice", + "title": "MinimaxVoice" + } + ] + }, + "type": { + "type": "string", + "description": "This is the type of recording consent plan.", + "enum": [ + "verbal" + ], + "example": "verbal" + }, + "declineTool": { + "type": "object", + "description": "Tool to execute if user verbally declines recording consent" + } + }, + "required": [ + "message", + "type", + "declineTool" + ] + }, "SecurityFilterBase": { "type": "object", "properties": {} @@ -14400,6 +14638,25 @@ "$ref": "#/components/schemas/SecurityFilterPlan" } ] + }, + "recordingConsentPlan": { + "oneOf": [ + { + "$ref": "#/components/schemas/RecordingConsentHangUpToDeclinePlan", + "title": "RecordingConsentHangUpToDeclinePlan" + }, + { + "$ref": "#/components/schemas/RecordingConsentVerbalPlan", + "title": "RecordingConsentVerbalPlan" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "hang-up-to-decline": "#/components/schemas/RecordingConsentHangUpToDeclinePlan", + "verbal": "#/components/schemas/RecordingConsentVerbalPlan" + } + } } } }, @@ -15792,6 +16049,11 @@ "$ref": "#/components/schemas/KeypadInputPlan" } ] + }, + "voicemailMessage": { + "type": "string", + "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", + "maxLength": 1000 } }, "required": [ @@ -16740,7 +17002,17 @@ "selene", "theia", "vesta", - "zeus" + "zeus", + "celeste", + "estrella", + "nestor", + "sirio", + "carina", + "alvaro", + "diana", + "aquila", + "selena", + "javier" ], "title": "This is the Deepgram Voice ID" }, @@ -18480,7 +18752,8 @@ "description": "This is the model that will be used. Options are 'speech-02-hd' and 'speech-02-turbo'.\nspeech-02-hd is optimized for high-fidelity applications like voiceovers and audiobooks.\nspeech-02-turbo is designed for real-time applications with low latency.\n\n@default \"speech-02-turbo\"", "enum": [ "speech-02-hd", - "speech-02-turbo" + "speech-02-turbo", + "speech-2.5-turbo-preview" ], "example": "speech-02-turbo", "default": "speech-02-turbo" @@ -18523,6 +18796,58 @@ ], "default": "worldwide" }, + "languageBoost": { + "type": "string", + "description": "Language hint for MiniMax T2A. Example: yue (Cantonese), zh (Chinese), en (English).", + "enum": [ + "Chinese", + "Chinese,Yue", + "English", + "Arabic", + "Russian", + "Spanish", + "French", + "Portuguese", + "German", + "Turkish", + "Dutch", + "Ukrainian", + "Vietnamese", + "Indonesian", + "Japanese", + "Italian", + "Korean", + "Thai", + "Polish", + "Romanian", + "Greek", + "Czech", + "Finnish", + "Hindi", + "Bulgarian", + "Danish", + "Hebrew", + "Malay", + "Persian", + "Slovak", + "Swedish", + "Croatian", + "Filipino", + "Hungarian", + "Norwegian", + "Slovenian", + "Catalan", + "Nynorsk", + "Tamil", + "Afrikaans", + "auto" + ] + }, + "textNormalizationEnabled": { + "type": "boolean", + "description": "Enable MiniMax text normalization to improve number reading and formatting.", + "default": true + }, "chunkPlan": { "description": "This is the plan for chunking the model output before it is sent to the voice provider.", "allOf": [ @@ -18785,7 +19110,17 @@ "selene", "theia", "vesta", - "zeus" + "zeus", + "celeste", + "estrella", + "nestor", + "sirio", + "carina", + "alvaro", + "diana", + "aquila", + "selena", + "javier" ], "title": "This is the Deepgram Voice ID" }, @@ -20357,7 +20692,8 @@ "description": "This is the model that will be used. Options are 'speech-02-hd' and 'speech-02-turbo'.\nspeech-02-hd is optimized for high-fidelity applications like voiceovers and audiobooks.\nspeech-02-turbo is designed for real-time applications with low latency.\n\n@default \"speech-02-turbo\"", "enum": [ "speech-02-hd", - "speech-02-turbo" + "speech-02-turbo", + "speech-2.5-turbo-preview" ], "example": "speech-02-turbo", "default": "speech-02-turbo" @@ -20400,6 +20736,58 @@ ], "default": "worldwide" }, + "languageBoost": { + "type": "string", + "description": "Language hint for MiniMax T2A. Example: yue (Cantonese), zh (Chinese), en (English).", + "enum": [ + "Chinese", + "Chinese,Yue", + "English", + "Arabic", + "Russian", + "Spanish", + "French", + "Portuguese", + "German", + "Turkish", + "Dutch", + "Ukrainian", + "Vietnamese", + "Indonesian", + "Japanese", + "Italian", + "Korean", + "Thai", + "Polish", + "Romanian", + "Greek", + "Czech", + "Finnish", + "Hindi", + "Bulgarian", + "Danish", + "Hebrew", + "Malay", + "Persian", + "Slovak", + "Swedish", + "Croatian", + "Filipino", + "Hungarian", + "Norwegian", + "Slovenian", + "Catalan", + "Nynorsk", + "Tamil", + "Afrikaans", + "auto" + ] + }, + "textNormalizationEnabled": { + "type": "boolean", + "description": "Enable MiniMax text normalization to improve number reading and formatting.", + "default": true + }, "chunkPlan": { "description": "This is the plan for chunking the model output before it is sent to the voice provider.", "allOf": [ @@ -24257,6 +24645,14 @@ }, "itemsBeyondRetention": { "type": "boolean" + }, + "createdAtLe": { + "format": "date-time", + "type": "string" + }, + "createdAtGe": { + "format": "date-time", + "type": "string" } }, "required": [ @@ -26652,6 +27048,11 @@ "$ref": "#/components/schemas/KeypadInputPlan" } ] + }, + "voicemailMessage": { + "type": "string", + "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", + "maxLength": 1000 } }, "required": [ @@ -27258,6 +27659,11 @@ "$ref": "#/components/schemas/KeypadInputPlan" } ] + }, + "voicemailMessage": { + "type": "string", + "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", + "maxLength": 1000 } }, "required": [ @@ -27860,6 +28266,11 @@ "$ref": "#/components/schemas/KeypadInputPlan" } ] + }, + "voicemailMessage": { + "type": "string", + "description": "This is the message that the assistant will say if the call is forwarded to voicemail.\n\nIf unspecified, it will hang up.", + "maxLength": 1000 } } }, @@ -28246,6 +28657,49 @@ "structuredOutputs": { "type": "object", "description": "These are the structured outputs that will be extracted from the call.\nTo enable, set `assistant.artifactPlan.structuredOutputIds` with the IDs of the structured outputs you want to extract." + }, + "transfers": { + "description": "These are the transfer records from warm transfers, including destinations, transcripts, and status.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "RecordingConsent": { + "type": "object", + "properties": { + "type": { + "type": "object", + "description": "This is the type of recording consent." + }, + "granted": { + "type": "boolean", + "description": "This is whether the user granted recording consent." + }, + "grantedAt": { + "format": "date-time", + "type": "string", + "description": "This is the date and time the recording consent was granted." + } + }, + "required": [ + "type", + "granted", + "grantedAt" + ] + }, + "Compliance": { + "type": "object", + "properties": { + "recordingConsent": { + "description": "This is the recording consent of the call. Configure in `assistant.compliancePlan.recordingConsentPlan`.", + "allOf": [ + { + "$ref": "#/components/schemas/RecordingConsent" + } + ] } } }, @@ -28714,6 +29168,7 @@ "call.start.error-vapi-number-outbound-daily-limit", "call.start.error-get-transport", "call.start.error-subscription-wallet-does-not-exist", + "call.start.error-fraud-check-failed", "call.start.error-subscription-frozen", "call.start.error-subscription-insufficient-credits", "call.start.error-subscription-upgrade-failed", @@ -29306,6 +29761,14 @@ } ] }, + "compliance": { + "description": "This is the compliance of the call. Configure in `assistant.compliancePlan`.", + "allOf": [ + { + "$ref": "#/components/schemas/Compliance" + } + ] + }, "phoneCallProviderId": { "type": "string", "description": "The ID of the call as provided by the phone number service. callSid in Twilio. conversationUuid in Vonage. callControlId in Telnyx.\n\nOnly relevant for `outboundPhoneCall` and `inboundPhoneCall` type.", @@ -29868,7 +30331,7 @@ "name": { "type": "string", "description": "This is the name of the function to call", - "maxLength": 40 + "maxLength": 80 } }, "required": [ @@ -37966,8 +38429,8 @@ "properties": { "messages": { "type": "array", - "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", - "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\n\nMock Messages are used to simulate the flow of the conversation\n\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", judgePlan: { type: \"exact\", content: \"I am good, thank you!\" } }]", "items": { "oneOf": [ { @@ -38026,8 +38489,8 @@ "properties": { "messages": { "type": "array", - "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", - "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\n\nMock Messages are used to simulate the flow of the conversation\n\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", judgePlan: { type: \"exact\", content: \"I am good, thank you!\" } }]", "items": { "oneOf": [ { @@ -38123,8 +38586,8 @@ "properties": { "messages": { "type": "array", - "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", - "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\n\nMock Messages are used to simulate the flow of the conversation\n\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", judgePlan: { type: \"exact\", content: \"I am good, thank you!\" } }]", "items": { "oneOf": [ { @@ -38242,7 +38705,7 @@ "type": "string", "description": "This is the content of the system message that would have been added in the middle of the conversation.\nDo not include the assistant prompt as a part of this message. It will automatically be fetched during runtime.", "example": "You are a helpful assistant.", - "maxLength": 1000 + "maxLength": 100000000 } }, "required": [ @@ -38304,27 +38767,23 @@ "properties": { "exitOnFailureEnabled": { "type": "boolean", - "description": "This is whether the evaluation should exit if the assistant message evaluates to false.\nBy default, it is false and the evaluation will continue.\n@default false", - "default": false + "description": "This is whether the evaluation should exit if the assistant message evaluates to false.\nBy default, it is false and the evaluation will continue.\n@default false" }, "contentOverride": { "type": "string", - "description": "This is the content that will be used in the conversation for this assistant turn if provided.\nIt will override the content received from the model.", + "description": "This is the content that will be used in the conversation for this assistant turn moving forward if provided.\nIt will override the content received from the model.", "example": "The weather in San Francisco is sunny.", "maxLength": 1000 }, "toolCallsOverride": { - "description": "This is the tool calls that will be used in the conversation for this assistant turn if provided.\nIt will override the tool calls received from the model.", + "description": "This is the tool calls that will be used in the conversation for this assistant turn moving forward if provided.\nIt will override the tool calls received from the model.", "example": "[{ name: \"get_weather\", arguments: { city: \"San Francisco\" } }]", "type": "array", "items": { "$ref": "#/components/schemas/ChatEvalAssistantMessageMockToolCall" } } - }, - "required": [ - "exitOnFailureEnabled" - ] + } }, "ChatEvalAssistantMessageEvaluation": { "type": "object", @@ -38883,8 +39342,8 @@ "properties": { "messages": { "type": "array", - "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\nMock Messages are used to simulate the flow of the conversation\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", - "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", content: \"I am good, thank you!\" }]", + "description": "This is the mock conversation that will be used to evaluate the flow of the conversation.\n\nMock Messages are used to simulate the flow of the conversation\n\nEvaluation Messages are used as checkpoints in the flow where the model's response to previous conversation needs to be evaluated to check the content and tool calls", + "example": "[{ role: \"user\", content: \"Hello, how are you?\" }, { role: \"assistant\", judgePlan: { type: \"exact\", content: \"I am good, thank you!\" } }]", "items": { "oneOf": [ { @@ -38934,56 +39393,6 @@ } } }, - "EvalRunTargetAssistant": { - "type": "object", - "properties": { - "assistant": { - "description": "This is the transient assistant that will be run against the eval", - "oneOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO", - "title": "CreateAssistantDTO" - } - ], - "allOf": [ - { - "$ref": "#/components/schemas/CreateAssistantDTO" - } - ] - }, - "assistantOverrides": { - "description": "This is the overrides that will be applied to the assistant.", - "example": "{", - "oneOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides", - "title": "AssistantOverrides" - } - ], - "allOf": [ - { - "$ref": "#/components/schemas/AssistantOverrides" - } - ] - }, - "type": { - "type": "string", - "description": "This is the type of the target.\nCurrently it is fixed to `assistant`.", - "example": "assistant", - "enum": [ - "assistant" - ] - }, - "assistantId": { - "type": "string", - "description": "This is the id of the assistant that will be run against the eval", - "example": "123e4567-e89b-12d3-a456-426614174000" - } - }, - "required": [ - "type" - ] - }, "CreateEvalRunDTO": { "type": "object", "properties": { @@ -38997,7 +39406,7 @@ ], "allOf": [ { - "$ref": "#/components/schemas/Eval" + "$ref": "#/components/schemas/CreateEvalDTO" } ] }, @@ -39007,11 +39416,10 @@ { "$ref": "#/components/schemas/EvalRunTargetAssistant", "title": "EvalRunTargetAssistant" - } - ], - "allOf": [ + }, { - "$ref": "#/components/schemas/EvalRunTargetAssistant" + "$ref": "#/components/schemas/EvalRunTargetSquad", + "title": "EvalRunTargetSquad" } ] }, @@ -39125,7 +39533,7 @@ ], "allOf": [ { - "$ref": "#/components/schemas/Eval" + "$ref": "#/components/schemas/CreateEvalDTO" } ] }, @@ -39135,11 +39543,10 @@ { "$ref": "#/components/schemas/EvalRunTargetAssistant", "title": "EvalRunTargetAssistant" - } - ], - "allOf": [ + }, { - "$ref": "#/components/schemas/EvalRunTargetAssistant" + "$ref": "#/components/schemas/EvalRunTargetSquad", + "title": "EvalRunTargetSquad" } ] }, @@ -39285,6 +39692,106 @@ } } }, + "EvalRunTargetAssistant": { + "type": "object", + "properties": { + "assistant": { + "description": "This is the transient assistant that will be run against the eval", + "oneOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO", + "title": "CreateAssistantDTO" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/CreateAssistantDTO" + } + ] + }, + "assistantOverrides": { + "description": "This is the overrides that will be applied to the assistant.", + "example": "{", + "oneOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides", + "title": "AssistantOverrides" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } + ] + }, + "type": { + "type": "string", + "description": "This is the type of the target.\nCurrently it is fixed to `assistant`.", + "example": "assistant", + "enum": [ + "assistant" + ] + }, + "assistantId": { + "type": "string", + "description": "This is the id of the assistant that will be run against the eval", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "required": [ + "type" + ] + }, + "EvalRunTargetSquad": { + "type": "object", + "properties": { + "squad": { + "description": "This is the transient squad that will be run against the eval", + "oneOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO", + "title": "CreateSquadDTO" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/CreateSquadDTO" + } + ] + }, + "assistantOverrides": { + "description": "This is the overrides that will be applied to the assistants.", + "example": "{", + "oneOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides", + "title": "AssistantOverrides" + } + ], + "allOf": [ + { + "$ref": "#/components/schemas/AssistantOverrides" + } + ] + }, + "type": { + "type": "string", + "description": "This is the type of the target.\nCurrently it is fixed to `squad`.", + "example": "squad", + "enum": [ + "squad" + ] + }, + "squadId": { + "type": "string", + "description": "This is the id of the squad that will be run against the eval", + "example": "123e4567-e89b-12d3-a456-426614174000" + } + }, + "required": [ + "type" + ] + }, "CreateOrgDTO": { "type": "object", "properties": { @@ -45513,6 +46020,19 @@ "files" ] }, + "VariableValueGroupBy": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "This is the key of the variable value to group by.", + "maxLength": 100 + } + }, + "required": [ + "key" + ] + }, "TimeRange": { "type": "object", "properties": { @@ -45628,6 +46148,13 @@ ] } }, + "groupByVariableValue": { + "description": "This is the list of variable value keys you want to group by.", + "type": "array", + "items": { + "$ref": "#/components/schemas/VariableValueGroupBy" + } + }, "name": { "type": "string", "description": "This is the name of the query. This will be used to identify the query in the response.", @@ -47526,6 +48053,7 @@ "call.start.error-vapi-number-outbound-daily-limit", "call.start.error-get-transport", "call.start.error-subscription-wallet-does-not-exist", + "call.start.error-fraud-check-failed", "call.start.error-subscription-frozen", "call.start.error-subscription-insufficient-credits", "call.start.error-subscription-upgrade-failed", @@ -48138,6 +48666,14 @@ "format": "date-time", "type": "string", "description": "This is the ISO 8601 date-time string of when the call ended. This can also be found at `call.endedAt` on GET /call/:id." + }, + "compliance": { + "description": "This is the compliance result of the call. This can also be found at `call.compliance` on GET /call/:id.", + "allOf": [ + { + "$ref": "#/components/schemas/Compliance" + } + ] } }, "required": [ @@ -48721,6 +49257,7 @@ "call.start.error-vapi-number-outbound-daily-limit", "call.start.error-get-transport", "call.start.error-subscription-wallet-does-not-exist", + "call.start.error-fraud-check-failed", "call.start.error-subscription-frozen", "call.start.error-subscription-insufficient-credits", "call.start.error-subscription-upgrade-failed", @@ -50912,6 +51449,10 @@ "$ref": "#/components/schemas/HandoffDestinationAssistant" } ] + }, + "error": { + "type": "string", + "description": "This is the error message if the handoff should not be made." } }, "required": [ @@ -51165,7 +51706,7 @@ "properties": { "type": { "type": "string", - "description": "This is the type of the message. Send \"control\" message to control the assistant. `control` options are:\n- \"mute-assistant\" - mute the assistant\n- \"unmute-assistant\" - unmute the assistant\n- \"say-first-message\" - say the first message (this is used when video recording is enabled and the conversation is only started once the client side kicks off the recording)", + "description": "This is the type of the message. Send \"control\" message to control the assistant. `control` options are:\n- \"mute-assistant\" - mute the assistant\n- \"unmute-assistant\" - unmute the assistant\n- \"mute-customer\" - mute the user\n- \"unmute-customer\" - unmute the user\n- \"say-first-message\" - say the first message (this is used when video recording is enabled and the conversation is only started once the client side kicks off the recording)", "enum": [ "control" ] @@ -51176,6 +51717,8 @@ "enum": [ "mute-assistant", "unmute-assistant", + "mute-customer", + "unmute-customer", "say-first-message" ] } @@ -51423,9 +51966,12 @@ "provider": { "type": "string", "enum": [ + "daily", + "vapi.websocket", "twilio", "vonage", - "vapi" + "telnyx", + "vapi.sip" ] }, "minutes": { From cd70bae1ccaa67b59836eeb02bce9ec095043c5b Mon Sep 17 00:00:00 2001 From: Fern Support <126544928+fern-support@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:44:22 -0600 Subject: [PATCH 033/171] fix: remove enum key (#699) Co-authored-by: Deep Singhvi --- fern/apis/api/openapi-overrides.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/fern/apis/api/openapi-overrides.yml b/fern/apis/api/openapi-overrides.yml index fb413081a..3452fc8fb 100644 --- a/fern/apis/api/openapi-overrides.yml +++ b/fern/apis/api/openapi-overrides.yml @@ -239,8 +239,6 @@ components: properties: serverMessages: items: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript @@ -248,8 +246,6 @@ components: properties: serverMessages: items: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript @@ -257,8 +253,6 @@ components: properties: serverMessages: items: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript @@ -266,8 +260,6 @@ components: properties: serverMessages: items: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript @@ -275,8 +267,6 @@ components: title: ClientMessageTranscript properties: type: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript @@ -284,8 +274,6 @@ components: title: ServerMessageTranscript properties: type: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript @@ -293,8 +281,6 @@ components: properties: serverMessages: items: - enum: - - "transcript[transcriptType='final']" x-fern-enum: "transcript[transcriptType='final']": name: FinalTranscript From ef53aaac60d6bafd249221a0f1a7a1e0597aa77f Mon Sep 17 00:00:00 2001 From: roshan Date: Wed, 17 Sep 2025 19:45:26 -0700 Subject: [PATCH 034/171] Update Quickstart guide for Structured Outputs + Fix Typo (#696) * updated SO quick start guide * fixed typo with websocket-transport --- .../structured-outputs-quickstart.mdx | 931 +++++++++--------- fern/calls/websocket-transport.mdx | 6 +- 2 files changed, 465 insertions(+), 472 deletions(-) diff --git a/fern/assistants/structured-outputs-quickstart.mdx b/fern/assistants/structured-outputs-quickstart.mdx index f5d0e1886..45cbd54ea 100644 --- a/fern/assistants/structured-outputs-quickstart.mdx +++ b/fern/assistants/structured-outputs-quickstart.mdx @@ -10,22 +10,38 @@ This quickstart guide will help you set up structured outputs to automatically e ### What are structured outputs? -Structured outputs are AI-powered data extraction templates that automatically capture and organize information from conversations. They work by: +Structured outputs are AI-powered analysis and extraction tools that intelligently process conversation data after calls end. They go beyond simple data extraction to provide intelligent analysis and evaluation. They work by: -1. **Listening to conversations** - As your assistant talks with customers, structured outputs analyze the conversation in real-time -2. **Extracting key information** - Based on your defined schema, they identify and extract relevant data points like names, emails, preferences, and issues -3. **Validating and formatting** - The extracted data is validated against your schema rules and formatted into clean, structured JSON -4. **Delivering results** - The structured data is available immediately after the call ends via API or webhooks +1. **Processing complete call context** - After the call ends, structured outputs analyze the full transcript, messages, tool call results, and call metadata +2. **Intelligent extraction & analysis** - Based on your schema, they can extract data, evaluate outcomes, analyze sentiment, determine success criteria, and summarize complex interactions +3. **Validating and formatting** - Results are validated against your schema rules and formatted into clean, structured JSON +4. **Delivering insights** - The processed data and insights are available via API or webhooks once analysis is complete ### When are structured outputs generated? Structured outputs are processed: -- **During the call** - Data is extracted in real-time as the conversation happens -- **After call completion** - Final validation and formatting occurs when the call ends +- **After call completion** - The full conversation is analyzed once the call ends +- **Processing time** - Typically completes within a few seconds after call termination - **Available via** - Call artifacts in the API response or webhook events +### What data do structured outputs have access to? + +When processing, structured outputs can analyze: +- **Complete transcript** - The full conversation between assistant and customer +- **Messages history** - All messages exchanged during the call +- **Tool call results** - Outcomes from any tools or functions executed +- **Assistant context** - System prompts and configuration used during the call + ### Why use structured outputs? +**Beyond simple data extraction:** +- **Call evaluation** - Determine if objectives were met (appointment booked, issue resolved) +- **Sentiment analysis** - Understand customer satisfaction and emotional state +- **CSAT scoring** - Extract customer satisfaction scores from feedback +- **Intelligent summaries** - Generate contextual summaries of complex conversations +- **Success metrics** - Evaluate agent performance and call outcomes + +**Operational benefits:** - **Automate data entry** - No more manual transcription or form filling - **Ensure consistency** - Every call captures the same structured information - **Enable integrations** - Automatically sync data to CRMs, ticketing systems, or databases @@ -45,79 +61,88 @@ A customer support assistant that automatically extracts: Sign up at [dashboard.vapi.ai](https://dashboard.vapi.ai) - Get your API key from the Dashboard settings + Get your API key from **API Keys** on sidebar ## Step 1: Create your structured output -You can create structured outputs using either the Dashboard UI or the API. - -### Option A: Using the Dashboard (Recommended for beginners) +Define what information you want to extract using a [JSON Schema](https://json-schema.org/learn/getting-started-step-by-step). JSON Schema is a standard for describing data structures - [learn more about JSON Schema here](https://json-schema.org/understanding-json-schema/). - - - 1. Log in to [dashboard.vapi.ai](https://dashboard.vapi.ai) - 2. Click on **Structured Outputs** in the left sidebar - 3. Click **Create New Structured Output** - - - - 1. **Name**: Enter "Support Ticket" - 2. **Type**: Select "AI" (for automatic extraction) - 3. **Description**: Add "Extract support ticket information from customer calls" - - - - Use the visual schema builder or paste this JSON directly: - ```json - { - "type": "object", - "properties": { - "customer": { - "type": "object", - "properties": { - "name": {"type": "string", "description": "Customer full name"}, - "email": {"type": "string", "format": "email", "description": "Customer email"}, - "phone": {"type": "string", "description": "Customer phone number"} - }, - "required": ["name"] - }, - "issue": { + + + + + 1. Log in to [dashboard.vapi.ai](https://dashboard.vapi.ai) + 2. Click on **Structured Outputs** in the left sidebar + 3. Click **Create New Structured Output** + + + + 1. **Name**: Enter "Support Ticket" + 2. **Type**: Select "Object" + 3. **Description**: Add "Extract support ticket information from customer calls" + + + + Use the visual schema builder: + ```json + { "type": "object", "properties": { - "description": {"type": "string", "description": "Issue description"}, - "category": { - "type": "string", - "enum": ["billing", "technical", "general", "complaint"], - "description": "Issue category" + "customer": { + "type": "object", + "properties": { + "name": {"type": "string", "description": "Customer full name"}, + "email": {"type": "string", "format": "email", "description": "Customer email"}, + "phone": {"type": "string", "description": "Customer phone number"} + }, + "required": ["name"] }, - "priority": { - "type": "string", - "enum": ["low", "medium", "high", "urgent"], - "description": "Priority level" + "issue": { + "type": "object", + "properties": { + "description": {"type": "string", "description": "Issue description"}, + "category": { + "type": "string", + "enum": ["billing", "technical", "general", "complaint"], + "description": "Issue category" + }, + "priority": { + "type": "string", + "enum": ["low", "medium", "high", "urgent"], + "description": "Priority level" + } + }, + "required": ["description", "category"] + }, + "followUp": { + "type": "object", + "properties": { + "required": {"type": "boolean", "description": "Whether follow-up is needed"}, + "method": { + "type": "string", + "enum": ["email", "phone", "none"], + "description": "Preferred follow-up method" + }, + "notes": {"type": "string", "description": "Additional notes for follow-up"} + } } }, - "required": ["description", "category"] + "required": ["customer", "issue"] } - }, - "required": ["customer", "issue"] - } - ``` - - - - 1. Click **Create Structured Output** - 2. Copy the generated ID from the details page - 3. You'll use this ID to link to your assistant - - - -### Option B: Using the API - -Define what information you want to extract using a [JSON Schema](https://json-schema.org/learn/getting-started-step-by-step). JSON Schema is a standard for describing data structures - [learn more about JSON Schema here](https://json-schema.org/understanding-json-schema/). - - + ``` + + + + 1. Click **Create Structured Output** + 2. In the structured output dialog, you can directly attach it to an assistant or workflow + 3. Select an existing assistant to attach this output to that assistant + + + + + ```bash title="cURL" curl -X POST https://api.vapi.ai/structured-output \ -H "Authorization: Bearer $VAPI_API_KEY" \ @@ -191,356 +216,364 @@ curl -X POST https://api.vapi.ai/structured-output \ } }' ``` - -```javascript title="Node.js" -const response = await fetch('https://api.vapi.ai/structured-output', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - name: "Support Ticket", - type: "ai", - description: "Extract support ticket information from customer calls", - schema: { - type: "object", - properties: { - customer: { - type: "object", - properties: { - name: { - type: "string", - description: "Customer full name" - }, - email: { - type: "string", - format: "email", - description: "Customer email address" - }, - phone: { - type: "string", - description: "Customer phone number" - } + + + + ```typescript +import { VapiClient } from "@vapi-ai/server-sdk"; + +const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + +const structuredOutput = await vapi.structuredOutputs.create({ + name: "Support Ticket", + type: "ai", + description: "Extract support ticket information from customer calls", + schema: { + type: "object", + properties: { + customer: { + type: "object", + properties: { + name: { + type: "string", + description: "Customer full name" }, - required: ["name"] + email: { + type: "string", + format: "email", + description: "Customer email address" + }, + phone: { + type: "string", + description: "Customer phone number" + } }, - issue: { - type: "object", - properties: { - description: { - type: "string", - description: "Description of the customer issue" - }, - category: { - type: "string", - enum: ["billing", "technical", "general", "complaint"], - description: "Issue category" - }, - priority: { - type: "string", - enum: ["low", "medium", "high", "urgent"], - description: "Issue priority level" - } + required: ["name"] + }, + issue: { + type: "object", + properties: { + description: { + type: "string", + description: "Description of the customer issue" }, - required: ["description", "category"] + category: { + type: "string", + enum: ["billing", "technical", "general", "complaint"], + description: "Issue category" + }, + priority: { + type: "string", + enum: ["low", "medium", "high", "urgent"], + description: "Issue priority level" + } }, - followUp: { - type: "object", - properties: { - required: { - type: "boolean", - description: "Whether follow-up is needed" - }, - method: { - type: "string", - enum: ["email", "phone", "none"], - description: "Preferred follow-up method" - }, - notes: { - type: "string", - description: "Additional notes for follow-up" - } + required: ["description", "category"] + }, + followUp: { + type: "object", + properties: { + required: { + type: "boolean", + description: "Whether follow-up is needed" + }, + method: { + type: "string", + enum: ["email", "phone", "none"], + description: "Preferred follow-up method" + }, + notes: { + type: "string", + description: "Additional notes for follow-up" } } - }, - required: ["customer", "issue"] - } - }) + } + }, + required: ["customer", "issue"] + } }); -const structuredOutput = await response.json(); console.log('Created structured output:', structuredOutput.id); // Save this ID - you'll need it in the next step ``` + -```python title="Python" -import requests + + ```python +from vapi import Vapi import os -response = requests.post( - 'https://api.vapi.ai/structured-output', - headers={ - 'Authorization': f'Bearer {os.environ["VAPI_API_KEY"]}', - 'Content-Type': 'application/json' - }, - json={ - "name": "Support Ticket", - "type": "ai", - "description": "Extract support ticket information from customer calls", - "schema": { - "type": "object", - "properties": { - "customer": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Customer full name" - }, - "email": { - "type": "string", - "format": "email", - "description": "Customer email address" - }, - "phone": { - "type": "string", - "description": "Customer phone number" - } +vapi = Vapi(token=os.environ.get("VAPI_API_KEY")) + +structured_output = vapi.structured_outputs.create( + name="Support Ticket", + type="ai", + description="Extract support ticket information from customer calls", + schema={ + "type": "object", + "properties": { + "customer": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Customer full name" + }, + "email": { + "type": "string", + "format": "email", + "description": "Customer email address" }, - "required": ["name"] + "phone": { + "type": "string", + "description": "Customer phone number" + } }, - "issue": { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Description of the customer issue" - }, - "category": { - "type": "string", - "enum": ["billing", "technical", "general", "complaint"], - "description": "Issue category" - }, - "priority": { - "type": "string", - "enum": ["low", "medium", "high", "urgent"], - "description": "Issue priority level" - } + "required": ["name"] + }, + "issue": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Description of the customer issue" + }, + "category": { + "type": "string", + "enum": ["billing", "technical", "general", "complaint"], + "description": "Issue category" }, - "required": ["description", "category"] + "priority": { + "type": "string", + "enum": ["low", "medium", "high", "urgent"], + "description": "Issue priority level" + } }, - "followUp": { - "type": "object", - "properties": { - "required": { - "type": "boolean", - "description": "Whether follow-up is needed" - }, - "method": { - "type": "string", - "enum": ["email", "phone", "none"], - "description": "Preferred follow-up method" - }, - "notes": { - "type": "string", - "description": "Additional notes for follow-up" - } + "required": ["description", "category"] + }, + "followUp": { + "type": "object", + "properties": { + "required": { + "type": "boolean", + "description": "Whether follow-up is needed" + }, + "method": { + "type": "string", + "enum": ["email", "phone", "none"], + "description": "Preferred follow-up method" + }, + "notes": { + "type": "string", + "description": "Additional notes for follow-up" } } - }, - "required": ["customer", "issue"] - } + } + }, + "required": ["customer", "issue"] } ) -structured_output = response.json() -print(f'Created structured output: {structured_output["id"]}') +print(f'Created structured output: {structured_output.id}') # Save this ID - you'll need it in the next step ``` - + + - -Save the returned `id` from the response - you'll need it to link to your assistant. - + +In the API approach, you'll need to save the returned `id` to attach it to an assistant. In the Dashboard, you can attach it directly when creating the structured output. + -## Step 2: Create an assistant with structured outputs +## Step 2: Create and test a call -Now create an assistant that uses your structured output: +Now test your structured output by making a call. - -```bash title="cURL" -curl -X POST https://api.vapi.ai/assistant \ - -H "Authorization: Bearer $VAPI_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "name": "Customer Support Agent", - "firstMessage": "Hello! I'\''m here to help you with your support request. Can you please tell me your name and describe the issue you'\''re experiencing?", - "model": { - "provider": "openai", - "model": "gpt-4-turbo-preview", - "messages": [ - { - "role": "system", - "content": "You are a helpful customer support agent. Gather the customer'\''s information and understand their issue. Be empathetic and professional." - } - ] - }, - "voice": { - "provider": "vapi", - "voiceId": "jennifer" - }, - "artifactPlan": { - "structuredOutputIds": ["YOUR_STRUCTURED_OUTPUT_ID_HERE"] - } - }' -``` + +**Prerequisites**: You need an assistant already created with: +- The structured output from Step 1 attached in `artifactPlan.structuredOutputIds` +- A model and voice configured +- System prompt appropriate for your use case -```javascript title="Node.js" -const assistant = await fetch('https://api.vapi.ai/assistant', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - name: "Customer Support Agent", - firstMessage: "Hello! I'm here to help you with your support request. Can you please tell me your name and describe the issue you're experiencing?", - model: { - provider: "openai", - model: "gpt-4-turbo-preview", - messages: [ - { - role: "system", - content: "You are a helpful customer support agent. Gather the customer's information and understand their issue. Be empathetic and professional." - } - ] - }, - voice: { - provider: "vapi", - voiceId: "jennifer" - }, - artifactPlan: { - structuredOutputIds: [structuredOutput.id] // Use the ID from step 1 - } - }) -}).then(res => res.json()); +You can create an assistant via the Dashboard or API, then use its ID in the examples below. + -console.log('Created assistant:', assistant.id); + + + + + 1. Navigate to your assistant (from **Assistants** in the sidebar) + 2. Ensure your structured output is attached in the **Artifact Plan** section + 3. Click **Talk to Assistant** in the top right corner + 4. The assistant will start speaking + + + + Try saying: "Hi, my name is John Smith. My email is john@example.com. I'm having trouble logging into my account - it keeps showing an error message. This is pretty urgent for me." + + + + Click **End Call** when you're done testing + + + + + + ```typescript +import { VapiClient } from "@vapi-ai/server-sdk"; + +const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); + +// Start a web call with your assistant (replace with your assistant ID) +const call = await vapi.calls.create({ + assistantId: "your-assistant-id", // Use an assistant with structured outputs attached + type: "webCall" +}); + +console.log('Call started:', call.id); +console.log('Join URL:', call.webCallUrl); + +// For phone calls, use: +// const call = await vapi.calls.create({ +// assistantId: "your-assistant-id", +// type: "outboundPhoneCall", +// phoneNumberId: "your-phone-number-id", +// customer: { +// number: "+1234567890" +// } +// }); ``` + -```python title="Python" -assistant_response = requests.post( - 'https://api.vapi.ai/assistant', - headers={ - 'Authorization': f'Bearer {os.environ["VAPI_API_KEY"]}', - 'Content-Type': 'application/json' - }, - json={ - "name": "Customer Support Agent", - "firstMessage": "Hello! I'm here to help you with your support request. Can you please tell me your name and describe the issue you're experiencing?", - "model": { - "provider": "openai", - "model": "gpt-4-turbo-preview", - "messages": [ - { - "role": "system", - "content": "You are a helpful customer support agent. Gather the customer's information and understand their issue. Be empathetic and professional." - } - ] - }, - "voice": { - "provider": "vapi", - "voiceId": "jennifer" - }, - "artifactPlan": { - "structuredOutputIds": [structured_output["id"]] # Use the ID from step 1 - } - } -) + + ```python +from vapi import Vapi +import os -assistant = assistant_response.json() -print(f'Created assistant: {assistant["id"]}') -``` - +vapi = Vapi(token=os.environ.get("VAPI_API_KEY")) -## Step 3: Test with a phone call +# Start a web call with your assistant (replace with your assistant ID) +call = vapi.calls.create( + assistant_id="your-assistant-id", # Use an assistant with structured outputs attached + type="webCall" +) -Make a test call to your assistant: +print(f'Call started: {call.id}') +print(f'Join URL: {call.web_call_url}') + +# For phone calls, use: +# call = vapi.calls.create( +# assistant_id="your-assistant-id", +# type="outboundPhoneCall", +# phone_number_id="your-phone-number-id", +# customer={ +# "number": "+1234567890" +# } +# ) +``` + - -```bash title="cURL" + + ```bash +# Start a web call curl -X POST https://api.vapi.ai/call \ -H "Authorization: Bearer $VAPI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "assistantId": "YOUR_ASSISTANT_ID_HERE", - "customer": { - "number": "+1234567890" - } + "assistantId": "your-assistant-id", + "type": "webCall" }' -``` -```javascript title="Node.js" -const call = await fetch('https://api.vapi.ai/call', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - assistantId: assistant.id, - customer: { - number: "+1234567890" // Replace with your phone number - } - }) -}).then(res => res.json()); - -console.log('Call initiated:', call.id); -``` - -```python title="Python" -call_response = requests.post( - 'https://api.vapi.ai/call', - headers={ - 'Authorization': f'Bearer {os.environ["VAPI_API_KEY"]}', - 'Content-Type': 'application/json' - }, - json={ - "assistantId": assistant["id"], - "customer": { - "number": "+1234567890" # Replace with your phone number - } - } -) - -call = call_response.json() -print(f'Call initiated: {call["id"]}') +# For phone calls: +# curl -X POST https://api.vapi.ai/call \ +# -H "Authorization: Bearer $VAPI_API_KEY" \ +# -H "Content-Type: application/json" \ +# -d '{ +# "assistantId": "your-assistant-id", +# "type": "outboundPhoneCall", +# "phoneNumberId": "your-phone-number-id", +# "customer": { +# "number": "+1234567890" +# } +# }' ``` - + + During the call, try saying something like: "Hi, my name is John Smith. My email is john@example.com. I'm having trouble logging into my account - it keeps showing an error message. This is pretty urgent for me." -## Step 4: Retrieve extracted data +## Step 3: Retrieve extracted data After the call ends, retrieve the extracted information: - -```bash title="cURL" -curl -X GET "https://api.vapi.ai/call/YOUR_CALL_ID_HERE" \ - -H "Authorization: Bearer $VAPI_API_KEY" -``` + + + + + 1. Navigate to **Call Logs** in the left sidebar + 2. Click on your recent call to view details + + + + 1. In the call details, find the **Structured Outputs** section + 2. View the extracted JSON data for your "Support Ticket" output + 3. The data will be displayed in a formatted JSON view showing each output with its ID, name, and result + + + + ### How structured outputs appear in Call Logs + + When you view a call in the Call Logs page, structured outputs are displayed in the following format: + + ```json + { + "550e8400-e29b-41d4-a716-446655440001": { + "name": "Support Ticket", + "result": { + "customer": { + "name": "John Smith", + "email": "john@example.com", + "phone": "+1234567890" + }, + "issue": { + "description": "Unable to login to account, receiving error message", + "category": "technical", + "priority": "urgent" + }, + "followUp": { + "required": true, + "method": "email", + "notes": "Customer needs immediate assistance with login issue" + } + } + } + } + ``` + + **Structure explanation:** + - **Root level**: Contains output IDs (UUIDs) as keys + - **name**: The name of the structured output configuration + - **result**: The actual extracted data based on your schema + - For object schemas: Contains the nested structure with all extracted fields + - For boolean schemas: Contains `true` or `false` + - For string schemas: Contains the extracted text + - For number schemas: Contains the numeric value + + + If you have multiple structured outputs attached to an assistant, each will appear with its own UUID key in the structuredOutputs object. + + + + + ```typescript +import { VapiClient } from "@vapi-ai/server-sdk"; + +const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! }); -```javascript title="Node.js" // Wait a few seconds after call ends for processing setTimeout(async () => { - const callData = await fetch(`https://api.vapi.ai/call/${call.id}`, { - headers: { - 'Authorization': `Bearer ${process.env.VAPI_API_KEY}` - } - }).then(res => res.json()); + const callData = await vapi.calls.get(call.id); const outputs = callData.artifact?.structuredOutputs; @@ -552,32 +585,41 @@ setTimeout(async () => { } }, 5000); ``` + -```python title="Python" + + ```python +from vapi import Vapi import time import json +import os + +vapi = Vapi(token=os.environ.get("VAPI_API_KEY")) # Wait a few seconds after call ends for processing time.sleep(5) -call_data = requests.get( - f'https://api.vapi.ai/call/{call["id"]}', - headers={ - 'Authorization': f'Bearer {os.environ["VAPI_API_KEY"]}' - } -).json() +call_data = vapi.calls.get(call.id) -outputs = call_data.get('artifact', {}).get('structuredOutputs', {}) +outputs = call_data.artifact.get('structuredOutputs', {}) if call_data.artifact else {} for output_id, data in outputs.items(): print('Extracted Support Ticket:') print(json.dumps(data['result'], indent=2)) ``` - + + + + ```bash +curl -X GET "https://api.vapi.ai/call/YOUR_CALL_ID_HERE" \ + -H "Authorization: Bearer $VAPI_API_KEY" +``` + + ### Expected output -You should see extracted data like this: +The extracted data (the `result` field from the API response) will look like this: ```json { @@ -599,103 +641,9 @@ You should see extracted data like this: } ``` -## Step 5: Set up webhook (optional) - -To automatically receive extracted data when calls end, set up a webhook: - - -```javascript title="Express.js webhook handler" -const express = require('express'); -const app = express(); - -app.use(express.json()); - -app.post('/vapi/webhook', (req, res) => { - const { type, call } = req.body; - - if (type === 'call.ended') { - const outputs = call.artifact?.structuredOutputs; - - if (outputs) { - Object.entries(outputs).forEach(([outputId, data]) => { - if (data.result) { - // Process the extracted support ticket - console.log('New support ticket:', data.result); - - // Example: Create ticket in your system - createSupportTicket({ - customer: data.result.customer, - issue: data.result.issue, - priority: data.result.issue.priority, - followUp: data.result.followUp - }); - } - }); - } - } - - res.status(200).send('OK'); -}); - -function createSupportTicket(ticketData) { - // Your ticket creation logic here - console.log('Creating ticket in system:', ticketData); -} - -app.listen(3000, () => { - console.log('Webhook server running on port 3000'); -}); -``` - -```python title="Flask webhook handler" -from flask import Flask, request, jsonify - -app = Flask(__name__) - -@app.route('/vapi/webhook', methods=['POST']) -def vapi_webhook(): - data = request.json - - if data.get('type') == 'call.ended': - call = data.get('call', {}) - outputs = call.get('artifact', {}).get('structuredOutputs', {}) - - for output_id, output_data in outputs.items(): - if output_data.get('result'): - # Process the extracted support ticket - print('New support ticket:', output_data['result']) - - # Example: Create ticket in your system - create_support_ticket({ - 'customer': output_data['result']['customer'], - 'issue': output_data['result']['issue'], - 'priority': output_data['result']['issue']['priority'], - 'followUp': output_data['result']['followUp'] - }) - - return jsonify({'status': 'ok'}), 200 - -def create_support_ticket(ticket_data): - # Your ticket creation logic here - print('Creating ticket in system:', ticket_data) - -if __name__ == '__main__': - app.run(port=3000) -``` - - -Then update your assistant with the webhook URL: - -```bash -curl -X PATCH "https://api.vapi.ai/assistant/YOUR_ASSISTANT_ID" \ - -H "Authorization: Bearer $VAPI_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "server": { - "url": "https://your-domain.com/vapi/webhook" - } - }' -``` + +When accessing via API, this data is nested inside the structured output object at `call.artifact.structuredOutputs[outputId].result`. The Dashboard shows the complete structure including the output ID and name. + ## Next steps @@ -737,6 +685,49 @@ You can attach multiple structured outputs to extract different types of data: The `structuredOutputIds` are UUIDs returned when you create each structured output configuration. +### Example: Intelligent analysis with multiple outputs + +Structured outputs can perform sophisticated analysis beyond simple data extraction. Here's a real example showing various types of intelligent evaluation: + +```json +{ + "2ca00f20-f2c3-4d74-af2e-52842be5885c": { + "name": "informationOnFileIsCorrect", + "result": false + }, + "4748e1aa-6c7a-49e6-bbde-c4365ef69c6e": { + "name": "Appointment Rescheduled", + "result": false + }, + "4d4bac33-2cea-43d4-a3b3-4554932b8933": { + "name": "CSAT", + "result": 8 + }, + "7898e478-c8dc-4ff8-a3f6-4a46555a957f": { + "name": "Appointment Booked", + "result": true + }, + "a0ca58b1-c343-4628-b088-bf53aabacab9": { + "name": "Call Summary", + "result": "The user called to schedule a consultation appointment for next week, specifically on Wednesday afternoon..." + }, + "b5a390d8-87c5-4015-b1ad-ed237201bdf0": { + "name": "Success Evaluation - Pass/Fail", + "result": true + } +} +``` + +This example demonstrates intelligent extraction capabilities: +- **Call outcome evaluation**: `Appointment Booked` (true) - Analyzed if the call's objective was achieved +- **Data verification**: `informationOnFileIsCorrect` (false) - Evaluated if customer data needed updates +- **Success metrics**: `Success Evaluation - Pass/Fail` (true) - Determined overall call success based on multiple criteria +- **CSAT extraction**: `CSAT` (8) - Extracted satisfaction score from customer feedback +- **Intelligent summarization**: `Call Summary` - Generated contextual summary of the conversation +- **Process tracking**: `Appointment Rescheduled` (false) - Tracked specific actions taken during the call + +Each output analyzes the complete call context including transcript, tool results, and metadata to provide actionable insights. + ### Validation patterns Common validation patterns for reliable extraction: diff --git a/fern/calls/websocket-transport.mdx b/fern/calls/websocket-transport.mdx index 115849fd1..7ac27279a 100644 --- a/fern/calls/websocket-transport.mdx +++ b/fern/calls/websocket-transport.mdx @@ -196,10 +196,12 @@ function hangupCall() { ## Ending the Call -To gracefully end the WebSocket call: +The recommended way to end a call is using [Live Call Control](/calls/call-features#end-call) which provides more control and proper cleanup. + +Alternatively, you can end the WebSocket call directly: ```javascript -sendControlMessage({ type: "hangup" }); +sendControlMessage({ type: "end-call" }); socket.close(); ``` From 0eebd55905ce658608b2b4f853658ea7c38a2b6d Mon Sep 17 00:00:00 2001 From: sahil suman Date: Thu, 18 Sep 2025 08:17:14 +0530 Subject: [PATCH 035/171] call queue management --- fern/calls/call-queue-management.mdx | 477 +++++++++++++++++++ fern/docs.yml | 3 + fern/static/images/call-queue-management.png | Bin 0 -> 239951 bytes 3 files changed, 480 insertions(+) create mode 100644 fern/calls/call-queue-management.mdx create mode 100644 fern/static/images/call-queue-management.png diff --git a/fern/calls/call-queue-management.mdx b/fern/calls/call-queue-management.mdx new file mode 100644 index 000000000..0f53876f0 --- /dev/null +++ b/fern/calls/call-queue-management.mdx @@ -0,0 +1,477 @@ +--- +title: Call queue management with Twilio +subtitle: Handle high-volume calls with Twilio queues when hitting Vapi concurrency limits +slug: calls/call-queue-management +description: Build a call queue system using Twilio to handle large volumes of calls while respecting Vapi concurrency limits, ensuring no calls are dropped. +--- + +## Overview + +When your application receives more simultaneous calls than your Vapi concurrency limit allows, calls can be rejected. A call queue system using Twilio queues solves this by holding excess calls in a queue and processing them as capacity becomes available. + +**In this guide, you'll learn to:** +- Set up Twilio call queues for high-volume scenarios +- Implement concurrency tracking to respect Vapi limits +- Build a queue processing system with JavaScript +- Handle call dequeuing and Vapi integration seamlessly + + +This approach is ideal for call centers, customer support lines, or any application expecting call volumes that exceed your Vapi concurrency limit. + + +## Prerequisites + +Before implementing call queue management, ensure you have: + +- **Vapi Account**: Access to the [Vapi Dashboard](https://dashboard.vapi.ai/org/api-keys) with your API key +- **Twilio Account**: Active Twilio account with Account SID and Auth Token +- **Twilio CLI**: Install from [twil.io/cli](https://twil.io/cli) for queue management +- **Phone Number**: Twilio phone number configured for incoming calls +- **Assistant**: Configured Vapi assistant ID for handling calls +- **Server Environment**: Node.js server capable of receiving webhooks + + +You'll need to know your Vapi account's concurrency limit. Check your plan details in the [Vapi Dashboard](https://dashboard.vapi.ai/settings/billing) under billing settings. + + +## How it works + +The queue management system operates in three phases: + + + + Incoming calls are automatically placed in a Twilio queue when received + + + Server monitors active Vapi calls against your concurrency limit + + + When capacity is available, calls are dequeued and connected to Vapi + + + +**Call Flow:** + + + + + +1. **Incoming call** → Twilio receives call and executes webhook +2. **Queue placement** → Call is placed in Twilio queue with hold music +3. **Automatic processing** → Server automatically checks queue every 1 second +4. **Capacity check** → Server verifies if Vapi concurrency limit allows new calls +5. **Dequeue & connect** → Available calls are dequeued and connected to Vapi assistants +6. **Concurrency tracking** → System tracks active calls via end-of-call webhooks + +--- + +## Implementation Guide + + + + First, create a Twilio queue using the Twilio CLI to hold incoming calls. + + ```bash + twilio api:core:queues:create \ + --friendly-name customer-support + ``` + + **Expected Response:** + ```json + { + "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "average_wait_time": 0, + "current_size": 0, + "date_created": "2024-01-15T18:39:09.000Z", + "date_updated": "2024-01-15T18:39:09.000Z", + "friendly_name": "customer-support", + "max_size": 100, + "sid": "QUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Queues/QUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json" + } + ``` + + + Save the queue `sid` (e.g., `QUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`) - you'll need this for queue operations. + + + + + Configure your Twilio phone number to send incoming calls to your queue endpoint. + + 1. Go to [Twilio Console > Phone Numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming) + 2. Select your phone number + 3. Set **A call comes in** webhook to: `https://your-server.com/incoming` + 4. Set HTTP method to `POST` + 5. Save configuration + + + + Create your Node.js server with the required dependencies and environment variables. + + **Install Dependencies:** + ```bash + npm install express twilio axios dotenv + ``` + + **Environment Variables (.env):** + ```bash + # Vapi Configuration + VAPI_API_KEY=your_vapi_api_key_here + VAPI_PHONE_NUMBER_ID=your_phone_number_id + VAPI_ASSISTANT_ID=your_assistant_id + + # Twilio Configuration + TWILIO_ACCOUNT_SID=your_twilio_account_sid + TWILIO_AUTH_TOKEN=your_twilio_auth_token + TWILIO_QUEUE_SID=QUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + # Server Configuration + PORT=3000 + MAX_CONCURRENCY=5 + ``` + + + + Create the main server file with queue handling, concurrency tracking, and Vapi integration. + + ```javascript title="server.js" + const express = require('express'); + const twilio = require('twilio'); + const axios = require('axios'); + require('dotenv').config(); + + const app = express(); + const twilioClient = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN); + + // Concurrency and queue tracking + let activeCalls = 0; + let callsInQueue = 0; + const MAX_CONCURRENCY = parseInt(process.env.MAX_CONCURRENCY) || 5; + + // Middleware + app.use(express.json()); + app.use(express.urlencoded({ extended: true })); + + // Incoming call handler - adds calls to queue + app.post('/incoming', (req, res) => { + try { + const twiml = ` + + customer-support + `; + + res.set('Content-Type', 'application/xml'); + res.send(twiml); + + // Increment queue counter + callsInQueue++; + console.log(`Call ${req.body.CallSid} added to queue. Calls in queue: ${callsInQueue}`); + } catch (error) { + console.error('Error handling incoming call:', error); + res.status(500).send('Error processing call'); + } + }); + + // Queue processing function + async function processQueue() { + try { + // Check if we have capacity for more calls + if (activeCalls >= MAX_CONCURRENCY) { + return; + } + + // Check if there are calls in queue + if (callsInQueue === 0) { + return; + } + + // Get next call from queue + const members = await twilioClient.queues(process.env.TWILIO_QUEUE_SID) + .members + .list({ limit: 1 }); + + if (members.length === 0) { + // No calls in queue - sync our counter + callsInQueue = 0; + return; + } + + const member = members[0]; + console.log(`Processing queued call: ${member.callSid}`); + + // Get Vapi TwiML for this call + const twiml = await initiateVapiCall(member.callSid, member.phoneNumber); + + if (twiml) { + // Update call with Vapi TwiML + await twilioClient.calls(member.callSid).update({ twiml }); + + // Increment active call counter and decrement queue counter + activeCalls++; + callsInQueue--; + console.log(`Call connected to Vapi. Active calls: ${activeCalls}/${MAX_CONCURRENCY}, Queue: ${callsInQueue}`); + } else { + console.error(`Failed to get TwiML for call ${member.callSid}`); + } + } catch (error) { + console.error('Error processing queue:', error); + } + } + + // Generate Vapi TwiML for a call + async function initiateVapiCall(callSid, customerNumber) { + const payload = { + phoneNumberId: process.env.VAPI_PHONE_NUMBER_ID, + phoneCallProviderBypassEnabled: true, + customer: { number: customerNumber }, + assistantId: process.env.VAPI_ASSISTANT_ID, + }; + + const headers = { + 'Authorization': `Bearer ${process.env.VAPI_API_KEY}`, + 'Content-Type': 'application/json', + }; + + try { + const response = await axios.post('https://api.vapi.ai/call', payload, { headers }); + + if (response.data && response.data.phoneCallProviderDetails) { + return response.data.phoneCallProviderDetails.twiml; + } else { + throw new Error('Invalid response structure from Vapi'); + } + } catch (error) { + console.error(`Error initiating Vapi call for ${callSid}:`, error.message); + return null; + } + } + + // Webhook for call completion (decrements active calls) + app.post('/call-ended', (req, res) => { + try { + // Handle Vapi end-of-call-report webhook + const message = req.body.message; + + if (message && message.type === 'end-of-call-report') { + const callId = message.call?.id; + + if (activeCalls > 0) { + activeCalls--; + console.log(`Vapi call ${callId} ended. Active calls: ${activeCalls}/${MAX_CONCURRENCY}`); + // Note: Queue processing happens automatically every 1 second + } + } + + res.status(200).send('OK'); + } catch (error) { + console.error('Error handling Vapi webhook:', error); + res.status(500).send('Error'); + } + }); + + // Manual queue processing endpoint (for testing/monitoring) + app.post('/process-queue', async (req, res) => { + try { + await processQueue(); + res.json({ + message: 'Queue processing triggered', + activeCalls, + callsInQueue, + maxConcurrency: MAX_CONCURRENCY + }); + } catch (error) { + console.error('Error in manual queue processing:', error); + res.status(500).json({ error: 'Failed to process queue' }); + } + }); + + // Health check endpoint + app.get('/health', (req, res) => { + res.json({ + status: 'healthy', + activeCalls, + callsInQueue, + maxConcurrency: MAX_CONCURRENCY, + availableCapacity: MAX_CONCURRENCY - activeCalls + }); + }); + + // Start server + const PORT = process.env.PORT || 3000; + app.listen(PORT, () => { + console.log(`Queue management server running on port ${PORT}`); + console.log(`Max concurrency: ${MAX_CONCURRENCY}`); + + // Start automatic queue processing every 1 second + startQueueProcessor(); + }); + + // Automatic queue processing with 1-second interval + function startQueueProcessor() { + setInterval(async () => { + try { + // Only process queue if there are calls waiting + if (callsInQueue > 0) { + await processQueue(); + } + } catch (error) { + console.error('Error in automatic queue processing:', error); + } + }, 1000); // Check queue every 1 second + + console.log('Automatic queue processor started (1-second interval)'); + } + + module.exports = app; + ``` + + + + Configure your Vapi assistant to send end-of-call-report webhooks for accurate concurrency tracking. + + **Assistant Configuration:** + You need to configure your assistant with proper webhook settings to receive call status updates. + + ```javascript title="assistant-configuration.js" + const assistantConfig = { + name: "Queue Management Assistant", + // ... other assistant configuration + + // Configure server URL for webhooks + server: { + url: "https://your-server.com", + timeoutSeconds: 20 + }, + + // Configure which messages to send to your server + serverMessages: ["end-of-call-report", "status-update"] + }; + ``` + + + The webhook will be sent to your server URL with the message type `end-of-call-report` when calls end. This allows you to decrement your active call counter accurately. See the [Assistant API reference](https://docs.vapi.ai/api-reference/assistants/create#request.body.serverMessages) for all available server message types. + + + **Webhook Payload Example:** + Your `/call-ended` endpoint will receive a webhook with this structure: + + ```json title="end-of-call-report-payload.json" + { + "message": { + "type": "end-of-call-report", + "call": { + "id": "73a6da0f-c455-4bb6-bf4a-5f0634871430", + "status": "ended", + "endedReason": "assistant-ended-call" + } + } + } + ``` + + + + Deploy your server and test the complete queue management flow. + + **Start Your Server:** + ```bash + node server.js + ``` + + **Test Scenarios:** + 1. **Single call**: Call your Twilio number - should connect immediately + 2. **Multiple calls**: Make several simultaneous calls to test queuing + 3. **Capacity limit**: Make more calls than your `MAX_CONCURRENCY` setting + 4. **Queue processing**: Check that calls are processed as others end + + **Monitor Queue Status:** + ```bash + # Check server health and capacity + curl https://your-server.com/health + + # Manually trigger queue processing + curl -X POST https://your-server.com/process-queue + ``` + + + +## Automatic Queue Processing + +The system includes **automatic queue processing** that runs continuously to ensure optimal call handling: + +### How It Works + +- **Smart checking**: Only runs `processQueue()` when `callsInQueue > 0` +- **Queue counter tracking**: Increments when calls enter queue, decrements when processed +- **1-second intervals**: The server checks for queued calls every second +- **Efficient processing**: Only processes calls when both capacity is available AND calls are waiting +- **Error handling**: Continues running even if individual queue checks fail + +### Benefits + + + + Calls are processed within 1 second of capacity becoming available + + + No need to manually trigger queue processing - it happens automatically + + + System continues running even if individual API calls fail + + + Handles high-volume scenarios without missing queued calls + + + +### Performance Considerations + +- **Minimal API Calls**: Only queries Twilio API when `callsInQueue > 0` +- **Counter Synchronization**: Automatically syncs queue counter with actual Twilio queue state +- **Efficient Resource Usage**: Avoids unnecessary processing when queue is empty +- **Graceful Degradation**: Handles temporary API failures without crashing +- **Smart Logging**: Provides clear visibility into queue and active call counts + + +The automatic processing ensures that as soon as a Vapi call ends and creates capacity, the next queued call will be processed within 1 second, providing near-real-time queue management. + + +## Troubleshooting + + + + **Common causes:** + - Server not receiving call-ended webhooks (check webhook URLs) + - Concurrency counter stuck (restart server to reset) + - Vapi API errors (check API key and assistant ID) + + **Solutions:** + - Verify webhook URLs are publicly accessible + - Add logging to track concurrency changes + - Test Vapi API calls independently + + + + **Check these items:** + - `MAX_CONCURRENCY` setting is appropriate for your Vapi plan + - Queue processing is being triggered (check logs) + - No errors in Vapi TwiML generation + + **Debug steps:** + - Call `/process-queue` endpoint manually + - Check `/health` endpoint for current capacity + - Review server logs for error messages + + + + **Potential issues:** + - Invalid phone number format (use E.164 format) + - Incorrect Vapi configuration (phone number ID, assistant ID) + - Network timeouts during TwiML generation + + **Solutions:** + - Validate all phone numbers before processing + - Add timeout handling to API calls + - Implement retry logic for failed Vapi requests + + \ No newline at end of file diff --git a/fern/docs.yml b/fern/docs.yml index 8fdc43093..1f86eea5e 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -398,6 +398,9 @@ navigation: - page: Debug forwarding drops path: calls/troubleshoot-call-forwarding-drops.mdx icon: fa-light fa-bug + - page: Call queue management + path: calls/call-queue-management.mdx + icon: fa-light fa-phone-office - page: Call end reasons path: calls/call-ended-reason.mdx icon: fa-light fa-phone-hangup diff --git a/fern/static/images/call-queue-management.png b/fern/static/images/call-queue-management.png new file mode 100644 index 0000000000000000000000000000000000000000..66dae1f93141673d79cfb8d1fc6ac52732399a78 GIT binary patch literal 239951 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%0D=-V~`Nu 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