builtin_tool_error call event and the assistant keeps talking to the caller — a broken tool never crashes a call.
On messaging (Telegram, Slack, Messenger, Teams, Discord, Google Chat, X) and email auto-replies, the same text-safe built-ins run in the Next.js reply path (API/MCP/KB/calendar too). Voice-only types (end_call, transfers, DTMF/keypad, payment card) are not registered there.
The standalone tools
Keypad collection is flow-scoped: add a Collect node in Flow Builder, where the worker can safely own DTMF state and transitions. Calendar actions are provided by Integrations. The old
dtmf_input, collect_keypad, and calendar_integration standalone configurations are retained only for backwards-compatible display and cannot be created as new reusable tools.
Enabling a tool
Open Tools, create a Built-in tool, fill in its fields, and assign it to an assistant. Its required name is the exact function name exposed to the model, while description tells the model when to use it. Calls are attributed to the reusable tool in the Runs view.End call
No configuration beyond the description. The model must finish the request and say goodbye before calling the function; the worker then marks the call as ending and hangs up.Call transfer (cold)
- Phone number — the fixed destination.
- AI can determine transfer number dynamically — exposes the destination as a function argument instead.
- Warm-transfer message — optional non-interruptible announcement before the cold transfer.
Warm call transfer
Puts the caller on hold and dials a colleague first:- Supervisor phone — who to call; the workspace’s configured outbound trunk is used.
- Hold music — on or off, plus an optional spoken hold message.
- Briefing — summary instructions (how to summarize the call for the colleague) and a briefing opener spoken to the colleague; both support
{{variables}}. - Ringing timeout and fallback — continue the conversation, end, or cold-transfer if the consult call fails.
Transfer to assistant (KI→KI)
Hands the live session to another assistant in the same workspace without hanging up:- Target assistant (
assistant_id) — required; must belong to the workspace. - Message before transfer — optional non-interruptible line spoken before the handoff.
- Speak transfer greeting — when on (default), the target assistant’s first message / greeting runs after the switch.
- Description — required: tell the model when to hand off (e.g. pricing questions → sales assistant).
reason and conversation_summary so the receiving assistant keeps context. The worker rebuilds STT/LLM/TTS (or realtime) for the target, calls session.update_agent, and writes assistant_transfer / assistant_transfer_failed call events. A call can be handed off at most three times (loop protection). Self-transfer to the same assistant is rejected.
Send SMS
The assistant drafts the message text itself from the conversation and sends it mid-call:- Recipient (
sms_to_mode) —caller(default: the caller’s own number) orcustomwith a fixed Custom number (sms_custom_number, E.164, e.g.+491701234567).
Send email
The email tool separates recipient capture, sender identity, content, and signature so each can be deterministic where needed:- Recipient (
email_to_mode) —askuses a dedicated email-capture workflow to normalize noisy speech and obtain explicit confirmation;fixedusesemail_fixed_to. Malformed or spoken-text addresses are never guessed at send time. - Sender (
email_sender_mode) —autotries the assistant’s verified SendGrid address, workspace/reseller SMTP, then platform mail. Or explicitly select Workspace SMTP, Platform mail, or one verified address fromGET /api/v1/email-senders. Explicit selections fail clearly instead of silently falling back. - Display name (
email_from_name) — optional per-tool override. - Content (
email_content_mode) —llmlets the model write subject/body from the call;fixedalways sends the configured literal copy;templateresolves{{call_variables}}and blocks the send if a value is missing. - Signature (
email_signature_mode) — workspace default (with{agent_name}/{{assistant_name}}), a custom per-tool signature, or none. It is appended once by application code, not improvised by the model. - Delivery status — a successful tool result means that the SMTP provider accepted the message, not that it reached the inbox. Known SendGrid bounce/block/spam suppressions are checked before sending and are returned to the assistant as a delivery failure.
Business hours
Lets the assistant answer “are you open right now?” truthfully — and behave differently outside opening hours:- Business hours (
business_hours) — a weekly schedule, one or more time windows per weekday ({"mon": [["09:00", "17:00"]], ...}— the same shape as campaign calling windows). - Note (
hours_note) — an optional free-text hint returned alongside the result (e.g. “Closed on public holidays”).
Schedule callback
The assistant agrees on a callback time with the caller; the platform stores it and a cron job dials the callback automatically when it’s due:- Callback number (
callback_to_mode) —caller(default: call the caller back on their own number) orcustomwith a fixed Custom number (callback_custom_number, E.164). - Max days ahead (
max_days_ahead) — how far into the future a callback may be booked (1–365 days).
Collect payment card
Enables Payment card Collect nodes in Flow Builder. This is not an LLM-callable action — it gates the flow node and selects which Stripe account receives the Payment Method.- Add your Stripe Secret Key under Tools → App Store → Stripe.
- Create a built-in tool of type
collect_payment_cardand select that Stripe account (stripe_connection_id). - Assign the tool to an assistant.
- Add a Collect node with type Payment card in the flow.
card_last4, card_brand, and stripe_payment_method_id are stored — never the full card number or CVV. Requires the plan feature Collect payment cards. Charged per successful collection (see credit settings).
Without a Stripe Secret Key connection, the tool form shows a hint to add one first — there is no platform fallback for customer card data.
Set call variable
Lets the assistant store a value mid-call (for example the caller’s company name) so later tools, emails, flow conditions, and the post-call webhook can use it:- Allowed keys (
allowed_keys) — optional snake_case allowlist. Empty = any valid key except reserved platform keys (assistant_name,direction,call_id,date,time,datetime,weekday). - Description — tell the model when to save (e.g. after the caller names their company).
{"updated":{"key":"value"}} so the model learns the stored value via the tool result. It does not rewrite the system prompt mid-call (realtime models would ignore that). Empty string clears a key.
System tool: get_current_time
Independent of the configurable tools above, every assistant always has theget_current_time system tool — no configuration, it cannot be disabled. The model calls it whenever the current date or time matters (resolving “tomorrow at 3”, checking a deadline, booking an appointment).
The returned time is localized to the assistant’s timezone (assistants.timezone, an IANA identifier like Europe/Berlin). On campaign calls, the campaign’s timezone overrides it per call (meta.timezone ?? assistant.timezone) — see Timezone.
API & MCP
Built-in tools live on the assistant’sbuiltin_tools array (also accepted as tools for compatibility). Set them via the public API:
GET /api/v1/email-senders and MCP list_email_senders expose the secrets-free sender catalog; see the API reference.