> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ouraicalling.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Built-in tools

> Configure reliable mid-call actions: end or transfer a call, send SMS or email, check business hours, and schedule a confirmed callback

Built-in tools are ready-made actions the assistant can call during a live conversation. Unlike a flow, they need no graph — create a reusable workspace tool, describe *when* it should run, and assign it to one or more assistants. They are an **additive second path** next to [flow nodes](/flow-builder/overview).

Every built-in tool is defensive: a misconfigured tool logs a `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

| Tool                                              | What it does                                                                                                                                                                                             |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **End call** (`end_call`)                         | Hangs up after the assistant has finished the work and said goodbye.                                                                                                                                     |
| **Call transfer** (`call_transfer`)               | Cold transfer (SIP REFER) to a phone number.                                                                                                                                                             |
| **Warm call transfer** (`warm_call_transfer`)     | Puts the caller on hold, dials a colleague, briefs them, then merges both parties.                                                                                                                       |
| **Transfer to assistant** (`assistant_transfer`)  | Hands the live call over to another AI assistant in the same workspace (KI→KI).                                                                                                                          |
| **Send SMS** (`send_sms`)                         | The assistant writes a text message mid-call and sends it — to the caller or a fixed number.                                                                                                             |
| **Send email** (`send_email`)                     | The assistant composes and sends an email during the call.                                                                                                                                               |
| **Business hours** (`check_business_hours`)       | Lets the assistant check whether you are currently open — evaluated in the assistant's timezone.                                                                                                         |
| **Schedule callback** (`schedule_callback`)       | The assistant agrees on a time with the caller; a cron job dials the callback automatically later. All bookings appear live under **Audience → Scheduled Callbacks** (voice, chat/messaging, and email). |
| **Collect payment card** (`collect_payment_card`) | Enables Payment card Collect nodes in flows. Cards are tokenized into your Stripe account (your Secret Key).                                                                                             |
| **Set call variable** (`set_variable`)            | Stores a value mid-call (e.g. company name). The model learns via the tool result; later tools, emails, flow conditions and webhooks can use it.                                                         |

Keypad collection is flow-scoped: add a **Collect** node in [Flow Builder](/flow-builder/overview), where the worker can safely own DTMF state and transitions. Calendar actions are provided by [Integrations](/assistants/calendar-booking). 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).

The model may pass a short `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) or `custom` with a fixed **Custom number** (`sms_custom_number`, E.164, e.g. `+491701234567`).

Typical use: texting a confirmation, an address, or a payment link while still on the phone.

### Send email

The email tool separates recipient capture, sender identity, content, and signature so each can be deterministic where needed:

* **Recipient** (`email_to_mode`) — `ask` uses a dedicated email-capture workflow to normalize noisy speech and obtain explicit confirmation; `fixed` uses `email_fixed_to`. Malformed or spoken-text addresses are never guessed at send time.
* **Sender** (`email_sender_mode`) — `auto` tries the assistant's verified SendGrid address, workspace/reseller SMTP, then platform mail. Or explicitly select **Workspace SMTP**, **Platform mail**, or one verified address from `GET /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`) — `llm` lets the model write subject/body from the call; `fixed` always sends the configured literal copy; `template` resolves `{{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.

The irreversible send disables interruptions, carries the call ID into email history, and uses an idempotency key so a retried function call does not intentionally create a second message.

### 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"*).

The check is evaluated in the **assistant's [timezone](/assistants/timezone)** (a campaign's timezone overrides it per call), so "open" always means open *locally*.

### 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) or `custom` with 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).

At runtime the function requires an exact ISO-8601 time and a positive confirmation flag. Past dates and dates beyond the configured limit are rejected; the worker never silently defaults to 30 minutes or clamps the caller's choice.

### Collect payment card

Enables **Payment card** Collect nodes in [Flow Builder](/flow-builder/nodes). This is not an LLM-callable action — it gates the flow node and selects which Stripe account receives the Payment Method.

1. Add your Stripe Secret Key under **Tools → App Store → Stripe**.
2. Create a built-in tool of type `collect_payment_card` and select that Stripe account (`stripe_connection_id`).
3. Assign the tool to an assistant.
4. Add a Collect node with type **Payment card** in the flow.

During the call the agent gathers card details securely; the platform creates a Stripe Payment Method in **your** Stripe account using your Secret Key. Only `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).

The tool writes into the live call's variable map and returns `{"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 the **`get_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](/assistants/timezone).

## API & MCP

Built-in tools live on the assistant's `builtin_tools` array (also accepted as `tools` for compatibility). Set them via the public API:

```bash theme={null}
curl -X PATCH https://app.famulor.io/api/v1/assistants/{id} \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tools": [
      { "type": "end_call", "description": "Hang up politely once the caller is done." },
      { "type": "send_email", "email_to_mode": "ask",
        "email_sender_mode": "auto", "email_content_mode": "llm",
        "email_signature_mode": "workspace" }
    ]
  }'
```

The same field contract is used by the editor, REST API, and MCP. `GET /api/v1/email-senders` and MCP `list_email_senders` expose the secrets-free sender catalog; see the [API reference](/api-reference/introduction).
