Dynamic tool messages

Generate a context-aware message before a tool runs with bot_say

bot_say is a reserved tool-call argument that lets the model generate a context-aware message in the same response that calls a tool. Vapi speaks the message before the tool runs, without making an additional model request.

When bot_say is a non-empty string, Vapi trims and speaks it before the tool runs. Vapi waits for the message to finish, the caller cannot interrupt it, and Vapi removes the property from the tool-call arguments before execution.

Define bot_say inside function.parameters. It is not a top-level tool field, so it does not appear as a named field in the Create Tool API reference.

Supported tools

ToolAdd bot_say toConfiguration note
Functionfunction.parameters.propertiesAdd it to the tool’s existing JSON Schema.
Handofffunction.parameters.propertiesPreserve the generated destination property and its required entry.

Configure bot_say

1

Add bot_say to the tool schema

Add a bot_say property with type set to string inside function.parameters.properties. Include bot_say in function.parameters.required so the schema requires the model to provide it.

Add the property to the existing schema without removing other properties or required entries.

2

Describe what the assistant should say

Use the property’s description to specify the message’s purpose, tone, length, language, and script rules. Ask for a non-empty value without trailing punctuation.

3

Suppress the static start message

For a tool that normally plays a static or default request-start message, add one request-start entry with an empty content value. Replace any existing request-start entries, but keep entries for other message types.

The empty entry prevents a second acknowledgment. Without it, Vapi can select a default filler message. If you configure a non-empty static start message, the caller can hear both the dynamic and static messages.

4

Update the assistant prompt

Tell the model to populate bot_say whenever it calls the tool and not to speak a separate acknowledgment.

Whenever you call lookup_order, set bot_say to one brief acknowledgment in
the caller's current language. Do not speak a separate acknowledgment.

Function tool example

{
"type": "function",
"function": {
"name": "lookup_order",
"description": "Look up an order by its ID",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order ID to look up"
},
"bot_say": {
"type": "string",
"description": "One brief acknowledgment before the lookup, in the caller's current language. No trailing punctuation."
}
},
"required": ["order_id", "bot_say"]
}
},
"server": {
"url": "https://example.com/vapi/tools"
},
"messages": [
{
"type": "request-start",
"content": ""
}
]
}

Behavior and limits

  • Vapi trims leading and trailing whitespace from a non-empty bot_say value before speaking it.
  • An empty or whitespace-only value is neither spoken nor removed, so it remains in the tool-call arguments.
  • If several tools are called in the same turn, Vapi joins their non-empty values with . and speaks one combined message.
  • If bot_say is missing, Vapi does not speak a dynamic tool message.

Verify the behavior

Make a test call that triggers the Function tool, then inspect the request received by your server. Confirm that:

  • The assistant finishes the dynamic message before the request arrives.
  • The caller cannot interrupt the message.
  • The caller hears no second start message.
  • The received tool-call arguments contain order_id but not bot_say.